From: Jan Beulich Date: Tue, 2 Apr 2013 06:30:03 +0000 (+0200) Subject: x86: irq_move_cleanup_interrupt() must ignore legacy vectors X-Git-Tag: 4.3.0-rc1~150 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=af699220ad6d111ba76fc3040342184e423cc9a1;p=xen.git x86: irq_move_cleanup_interrupt() must ignore legacy vectors Since the main loop in the function includes legacy vectors, and since vector_irq[] gets set up for legacy vectors regardless of whether those get handled through the IO-APIC, it must not do anything on this vector range. In fact, we should never get past the move_cleanup_count check for IRQs not handled through the IO-APIC. Adding a respective assertion woulkd make those iterations more expensive (due to the lock acquire). For such an assertion to not have false positives we however ought to suppress setting up IRQ2 as an 8259A interrupt (which wasn't correct anyway), which is being done here despite the assertion not actually getting added. Furthermore, there's no point iterating over the vectors past LAST_HIPRIORITY_VECTOR, so terminate the loop accordingly. Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper Acked-by: Keir Fraser --- diff --git a/xen/arch/x86/i8259.c b/xen/arch/x86/i8259.c index f637ecc891..b537c5f25f 100644 --- a/xen/arch/x86/i8259.c +++ b/xen/arch/x86/i8259.c @@ -416,6 +416,8 @@ void __init init_IRQ(void) for (irq = 0; platform_legacy_irq(irq); irq++) { struct irq_desc *desc = irq_to_desc(irq); + if ( irq == 2 ) /* IRQ2 doesn't exist */ + continue; desc->handler = &i8259A_irq_type; per_cpu(vector_irq, cpu)[FIRST_LEGACY_VECTOR + irq] = irq; cpumask_copy(desc->arch.cpu_mask, cpumask_of(cpu)); diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index 5e0f463c38..fff9f1d353 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -616,7 +616,9 @@ void irq_move_cleanup_interrupt(struct cpu_user_regs *regs) ack_APIC_irq(); me = smp_processor_id(); - for (vector = FIRST_DYNAMIC_VECTOR; vector < NR_VECTORS; vector++) { + for ( vector = FIRST_DYNAMIC_VECTOR; + vector <= LAST_HIPRIORITY_VECTOR; vector++) + { unsigned int irq; unsigned int irr; struct irq_desc *desc; @@ -625,6 +627,9 @@ void irq_move_cleanup_interrupt(struct cpu_user_regs *regs) if ((int)irq < 0) continue; + if ( vector >= FIRST_LEGACY_VECTOR && vector <= LAST_LEGACY_VECTOR ) + continue; + desc = irq_to_desc(irq); if (!desc) continue;