At early at MADT parse time, mp_config_acpi_legacy_irqs() creates an mp_irqs[] entry for the IRQs < 16. Later at IO-APIC initialization time, setup_IO_APIC_irqs() goes through all the IOAPIC pins, and for each one idx = find_irq_entry(apic,pin,mp_INT) finds the mp_irqs[] index. irq = pin_2_irq(idx, apic, pin) gets the IRQ back from mp_irqs[].srcbusirq add_pin_to_irq(irq, ioapic, pin) adds that pin to the IRQ irq_2_pin pin-map. Later the _PRT is processed, and io_apic_set_pci_routing(apic, pin, gsi, flags) calls add_pin_to_irq(irq, ioapic, pin) before setting up the IOAPIC RTE. The bug is that if the IRQ is < 16, then the pin was added to the IRQ pin-map twice eg. ACPI: PCI Interrupt Link [LM5B] enabled at IRQ 10 IOAPIC[0]: Set PCI routing entry (14-10 -> 0x79 -> IRQ 10 Mode:1 Active:1) 00:02:05[B] -> 14-10 -> IRQ 10 ACPI: PCI Interrupt Link [LM1B] enabled at IRQ 15 IOAPIC[0]: Set PCI routing entry (14-15 -> 0xa1 -> IRQ 15 Mode:1 Active:1) 00:00:01[B] -> 14-15 -> IRQ 15 IRQ to pin mappings: IRQ0 -> 0:0 IRQ1 -> 0:1 IRQ3 -> 0:3 IRQ4 -> 0:4 IRQ5 -> 0:5 IRQ6 -> 0:6 IRQ7 -> 0:7 IRQ8 -> 0:8 IRQ9 -> 0:9 IRQ10 -> 0:10 -> 0:10 IRQ11 -> 0:11 IRQ12 -> 0:12 IRQ13 -> 0:13 IRQ14 -> 0:14 IRQ15 -> 0:15 -> 0:15 This causes all physical access to the IOAPIC at run-time to be done twice, as if two different pins were involved. Unknown if this rough edge causes any actual run-time failures.
Created attachment 2471 [details] proposed fix (i386 and x86_64, vs 2.6.5)
Created attachment 2476 [details] dmesg before patch
Created attachment 2477 [details] dmesg after patch thanks to Trond Myklebust for running this test that shows the patch works.
fix is in 2.6.5 and > 2.4.26-rc1 -- closing.