diff options
author | Andi Kleen <ak@suse.de> | 2007-07-22 05:12:32 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-22 14:03:37 -0400 |
commit | 8f4e956b313dcccbc7be6f10808952345e3b638c (patch) | |
tree | cc8c93fa1faf5e0b608e3a21330a32bd82fe6f47 /arch/i386/kernel/traps.c | |
parent | 19d36ccdc34f5ed444f8a6af0cbfdb6790eb1177 (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/i386/kernel/traps.c')
-rw-r--r-- | arch/i386/kernel/traps.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 438949da3b63..cfffe3dd9e83 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
@@ -775,6 +775,8 @@ static __kprobes void default_do_nmi(struct pt_regs * regs) | |||
775 | reassert_nmi(); | 775 | reassert_nmi(); |
776 | } | 776 | } |
777 | 777 | ||
778 | static int ignore_nmis; | ||
779 | |||
778 | fastcall __kprobes void do_nmi(struct pt_regs * regs, long error_code) | 780 | fastcall __kprobes void do_nmi(struct pt_regs * regs, long error_code) |
779 | { | 781 | { |
780 | int cpu; | 782 | int cpu; |
@@ -785,11 +787,24 @@ fastcall __kprobes void do_nmi(struct pt_regs * regs, long error_code) | |||
785 | 787 | ||
786 | ++nmi_count(cpu); | 788 | ++nmi_count(cpu); |
787 | 789 | ||
788 | default_do_nmi(regs); | 790 | if (!ignore_nmis) |
791 | default_do_nmi(regs); | ||
789 | 792 | ||
790 | nmi_exit(); | 793 | nmi_exit(); |
791 | } | 794 | } |
792 | 795 | ||
796 | void stop_nmi(void) | ||
797 | { | ||
798 | acpi_nmi_disable(); | ||
799 | ignore_nmis++; | ||
800 | } | ||
801 | |||
802 | void restart_nmi(void) | ||
803 | { | ||
804 | ignore_nmis--; | ||
805 | acpi_nmi_enable(); | ||
806 | } | ||
807 | |||
793 | #ifdef CONFIG_KPROBES | 808 | #ifdef CONFIG_KPROBES |
794 | fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code) | 809 | fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code) |
795 | { | 810 | { |