diff options
author | Andi Kleen <andi@firstfloor.org> | 2009-02-12 07:39:27 -0500 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2009-02-17 18:32:38 -0500 |
commit | 123aa76ec0cab5d4881cd8509faed43231e68801 (patch) | |
tree | 9b15b722f93adf886fc4dcbacea062325b2ea365 /arch | |
parent | 973a2dd1d50a11d380086601f14e59116f93e8c5 (diff) |
x86, mce: don't disable machine checks during code patching
Impact: low priority bug fix
This removes part of a a patch I added myself some time ago. After some
consideration the patch was a bad idea. In particular it stopped machine check
exceptions during code patching.
To quote the comment:
* MCEs only happen when something got corrupted and in this
* case we must do something about the corruption.
* Ignoring it is worse than a unlikely patching race.
* Also machine checks tend to be broadcast and if one CPU
* goes into machine check the others follow quickly, so we don't
* expect a machine check to cause undue problems during to code
* patching.
So undo the machine check related parts of
8f4e956b313dcccbc7be6f10808952345e3b638c NMIs are still disabled.
This only removes code, the only additions are a new comment.
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/mce.h | 2 | ||||
-rw-r--r-- | arch/x86/kernel/alternative.c | 17 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce_32.c | 14 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce_64.c | 14 |
4 files changed, 11 insertions, 36 deletions
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index 32c6e17b960..5522273a3ad 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h | |||
@@ -120,8 +120,6 @@ extern void mcheck_init(struct cpuinfo_x86 *c); | |||
120 | #else | 120 | #else |
121 | #define mcheck_init(c) do { } while (0) | 121 | #define mcheck_init(c) do { } while (0) |
122 | #endif | 122 | #endif |
123 | extern void stop_mce(void); | ||
124 | extern void restart_mce(void); | ||
125 | 123 | ||
126 | #endif /* __KERNEL__ */ | 124 | #endif /* __KERNEL__ */ |
127 | #endif /* _ASM_X86_MCE_H */ | 125 | #endif /* _ASM_X86_MCE_H */ |
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index a84ac7b570e..5b8394a3a6b 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c | |||
@@ -414,9 +414,17 @@ void __init alternative_instructions(void) | |||
414 | that might execute the to be patched code. | 414 | that might execute the to be patched code. |
415 | Other CPUs are not running. */ | 415 | Other CPUs are not running. */ |
416 | stop_nmi(); | 416 | stop_nmi(); |
417 | #ifdef CONFIG_X86_MCE | 417 | |
418 | stop_mce(); | 418 | /* |
419 | #endif | 419 | * Don't stop machine check exceptions while patching. |
420 | * MCEs only happen when something got corrupted and in this | ||
421 | * case we must do something about the corruption. | ||
422 | * Ignoring it is worse than a unlikely patching race. | ||
423 | * Also machine checks tend to be broadcast and if one CPU | ||
424 | * goes into machine check the others follow quickly, so we don't | ||
425 | * expect a machine check to cause undue problems during to code | ||
426 | * patching. | ||
427 | */ | ||
420 | 428 | ||
421 | apply_alternatives(__alt_instructions, __alt_instructions_end); | 429 | apply_alternatives(__alt_instructions, __alt_instructions_end); |
422 | 430 | ||
@@ -456,9 +464,6 @@ void __init alternative_instructions(void) | |||
456 | (unsigned long)__smp_locks_end); | 464 | (unsigned long)__smp_locks_end); |
457 | 465 | ||
458 | restart_nmi(); | 466 | restart_nmi(); |
459 | #ifdef CONFIG_X86_MCE | ||
460 | restart_mce(); | ||
461 | #endif | ||
462 | } | 467 | } |
463 | 468 | ||
464 | /** | 469 | /** |
diff --git a/arch/x86/kernel/cpu/mcheck/mce_32.c b/arch/x86/kernel/cpu/mcheck/mce_32.c index dfaebce3633..3552119b091 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_32.c +++ b/arch/x86/kernel/cpu/mcheck/mce_32.c | |||
@@ -60,20 +60,6 @@ void mcheck_init(struct cpuinfo_x86 *c) | |||
60 | } | 60 | } |
61 | } | 61 | } |
62 | 62 | ||
63 | static unsigned long old_cr4 __initdata; | ||
64 | |||
65 | void __init stop_mce(void) | ||
66 | { | ||
67 | old_cr4 = read_cr4(); | ||
68 | clear_in_cr4(X86_CR4_MCE); | ||
69 | } | ||
70 | |||
71 | void __init restart_mce(void) | ||
72 | { | ||
73 | if (old_cr4 & X86_CR4_MCE) | ||
74 | set_in_cr4(X86_CR4_MCE); | ||
75 | } | ||
76 | |||
77 | static int __init mcheck_disable(char *str) | 63 | static int __init mcheck_disable(char *str) |
78 | { | 64 | { |
79 | mce_disabled = 1; | 65 | mce_disabled = 1; |
diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index 5ed80991ab9..25ccdbec86e 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c | |||
@@ -680,20 +680,6 @@ static struct miscdevice mce_log_device = { | |||
680 | &mce_chrdev_ops, | 680 | &mce_chrdev_ops, |
681 | }; | 681 | }; |
682 | 682 | ||
683 | static unsigned long old_cr4 __initdata; | ||
684 | |||
685 | void __init stop_mce(void) | ||
686 | { | ||
687 | old_cr4 = read_cr4(); | ||
688 | clear_in_cr4(X86_CR4_MCE); | ||
689 | } | ||
690 | |||
691 | void __init restart_mce(void) | ||
692 | { | ||
693 | if (old_cr4 & X86_CR4_MCE) | ||
694 | set_in_cr4(X86_CR4_MCE); | ||
695 | } | ||
696 | |||
697 | /* | 683 | /* |
698 | * Old style boot options parsing. Only for compatibility. | 684 | * Old style boot options parsing. Only for compatibility. |
699 | */ | 685 | */ |