diff --git a/xen/arch/x86/i8259.c b/xen/arch/x86/i8259.c index ed9f55abe5..e0fa1f96b4 100644 --- a/xen/arch/x86/i8259.c +++ b/xen/arch/x86/i8259.c @@ -222,7 +222,8 @@ static bool _mask_and_ack_8259A_irq(unsigned int irq) is_real_irq = false; /* Report spurious IRQ, once per IRQ line. */ if (!(spurious_irq_mask & irqmask)) { - printk("spurious 8259A interrupt: IRQ%d.\n", irq); + printk("cpu%u: spurious 8259A interrupt: IRQ%u\n", + smp_processor_id(), irq); spurious_irq_mask |= irqmask; } /* @@ -349,7 +350,23 @@ void __init init_IRQ(void) continue; desc->handler = &i8259A_irq_type; per_cpu(vector_irq, cpu)[LEGACY_VECTOR(irq)] = irq; - cpumask_copy(desc->arch.cpu_mask, cpumask_of(cpu)); + + /* + * The interrupt affinity logic never targets interrupts to offline + * CPUs, hence it's safe to use cpumask_all here. + * + * Legacy PIC interrupts are only targeted to CPU0, but depending on + * the platform they can be distributed to any online CPU in hardware. + * Note this behavior has only been observed on AMD hardware. In order + * to cope install all active legacy vectors on all CPUs. + * + * IO-APIC will change the destination mask if/when taking ownership of + * the interrupt. + */ + cpumask_copy(desc->arch.cpu_mask, + (boot_cpu_data.x86_vendor & + (X86_VENDOR_AMD | X86_VENDOR_HYGON) ? &cpumask_all + : cpumask_of(cpu))); desc->arch.vector = LEGACY_VECTOR(irq); } diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index f42ad539dc..16d9fceba1 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -1920,7 +1920,16 @@ void do_IRQ(struct cpu_user_regs *regs) kind = ""; if ( !(vector >= FIRST_LEGACY_VECTOR && vector <= LAST_LEGACY_VECTOR && - !smp_processor_id() && + (!smp_processor_id() || + /* + * For AMD/Hygon do spurious PIC interrupt + * detection on all CPUs, as it has been observed + * that during unknown circumstances spurious PIC + * interrupts have been delivered to CPUs + * different than the BSP. + */ + (boot_cpu_data.x86_vendor & (X86_VENDOR_AMD | + X86_VENDOR_HYGON))) && bogus_8259A_irq(vector - FIRST_LEGACY_VECTOR)) ) { printk("CPU%u: No irq handler for vector %02x (IRQ %d%s)\n",