Stefano Stabellini
2013-Jan-15 19:14 UTC
[PATCH v2 2/2] xen/arm: initialize the GIC irq properties of interrupts routed to guests
We are currently initializing GIC irq properties (ITARGETSR, IPRIORITYR, and GICD_ICFGR) only in gic_route_irq, that is not called for guest interrupts at all. Move the initialization into a separate function (gic_set_irq_properties) and call it from gic_route_irq_to_guest. Changes in v2: - rebased on 77d3a1db3196b1b5864469f8d3f41d496800c795. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> --- xen/arch/arm/gic.c | 49 +++++++++++++++++++++++++++++++------------------ 1 files changed, 31 insertions(+), 18 deletions(-) diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index 293efdc..165287c 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -174,12 +174,36 @@ static hw_irq_controller gic_guest_irq_type = { .set_affinity = gic_irq_set_affinity, }; +/* needs to be called with gic.lock held */ +static void gic_set_irq_properties(unsigned int irq, bool_t level, + unsigned int cpu_mask, unsigned int priority) +{ + volatile unsigned char *bytereg; + uint32_t cfg, edgebit; + + /* Set edge / level */ + cfg = GICD[GICD_ICFGR + irq / 16]; + edgebit = 2u << (2 * (irq % 16)); + if ( level ) + cfg &= ~edgebit; + else + cfg |= edgebit; + GICD[GICD_ICFGR + irq / 16] = cfg; + + /* Set target CPU mask (RAZ/WI on uniprocessor) */ + bytereg = (unsigned char *) (GICD + GICD_ITARGETSR); + bytereg[irq] = cpu_mask; + + /* Set priority */ + bytereg = (unsigned char *) (GICD + GICD_IPRIORITYR); + bytereg[irq] = priority; + +} + /* Program the GIC to route an interrupt */ static int gic_route_irq(unsigned int irq, bool_t level, unsigned int cpu_mask, unsigned int priority) { - volatile unsigned char *bytereg; - uint32_t cfg, edgebit; struct irq_desc *desc = irq_to_desc(irq); unsigned long flags; @@ -202,22 +226,7 @@ static int gic_route_irq(unsigned int irq, bool_t level, /* Disable interrupt */ desc->handler->shutdown(desc); - /* Set edge / level */ - cfg = GICD[GICD_ICFGR + irq / 16]; - edgebit = 2u << (2 * (irq % 16)); - if ( level ) - cfg &= ~edgebit; - else - cfg |= edgebit; - GICD[GICD_ICFGR + irq / 16] = cfg; - - /* Set target CPU mask (RAZ/WI on uniprocessor) */ - bytereg = (unsigned char *) (GICD + GICD_ITARGETSR); - bytereg[irq] = cpu_mask; - - /* Set priority */ - bytereg = (unsigned char *) (GICD + GICD_IPRIORITYR); - bytereg[irq] = priority; + gic_set_irq_properties(irq, level, cpu_mask, priority); spin_unlock(&gic.lock); spin_unlock_irqrestore(&desc->lock, flags); @@ -561,10 +570,13 @@ int gic_route_irq_to_guest(struct domain *d, unsigned int irq, action->name = devname; spin_lock_irqsave(&desc->lock, flags); + spin_lock(&gic.lock); desc->handler = &gic_guest_irq_type; desc->status |= IRQ_GUEST; + gic_set_irq_properties(irq, 1, 1u << smp_processor_id(), 0xa0); + retval = __setup_irq(desc, irq, action); if (retval) { xfree(action); @@ -572,6 +584,7 @@ int gic_route_irq_to_guest(struct domain *d, unsigned int irq, } out: + spin_unlock(&gic.lock); spin_unlock_irqrestore(&desc->lock, flags); return retval; } -- 1.7.2.5
Possibly Parallel Threads
- [PATCH v2 13/15] xen: arm: Add debug keyhandler to dump the physical GIC state.
- [PATCH v5 0/7] Dissociate logical and gic/hardware CPU ID
- [PATCH] xen/arm: Missing +1 when then number of interrupt lines for the GIC is computed
- [PATCH v2] xen/arm: Use the right GICD register to initialize IRQs routing
- [PATCH v4 00/25] xen: ARMv7 with virtualization extensions