[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 3/8] xen: arm: Refactor route_irq_to_guest
Split out the bit which allocates the struct irqaction and calls __setup_irq into a new function (setup_guest_irq). I'm going to want to call this a second time in a subsequent patch. Note that the action is now allocated and initialised with the desc lock held (since it is taken by the caller). I don't think this is an issue (and avoiding this would make things more complex) Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> --- v2: New patch (maybe, it's been a while...) --- xen/arch/arm/irq.c | 104 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 61 insertions(+), 43 deletions(-) diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c index 5031777..6918438 100644 --- a/xen/arch/arm/irq.c +++ b/xen/arch/arm/irq.c @@ -394,61 +394,24 @@ bool_t is_assignable_irq(unsigned int irq) return ((irq >= NR_LOCAL_IRQS) && (irq < gic_number_lines())); } -/* - * Route an IRQ to a specific guest. - * For now only SPIs are assignable to the guest. - */ -int route_irq_to_guest(struct domain *d, unsigned int virq, - unsigned int irq, const char * devname) +static int setup_guest_irq(struct irq_desc *desc, unsigned int virq, + unsigned int irqflags, + struct irq_guest *info, const char *devname) { + const unsigned irq = desc->irq; struct irqaction *action; - struct irq_guest *info; - struct irq_desc *desc; - unsigned long flags; int retval = 0; - if ( virq >= vgic_num_irqs(d) ) - { - printk(XENLOG_G_ERR - "the vIRQ number %u is too high for domain %u (max = %u)\n", - irq, d->domain_id, vgic_num_irqs(d)); - return -EINVAL; - } - - /* Only routing to virtual SPIs is supported */ - if ( virq < NR_LOCAL_IRQS ) - { - printk(XENLOG_G_ERR "IRQ can only be routed to an SPI\n"); - return -EINVAL; - } - - if ( !is_assignable_irq(irq) ) - { - printk(XENLOG_G_ERR "the IRQ%u is not routable\n", irq); - return -EINVAL; - } - desc = irq_to_desc(irq); + ASSERT(spin_is_locked(&desc->lock)); action = xmalloc(struct irqaction); if ( !action ) return -ENOMEM; - info = xmalloc(struct irq_guest); - if ( !info ) - { - xfree(action); - return -ENOMEM; - } - - info->d = d; - info->virq = virq; - action->dev_id = info; action->name = devname; action->free_on_release = 1; - spin_lock_irqsave(&desc->lock, flags); - if ( desc->arch.type == DT_IRQ_TYPE_INVALID ) { printk(XENLOG_G_ERR "IRQ %u has not been configured\n", irq); @@ -466,6 +429,7 @@ int route_irq_to_guest(struct domain *d, unsigned int virq, */ if ( desc->action != NULL ) { + struct domain *d = info->d; struct domain *ad = irq_get_domain(desc); if ( test_bit(_IRQ_GUEST, &desc->status) && d == ad ) @@ -493,6 +457,61 @@ int route_irq_to_guest(struct domain *d, unsigned int virq, if ( retval ) goto out; + return 0; + +out: + xfree(action); + return retval; +} + +/* + * Route an IRQ to a specific guest. + * For now only SPIs are assignable to the guest. + */ +int route_irq_to_guest(struct domain *d, unsigned int virq, + unsigned int irq, const char * devname) +{ + struct irq_guest *info; + struct irq_desc *desc; + unsigned long flags; + int retval; + + if ( virq >= vgic_num_irqs(d) ) + { + printk(XENLOG_G_ERR + "the vIRQ number %u is too high for domain %u (max = %u)\n", + irq, d->domain_id, vgic_num_irqs(d)); + return -EINVAL; + } + + /* Only routing to virtual SPIs is supported */ + if ( virq < NR_LOCAL_IRQS ) + { + printk(XENLOG_G_ERR "IRQ can only be routed to an SPI\n"); + return -EINVAL; + } + + if ( !is_assignable_irq(irq) ) + { + printk(XENLOG_G_ERR "the IRQ%u is not routable\n", irq); + return -EINVAL; + } + + desc = irq_to_desc(irq); + + info = xmalloc(struct irq_guest); + if ( !info ) + return -ENOMEM; + + info->d = d; + info->virq = virq; + + spin_lock_irqsave(&desc->lock, flags); + + retval = setup_guest_irq(desc, virq, flags, info, devname); + if ( retval ) + goto out; + retval = gic_route_irq_to_guest(d, virq, desc, GIC_PRI_IRQ); spin_unlock_irqrestore(&desc->lock, flags); @@ -507,7 +526,6 @@ int route_irq_to_guest(struct domain *d, unsigned int virq, out: spin_unlock_irqrestore(&desc->lock, flags); - xfree(action); free_info: xfree(info); -- 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 |