From: "Maciej W. Rozycki" While discussing races in the NMI handler's trailer fiddling with RTC registers, I've discovered we incorrectly attempt to handle NMIs coming from the system (memory errors, IOCHK# assertions, etc.) with all processors even though the interrupts are only routed to the bootstrap processor. If one of these events coincides with a NMI watchdog tick it may even be handled multiple times in parallel. Here is a fix that makes application processors ignore these events. They no longer access the NMI status bits at I/O port 0x61 which has also the advantage of removing the contention on the port when the I/O APIC NMI watchdog makes all processors arrive at the handler at the same time. Signed-off-by: Maciej W. Rozycki Signed-off-by: Andrew Morton --- 25-akpm/arch/i386/kernel/traps.c | 6 +++++- 25-akpm/arch/x86_64/kernel/traps.c | 8 ++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff -puN arch/i386/kernel/traps.c~x86-x86_64-only-handle-system-nmis-on-the-bsp arch/i386/kernel/traps.c --- 25/arch/i386/kernel/traps.c~x86-x86_64-only-handle-system-nmis-on-the-bsp Wed Nov 3 15:37:20 2004 +++ 25-akpm/arch/i386/kernel/traps.c Wed Nov 3 15:37:20 2004 @@ -583,7 +583,11 @@ void die_nmi (struct pt_regs *regs, cons static void default_do_nmi(struct pt_regs * regs) { - unsigned char reason = get_nmi_reason(); + unsigned char reason = 0; + + /* Only the BSP gets external NMIs from the system. */ + if (!smp_processor_id()) + reason = get_nmi_reason(); if (!(reason & 0xc0)) { if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT) diff -puN arch/x86_64/kernel/traps.c~x86-x86_64-only-handle-system-nmis-on-the-bsp arch/x86_64/kernel/traps.c --- 25/arch/x86_64/kernel/traps.c~x86-x86_64-only-handle-system-nmis-on-the-bsp Wed Nov 3 15:37:20 2004 +++ 25-akpm/arch/x86_64/kernel/traps.c Wed Nov 3 15:38:48 2004 @@ -580,9 +580,13 @@ static void unknown_nmi_error(unsigned c printk("Do you have a strange power saving mode enabled?\n"); } -asmlinkage void default_do_nmi(struct pt_regs * regs) +asmlinkage void default_do_nmi(struct pt_regs *regs) { - unsigned char reason = get_nmi_reason(); + unsigned char reason; + + /* Only the BSP gets external NMIs from the system. */ + if (!smp_processor_id()) + reason = get_nmi_reason(); if (!(reason & 0xc0)) { if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT) _