From mboxrd@z Thu Jan 1 00:00:00 1970 From: Stefano Stabellini Subject: Re: [PATCH 6/9] arm: vgic: fix race in vgic_vcpu_inject_irq Date: Tue, 19 Mar 2013 16:10:56 +0000 Message-ID: References: <1362559920.8941.98.camel@hastur.hellion.org.uk> <1362560076-25897-6-git-send-email-ijc@hellion.org.uk> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1362560076-25897-6-git-send-email-ijc@hellion.org.uk> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Ian Campbell Cc: Stefano Stabellini , "Tim (Xen.org)" , Ian Campbell , "xen-devel@lists.xen.org" List-Id: xen-devel@lists.xenproject.org On Wed, 6 Mar 2013, Ian Campbell wrote: > From: Ian Campbell > > 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 Acked-by: Stefano Stabellini > xen/arch/arm/vgic.c | 11 +++++++---- > 1 file changed, 7 insertions(+), 4 deletions(-) > > diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c > index dbfcd04..b30da78 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,20 +606,18 @@ 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); > 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 */ > -out: > vcpu_unblock(v); > } > > -- > 1.7.10.4 >