|
[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 |