Commit 67e8e04a authored by Maciej W. Rozycki's avatar Maciej W. Rozycki Committed by Linus Torvalds

[PATCH] x86, x86_64: Only handle system NMIs on the BSP

 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: default avatarMaciej W. Rozycki <macro@linux-mips.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 8301d51f
...@@ -583,7 +583,11 @@ void die_nmi (struct pt_regs *regs, const char *msg) ...@@ -583,7 +583,11 @@ void die_nmi (struct pt_regs *regs, const char *msg)
static void default_do_nmi(struct pt_regs * regs) 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 (!(reason & 0xc0)) {
if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT) if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT)
......
...@@ -580,9 +580,13 @@ static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs) ...@@ -580,9 +580,13 @@ static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
printk("Do you have a strange power saving mode enabled?\n"); 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 (!(reason & 0xc0)) {
if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT) if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment