Skip to content

Commit f1c6300

Browse files
Suresh SiddhaH. Peter Anvin
authored andcommitted
x86, apic: fix broken legacy interrupts in the logical apic mode
Recent commit 332afa6 cleaned up a workaround that updates irq_cfg domain for legacy irq's that are handled by the IO-APIC. This was assuming that the recent changes in assign_irq_vector() were sufficient to remove the workaround. But this broke couple of AMD platforms. One of them seems to be sending interrupts to the offline cpu's, resulting in spurious "No irq handler for vector xx (irq -1)" messages when those cpu's come online. And the other platform seems to always send the interrupt to the last logical CPU (cpu-7). Recent changes had an unintended side effect of using only logical cpu-0 in the IO-APIC RTE (during boot for the legacy interrupts) and this broke the legacy interrupts not getting routed to the cpu-7 on the AMD platform, resulting in a boot hang. For now, reintroduce the removed workaround, (essentially not allowing the vector to change for legacy irq's when io-apic starts to handle the irq. Which also addressed the uninteded sife effect of just specifying cpu-0 in the IO-APIC RTE for those irq's during boot). Reported-and-tested-by: Robert Richter <[email protected]> Reported-and-tested-by: Borislav Petkov <[email protected]> Signed-off-by: Suresh Siddha <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: H. Peter Anvin <[email protected]>
1 parent 484d90e commit f1c6300

File tree

1 file changed

+10
-0
lines changed

1 file changed

+10
-0
lines changed

arch/x86/kernel/apic/io_apic.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,6 +1356,16 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg,
13561356
if (!IO_APIC_IRQ(irq))
13571357
return;
13581358

1359+
/*
1360+
* For legacy irqs, cfg->domain starts with cpu 0. Now that IO-APIC
1361+
* can handle this irq and the apic driver is finialized at this point,
1362+
* update the cfg->domain.
1363+
*/
1364+
if (irq < legacy_pic->nr_legacy_irqs &&
1365+
cpumask_equal(cfg->domain, cpumask_of(0)))
1366+
apic->vector_allocation_domain(0, cfg->domain,
1367+
apic->target_cpus());
1368+
13591369
if (assign_irq_vector(irq, cfg, apic->target_cpus()))
13601370
return;
13611371

0 commit comments

Comments
 (0)