|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] arm: vgic: fix race in vgic_vcpu_inject_irq
commit e83d6b9432af603200f065b499b8e4b78e92842d
Author: Ian Campbell <ian.campbell@xxxxxxxxxx>
AuthorDate: Wed Apr 17 13:52:34 2013 +0100
Commit: Ian Campbell <ian.campbell@xxxxxxxxxx>
CommitDate: Thu Apr 18 14:58:43 2013 +0100
arm: vgic: fix race in vgic_vcpu_inject_irq
The initial check for a still pending interrupt (!list_empty(&n->inflight))
needs to be covered by the vgic lock to avoid trying to insert the IRQ into
the
inflight list simultaneously on 2 pCPUS. Expand the area covered by the lock
appropriately.
Also consolidate the unlocks on the exit path into one location.
Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
Acked-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
---
xen/arch/arm/vgic.c | 12 ++++++++----
1 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index d9ceaaa..4d8da02 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -584,9 +584,14 @@ void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int
irq, int virtual)
struct pending_irq *iter, *n = irq_to_pending(v, irq);
unsigned long flags;
- /* irq still pending */
+ spin_lock_irqsave(&v->arch.vgic.lock, flags);
+
+ /* irq already pending */
if (!list_empty(&n->inflight))
+ {
+ spin_unlock_irqrestore(&v->arch.vgic.lock, flags);
return;
+ }
priority = byte_read(rank->ipriority[REG_RANK_INDEX(8, idx)], 0, byte);
@@ -601,17 +606,16 @@ void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int
irq, int virtual)
if ( rank->ienable & (1 << (irq % 32)) )
gic_set_guest_irq(v, irq, GICH_LR_PENDING, priority);
- spin_lock_irqsave(&v->arch.vgic.lock, flags);
list_for_each_entry ( iter, &v->arch.vgic.inflight_irqs, inflight )
{
if ( iter->priority > priority )
{
list_add_tail(&n->inflight, &iter->inflight);
- spin_unlock_irqrestore(&v->arch.vgic.lock, flags);
- return;
+ goto out;
}
}
list_add_tail(&n->inflight, &v->arch.vgic.inflight_irqs);
+out:
spin_unlock_irqrestore(&v->arch.vgic.lock, flags);
/* we have a new higher priority irq, inject it into the guest */
}
--
generated by git-patchbot for /home/xen/git/xen.git#master
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |