Signed-off-by: Andrew Morton --- arch/i386/kernel/traps.c | 6 ++++++ arch/x86_64/kernel/traps.c | 6 ++++++ include/linux/kernel.h | 1 + include/linux/sysctl.h | 1 + kernel/panic.c | 1 + kernel/sysctl.c | 8 ++++++++ 6 files changed, 23 insertions(+) diff -puN arch/i386/kernel/traps.c~x86_64-mm-allow-users-to-force-a-panic-on-nmi arch/i386/kernel/traps.c --- a/arch/i386/kernel/traps.c~x86_64-mm-allow-users-to-force-a-panic-on-nmi +++ a/arch/i386/kernel/traps.c @@ -633,6 +633,8 @@ static void mem_parity_error(unsigned ch "to continue\n"); printk(KERN_EMERG "You probably have a hardware problem with your RAM " "chips\n"); + if (panic_on_unrecovered_nmi) + panic("NMI: Not continuing"); /* Clear and disable the memory parity error line. */ clear_mem_error(reason); @@ -668,6 +670,10 @@ static void unknown_nmi_error(unsigned c reason, smp_processor_id()); printk("Dazed and confused, but trying to continue\n"); printk("Do you have a strange power saving mode enabled?\n"); + + if (panic_on_unrecovered_nmi) + panic("NMI: Not continuing"); + } static DEFINE_SPINLOCK(nmi_print_lock); diff -puN arch/x86_64/kernel/traps.c~x86_64-mm-allow-users-to-force-a-panic-on-nmi arch/x86_64/kernel/traps.c --- a/arch/x86_64/kernel/traps.c~x86_64-mm-allow-users-to-force-a-panic-on-nmi +++ a/arch/x86_64/kernel/traps.c @@ -729,6 +729,8 @@ mem_parity_error(unsigned char reason, s { printk("Uhhuh. NMI received. Dazed and confused, but trying to continue\n"); printk("You probably have a hardware problem with your RAM chips\n"); + if (panic_on_unrecovered_nmi) + panic("NMI: Not continuing"); /* Clear and disable the memory parity error line. */ reason = (reason & 0xf) | 4; @@ -754,6 +756,10 @@ unknown_nmi_error(unsigned char reason, { printk("Uhhuh. NMI received for unknown reason %02x.\n", reason); printk("Dazed and confused, but trying to continue\n"); printk("Do you have a strange power saving mode enabled?\n"); + + if (panic_on_unrecovered_nmi) + panic("NMI: Not continuing"); + } /* Runs on IST stack. This code must keep interrupts off all the time. diff -puN include/linux/kernel.h~x86_64-mm-allow-users-to-force-a-panic-on-nmi include/linux/kernel.h --- a/include/linux/kernel.h~x86_64-mm-allow-users-to-force-a-panic-on-nmi +++ a/include/linux/kernel.h @@ -187,6 +187,7 @@ extern void bust_spinlocks(int yes); extern int oops_in_progress; /* If set, an oops, panic(), BUG() or die() is in progress */ extern int panic_timeout; extern int panic_on_oops; +extern int panic_on_unrecovered_nmi; extern int tainted; extern const char *print_tainted(void); extern void add_taint(unsigned); diff -puN include/linux/sysctl.h~x86_64-mm-allow-users-to-force-a-panic-on-nmi include/linux/sysctl.h --- a/include/linux/sysctl.h~x86_64-mm-allow-users-to-force-a-panic-on-nmi +++ a/include/linux/sysctl.h @@ -151,6 +151,7 @@ enum KERN_COMPAT_LOG=73, /* int: print compat layer messages */ KERN_MAX_LOCK_DEPTH=74, KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */ + KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */ }; diff -puN kernel/panic.c~x86_64-mm-allow-users-to-force-a-panic-on-nmi kernel/panic.c --- a/kernel/panic.c~x86_64-mm-allow-users-to-force-a-panic-on-nmi +++ a/kernel/panic.c @@ -20,6 +20,7 @@ #include int panic_on_oops; +int panic_on_unrecovered_nmi; int tainted; static int pause_on_oops; static int pause_on_oops_flag; diff -puN kernel/sysctl.c~x86_64-mm-allow-users-to-force-a-panic-on-nmi kernel/sysctl.c --- a/kernel/sysctl.c~x86_64-mm-allow-users-to-force-a-panic-on-nmi +++ a/kernel/sysctl.c @@ -642,6 +642,14 @@ static ctl_table kern_table[] = { #endif #if defined(CONFIG_X86) { + .ctl_name = KERN_PANIC_ON_NMI, + .procname = "panic_on_unrecovered_nmi", + .data = &panic_on_unrecovered_nmi, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { .ctl_name = KERN_BOOTLOADER_TYPE, .procname = "bootloader_type", .data = &bootloader_type, _