From: Eric W. Biederman Likewise we need to place the local apic in virtual wire mode on reboot for x86_64. Signed-off-by: Andrew Morton --- 25-akpm/arch/x86_64/kernel/apic.c | 30 ++++++++++++++++++++++++++++++ 1 files changed, 30 insertions(+) diff -puN arch/x86_64/kernel/apic.c~kexec-apic-virtwire-on-shutdownx86_64 arch/x86_64/kernel/apic.c --- 25/arch/x86_64/kernel/apic.c~kexec-apic-virtwire-on-shutdownx86_64 2004-10-28 18:45:17.774605648 -0700 +++ 25-akpm/arch/x86_64/kernel/apic.c 2004-10-28 18:45:17.779604888 -0700 @@ -145,6 +145,36 @@ void disconnect_bsp_APIC(void) outb(0x70, 0x22); outb(0x00, 0x23); } + else { + /* Go back to Virtual Wire compatibility mode */ + unsigned long value; + + /* For the spurious interrupt use vector F, and enable it */ + value = apic_read(APIC_SPIV); + value &= ~APIC_VECTOR_MASK; + value |= APIC_SPIV_APIC_ENABLED; + value |= 0xf; + apic_write_around(APIC_SPIV, value); + + /* For LVT0 make it edge triggered, active high, external and enabled */ + value = apic_read(APIC_LVT0); + value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING | + APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | + APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED ); + value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; + value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXINT); + apic_write_around(APIC_LVT0, value); + + /* For LVT1 make it edge triggered, active high, nmi and enabled */ + value = apic_read(APIC_LVT1); + value &= ~( + APIC_MODE_MASK | APIC_SEND_PENDING | + APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | + APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED); + value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; + value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI); + apic_write_around(APIC_LVT1, value); + } } void disable_local_APIC(void) _