aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/nmi.c
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2007-07-22 05:12:32 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-22 14:03:37 -0400
commit8f4e956b313dcccbc7be6f10808952345e3b638c (patch)
treecc8c93fa1faf5e0b608e3a21330a32bd82fe6f47 /arch/x86_64/kernel/nmi.c
parent19d36ccdc34f5ed444f8a6af0cbfdb6790eb1177 (diff)
x86: Stop MCEs and NMIs during code patching
When a machine check or NMI occurs while multiple byte code is patched the CPU could theoretically see an inconsistent instruction and crash. Prevent this by temporarily disabling MCEs and returning early in the NMI handler. Based on discussion with Mathieu Desnoyers. Cc: Mathieu Desnoyers <compudj@krystal.dyndns.org> Cc: Jeremy Fitzhardinge <jeremy@goop.org> Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/x86_64/kernel/nmi.c')
-rw-r--r--arch/x86_64/kernel/nmi.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index edbbc59b7523..cb8ee9d02f86 100644
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -384,11 +384,14 @@ int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason)
384 return rc; 384 return rc;
385} 385}
386 386
387static unsigned ignore_nmis;
388
387asmlinkage __kprobes void do_nmi(struct pt_regs * regs, long error_code) 389asmlinkage __kprobes void do_nmi(struct pt_regs * regs, long error_code)
388{ 390{
389 nmi_enter(); 391 nmi_enter();
390 add_pda(__nmi_count,1); 392 add_pda(__nmi_count,1);
391 default_do_nmi(regs); 393 if (!ignore_nmis)
394 default_do_nmi(regs);
392 nmi_exit(); 395 nmi_exit();
393} 396}
394 397
@@ -401,6 +404,18 @@ int do_nmi_callback(struct pt_regs * regs, int cpu)
401 return 0; 404 return 0;
402} 405}
403 406
407void stop_nmi(void)
408{
409 acpi_nmi_disable();
410 ignore_nmis++;
411}
412
413void restart_nmi(void)
414{
415 ignore_nmis--;
416 acpi_nmi_enable();
417}
418
404#ifdef CONFIG_SYSCTL 419#ifdef CONFIG_SYSCTL
405 420
406static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu) 421static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu)