x86, x2apic: use virtual wire A mode in disable_IO_APIC() with interrupt-remapping
authorSuresh Siddha <suresh.b.siddha@intel.com>
Tue, 17 Mar 2009 00:04:59 +0000 (17:04 -0700)
committerH. Peter Anvin <hpa@linux.intel.com>
Tue, 17 Mar 2009 22:42:28 +0000 (15:42 -0700)
Impact: make kexec work with x2apic

disable_IO_APIC() gets called during crashdump aswell, which configures the
IO-APIC/LAPIC so that legacy interrupts can be delivered for the kexec'd kernel.

In the presence of interrupt-remapping, we need to change the
interrupt-remapping configuration aswell as modifying IO-APIC for virtual wire
B mode.

To keep things simple during the crash, use virtual wire A mode
(for which we don't need to touch io-apic and interrupt-remapping tables).

Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
arch/x86/kernel/apic/io_apic.c

index b18a773..4d975d0 100644 (file)
@@ -2040,8 +2040,13 @@ void disable_IO_APIC(void)
         * If the i8259 is routed through an IOAPIC
         * Put that IOAPIC in virtual wire mode
         * so legacy interrupts can be delivered.
+        *
+        * With interrupt-remapping, for now we will use virtual wire A mode,
+        * as virtual wire B is little complex (need to configure both
+        * IOAPIC RTE aswell as interrupt-remapping table entry).
+        * As this gets called during crash dump, keep this simple for now.
         */
-       if (ioapic_i8259.pin != -1) {
+       if (ioapic_i8259.pin != -1 && !intr_remapping_enabled) {
                struct IO_APIC_route_entry entry;
 
                memset(&entry, 0, sizeof(entry));
@@ -2061,7 +2066,10 @@ void disable_IO_APIC(void)
                ioapic_write_entry(ioapic_i8259.apic, ioapic_i8259.pin, entry);
        }
 
-       disconnect_bsp_APIC(ioapic_i8259.pin != -1);
+       /*
+        * Use virtual wire A mode when interrupt remapping is enabled.
+        */
+       disconnect_bsp_APIC(!intr_remapping_enabled && ioapic_i8259.pin != -1);
 }
 
 #ifdef CONFIG_X86_32