diff options
author | Andi Kleen <ak@muc.de> | 2005-08-07 12:42:07 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-08-07 13:00:37 -0400 |
commit | d5172f263f76ca6d588f533c0989b22521fcbac2 (patch) | |
tree | a4a017f686f101b5817f6c1abbc84518335d497e /arch/x86_64 | |
parent | cf7bee5a0bf270a4eace0be39329d6ac0136cc47 (diff) |
[PATCH] x86_64: ignore machine checks from boot time
Don't log machine check events left over from boot. Too many BIOSes leave
bogus events in there.
This unfortunately also makes it impossible to log events that caused a
reboot. For people with non broken BIOS there is mce=bootlog
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/x86_64')
-rw-r--r-- | arch/x86_64/kernel/mce.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c index 3b267c91bb0c..8aa56736cde3 100644 --- a/arch/x86_64/kernel/mce.c +++ b/arch/x86_64/kernel/mce.c | |||
@@ -36,6 +36,7 @@ static unsigned long bank[NR_BANKS] = { [0 ... NR_BANKS-1] = ~0UL }; | |||
36 | static unsigned long console_logged; | 36 | static unsigned long console_logged; |
37 | static int notify_user; | 37 | static int notify_user; |
38 | static int rip_msr; | 38 | static int rip_msr; |
39 | static int mce_bootlog; | ||
39 | 40 | ||
40 | /* | 41 | /* |
41 | * Lockless MCE logging infrastructure. | 42 | * Lockless MCE logging infrastructure. |
@@ -197,10 +198,11 @@ void do_machine_check(struct pt_regs * regs, long error_code) | |||
197 | rdmsrl(MSR_IA32_MC0_ADDR + i*4, m.addr); | 198 | rdmsrl(MSR_IA32_MC0_ADDR + i*4, m.addr); |
198 | 199 | ||
199 | mce_get_rip(&m, regs); | 200 | mce_get_rip(&m, regs); |
200 | if (error_code != -1) | 201 | if (error_code >= 0) |
201 | rdtscll(m.tsc); | 202 | rdtscll(m.tsc); |
202 | wrmsrl(MSR_IA32_MC0_STATUS + i*4, 0); | 203 | wrmsrl(MSR_IA32_MC0_STATUS + i*4, 0); |
203 | mce_log(&m); | 204 | if (error_code != -2) |
205 | mce_log(&m); | ||
204 | 206 | ||
205 | /* Did this bank cause the exception? */ | 207 | /* Did this bank cause the exception? */ |
206 | /* Assume that the bank with uncorrectable errors did it, | 208 | /* Assume that the bank with uncorrectable errors did it, |
@@ -315,7 +317,7 @@ static void mce_init(void *dummy) | |||
315 | 317 | ||
316 | /* Log the machine checks left over from the previous reset. | 318 | /* Log the machine checks left over from the previous reset. |
317 | This also clears all registers */ | 319 | This also clears all registers */ |
318 | do_machine_check(NULL, -1); | 320 | do_machine_check(NULL, mce_bootlog ? -1 : -2); |
319 | 321 | ||
320 | set_in_cr4(X86_CR4_MCE); | 322 | set_in_cr4(X86_CR4_MCE); |
321 | 323 | ||
@@ -476,11 +478,17 @@ static int __init mcheck_disable(char *str) | |||
476 | } | 478 | } |
477 | 479 | ||
478 | /* mce=off disables machine check. Note you can reenable it later | 480 | /* mce=off disables machine check. Note you can reenable it later |
479 | using sysfs */ | 481 | using sysfs. |
482 | mce=bootlog Log MCEs from before booting. Disabled by default to work | ||
483 | around buggy BIOS that leave bogus MCEs. */ | ||
480 | static int __init mcheck_enable(char *str) | 484 | static int __init mcheck_enable(char *str) |
481 | { | 485 | { |
486 | if (*str == '=') | ||
487 | str++; | ||
482 | if (!strcmp(str, "off")) | 488 | if (!strcmp(str, "off")) |
483 | mce_dont_init = 1; | 489 | mce_dont_init = 1; |
490 | else if (!strcmp(str, "bootlog")) | ||
491 | mce_bootlog = 1; | ||
484 | else | 492 | else |
485 | printk("mce= argument %s ignored. Please use /sys", str); | 493 | printk("mce= argument %s ignored. Please use /sys", str); |
486 | return 0; | 494 | return 0; |