[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v8 03/27] ARM: GIC: Add checks for NULL pointer pending_irq's
Hi, On 12/04/17 11:25, Julien Grall wrote: > Hi Andre, > > On 12/04/17 01:44, Andre Przywara wrote: >> For LPIs the struct pending_irq's are dynamically allocated and the >> pointers will be stored in a radix tree. Since an LPI can be "unmapped" >> at any time, teach the VGIC how to handle with irq_to_pending() returning >> a NULL pointer. >> We just do nothing in this case or clean up the LR if the virtual LPI >> number was still in an LR. > > Why not all the irq_to_pending call are not protected (such as > vgic_irq_to_migrate)? Some of them are never called by LPIs. Is it worth the put ASSERTs in there everywhere? I can copy the table with all call sites and their evaluations from that other email into this commit message, if that sounds good. Fixed the rest. Cheers, Andre. > This is a call to forget to check NULL if we > decide to use the function in the future. > > Also, I would like a comment on top of irq_to_pending stating this can > return NULL as you change the semantic of the function. >> >> Signed-off-by: Andre Przywara <andre.przywara@xxxxxxx> >> --- >> xen/arch/arm/gic.c | 37 ++++++++++++++++++++++++++++++++----- >> xen/arch/arm/vgic.c | 6 ++++++ >> 2 files changed, 38 insertions(+), 5 deletions(-) >> >> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c >> index dcb1783..62ae3b8 100644 >> --- a/xen/arch/arm/gic.c >> +++ b/xen/arch/arm/gic.c >> @@ -408,9 +408,15 @@ void gic_remove_from_queues(struct vcpu *v, >> unsigned int virtual_irq) >> spin_lock_irqsave(&v->arch.vgic.lock, flags); >> >> p = irq_to_pending(v, virtual_irq); >> - >> - if ( !list_empty(&p->lr_queue) ) >> - list_del_init(&p->lr_queue); >> + /* >> + * If an LPIs has been removed meanwhile, it has been cleaned up >> + * already, so nothing to remove here. >> + */ >> + if ( p ) >> + { >> + if ( !list_empty(&p->lr_queue) ) >> + list_del_init(&p->lr_queue); >> + } > > This could be simplified with: > > if ( p && !list_empty(&p->lr_queue) ) > list_del_init(...); > > Also, you probably want a likely(p). > >> spin_unlock_irqrestore(&v->arch.vgic.lock, flags); >> } >> >> @@ -418,6 +424,10 @@ void gic_raise_inflight_irq(struct vcpu *v, >> unsigned int virtual_irq) >> { >> struct pending_irq *n = irq_to_pending(v, virtual_irq); >> >> + /* If an LPI has been removed meanwhile, there is nothing left to >> raise. */ >> + if ( !n ) > > if ( unlikely(!n) ) > >> + return; >> + >> ASSERT(spin_is_locked(&v->arch.vgic.lock)); >> >> if ( list_empty(&n->lr_queue) ) >> @@ -437,6 +447,11 @@ void gic_raise_guest_irq(struct vcpu *v, unsigned >> int virtual_irq, >> { >> int i; >> unsigned int nr_lrs = gic_hw_ops->info->nr_lrs; >> + struct pending_irq *p = irq_to_pending(v, virtual_irq); >> + >> + if ( !p ) > > if ( unlikely(!p) ) > >> + /* An unmapped LPI does not need to be raised. */ >> + return; > > Please move this check after the ASSERT to keep the check on all the paths. > >> >> ASSERT(spin_is_locked(&v->arch.vgic.lock)); >> >> @@ -445,12 +460,12 @@ void gic_raise_guest_irq(struct vcpu *v, >> unsigned int virtual_irq, >> i = find_first_zero_bit(&this_cpu(lr_mask), nr_lrs); >> if (i < nr_lrs) { >> set_bit(i, &this_cpu(lr_mask)); >> - gic_set_lr(i, irq_to_pending(v, virtual_irq), >> GICH_LR_PENDING); >> + gic_set_lr(i, p, GICH_LR_PENDING); >> return; >> } >> } >> >> - gic_add_to_lr_pending(v, irq_to_pending(v, virtual_irq)); >> + gic_add_to_lr_pending(v, p); >> } >> >> static void gic_update_one_lr(struct vcpu *v, int i) >> @@ -464,7 +479,19 @@ static void gic_update_one_lr(struct vcpu *v, int i) >> >> gic_hw_ops->read_lr(i, &lr_val); >> irq = lr_val.virq; >> + > > 4th time I am saying this.... Spurious line. > >> p = irq_to_pending(v, irq); >> + /* An LPI might have been unmapped, in which case we just clean >> up here. */ >> + if ( !p ) > > unlikely(!p) > >> + { >> + ASSERT(is_lpi(irq)); >> + >> + gic_hw_ops->clear_lr(i); >> + clear_bit(i, &this_cpu(lr_mask)); >> + >> + return; >> + } >> + >> if ( lr_val.state & GICH_LR_ACTIVE ) >> { >> set_bit(GIC_IRQ_GUEST_ACTIVE, &p->status); >> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c >> index c953f13..b9fc837 100644 >> --- a/xen/arch/arm/vgic.c >> +++ b/xen/arch/arm/vgic.c >> @@ -473,6 +473,12 @@ void vgic_vcpu_inject_irq(struct vcpu *v, >> unsigned int virq) >> spin_lock_irqsave(&v->arch.vgic.lock, flags); >> >> n = irq_to_pending(v, virq); >> + /* If an LPI has been removed, there is nothing to inject here. */ >> + if ( !n ) > > unlikely(...) > >> + { >> + spin_unlock_irqrestore(&v->arch.vgic.lock, flags); >> + return; >> + } >> >> priority = vgic_get_virq_priority(v, virq); >> >> > > Cheers, > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |