[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v3 10/24] xen/arm: gic: Add sanity checks gic_route_irq_to_guest
On Tue, 13 Jan 2015, Julien Grall wrote: > With the addition of interrupt assignment to guest, we need to make sure > the guest don't blow up the interrupt management in Xen. > > Before associating the IRQ to a vIRQ we need to make sure: > - the vIRQ is not already associated to another IRQ > - the guest didn't enable the vIRQ > > Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx> Acked-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> > Changes in v3: > - Patch added > --- > xen/arch/arm/gic.c | 34 ++++++++++++++++++++++++++-------- > xen/arch/arm/irq.c | 12 ++++++++++-- > xen/include/asm-arm/gic.h | 7 +++---- > 3 files changed, 39 insertions(+), 14 deletions(-) > > diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c > index 15de283..240870f 100644 > --- a/xen/arch/arm/gic.c > +++ b/xen/arch/arm/gic.c > @@ -126,22 +126,40 @@ void gic_route_irq_to_xen(struct irq_desc *desc, const > cpumask_t *cpu_mask, > /* Program the GIC to route an interrupt to a guest > * - desc.lock must be held > */ > -void gic_route_irq_to_guest(struct domain *d, unsigned int virq, > - struct irq_desc *desc, > - const cpumask_t *cpu_mask, unsigned int priority) > +int gic_route_irq_to_guest(struct domain *d, unsigned int virq, > + struct irq_desc *desc, unsigned int priority) > { > - struct pending_irq *p; > + unsigned long flags; > + /* Use vcpu0 to retrieve the pending_irq struct. Given that we only > + * route SPIs to guests, it doesn't make any difference. */ > + struct vcpu *v_target = vgic_get_target_vcpu(d->vcpu[0], virq); > + struct vgic_irq_rank *rank = vgic_rank_irq(v_target, virq); > + struct pending_irq *p = irq_to_pending(v_target, virq); > + int res = -EBUSY; > + > ASSERT(spin_is_locked(&desc->lock)); > + /* We only support SPIs */ > + ASSERT(virq >= 32 && virq < vgic_num_irqs(d)); > + > + vgic_lock_rank(v_target, rank, flags); > + > + if ( p->desc || > + /* The VIRQ should not be already enabled by the guest */ > + test_bit(GIC_IRQ_GUEST_ENABLED, &p->status) ) > + goto out; > > desc->handler = gic_hw_ops->gic_guest_irq_type; > set_bit(_IRQ_GUEST, &desc->status); > > - gic_set_irq_properties(desc, cpumask_of(smp_processor_id()), > GIC_PRI_IRQ); > + gic_set_irq_properties(desc, cpumask_of(v_target->processor), priority); > > - /* Use vcpu0 to retrieve the pending_irq struct. Given that we only > - * route SPIs to guests, it doesn't make any difference. */ > - p = irq_to_pending(d->vcpu[0], virq); > p->desc = desc; > + res = 0; > + > +out: > + vgic_unlock_rank(v_target, rank, flags); > + > + return res; > } > > int gic_irq_xlate(const u32 *intspec, unsigned int intsize, > diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c > index af408ac..0072347 100644 > --- a/xen/arch/arm/irq.c > +++ b/xen/arch/arm/irq.c > @@ -483,14 +483,22 @@ int route_irq_to_guest(struct domain *d, unsigned int > virq, > if ( retval ) > goto out; > > - gic_route_irq_to_guest(d, virq, desc, cpumask_of(smp_processor_id()), > - GIC_PRI_IRQ); > + retval = gic_route_irq_to_guest(d, virq, desc, GIC_PRI_IRQ); > + > spin_unlock_irqrestore(&desc->lock, flags); > + > + if ( retval ) > + { > + release_irq(desc->irq, info); > + goto free_info; > + } > + > return 0; > > out: > spin_unlock_irqrestore(&desc->lock, flags); > xfree(action); > +free_info: > xfree(info); > > return retval; > diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h > index cf9f257..a8ac294 100644 > --- a/xen/include/asm-arm/gic.h > +++ b/xen/include/asm-arm/gic.h > @@ -213,10 +213,9 @@ extern enum gic_version gic_hw_version(void); > /* Program the GIC to route an interrupt */ > extern void gic_route_irq_to_xen(struct irq_desc *desc, const cpumask_t > *cpu_mask, > unsigned int priority); > -extern void gic_route_irq_to_guest(struct domain *, unsigned int virq, > - struct irq_desc *desc, > - const cpumask_t *cpu_mask, > - unsigned int priority); > +extern int gic_route_irq_to_guest(struct domain *, unsigned int virq, > + struct irq_desc *desc, > + unsigned int priority); > > extern void gic_inject(void); > extern void gic_clear_pending_irqs(struct vcpu *v); > -- > 2.1.4 > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |