Commit d5172f26 authored by Andi Kleen's avatar Andi Kleen Committed by Linus Torvalds

[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: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent cf7bee5a
...@@ -6,6 +6,11 @@ only the AMD64 specific ones are listed here. ...@@ -6,6 +6,11 @@ only the AMD64 specific ones are listed here.
Machine check Machine check
mce=off disable machine check mce=off disable machine check
mce=bootlog Enable logging of machine checks left over from booting.
Disabled by default because some BIOS leave bogus ones.
If your BIOS doesn't do that it's a good idea to enable though
to make sure you log even machine check events that result
in a reboot.
nomce (for compatibility with i386): same as mce=off nomce (for compatibility with i386): same as mce=off
......
...@@ -36,6 +36,7 @@ static unsigned long bank[NR_BANKS] = { [0 ... NR_BANKS-1] = ~0UL }; ...@@ -36,6 +36,7 @@ static unsigned long bank[NR_BANKS] = { [0 ... NR_BANKS-1] = ~0UL };
static unsigned long console_logged; static unsigned long console_logged;
static int notify_user; static int notify_user;
static int rip_msr; static int rip_msr;
static int mce_bootlog;
/* /*
* Lockless MCE logging infrastructure. * Lockless MCE logging infrastructure.
...@@ -197,9 +198,10 @@ void do_machine_check(struct pt_regs * regs, long error_code) ...@@ -197,9 +198,10 @@ void do_machine_check(struct pt_regs * regs, long error_code)
rdmsrl(MSR_IA32_MC0_ADDR + i*4, m.addr); rdmsrl(MSR_IA32_MC0_ADDR + i*4, m.addr);
mce_get_rip(&m, regs); mce_get_rip(&m, regs);
if (error_code != -1) if (error_code >= 0)
rdtscll(m.tsc); rdtscll(m.tsc);
wrmsrl(MSR_IA32_MC0_STATUS + i*4, 0); wrmsrl(MSR_IA32_MC0_STATUS + i*4, 0);
if (error_code != -2)
mce_log(&m); mce_log(&m);
/* Did this bank cause the exception? */ /* Did this bank cause the exception? */
...@@ -315,7 +317,7 @@ static void mce_init(void *dummy) ...@@ -315,7 +317,7 @@ static void mce_init(void *dummy)
/* Log the machine checks left over from the previous reset. /* Log the machine checks left over from the previous reset.
This also clears all registers */ This also clears all registers */
do_machine_check(NULL, -1); do_machine_check(NULL, mce_bootlog ? -1 : -2);
set_in_cr4(X86_CR4_MCE); set_in_cr4(X86_CR4_MCE);
...@@ -476,11 +478,17 @@ static int __init mcheck_disable(char *str) ...@@ -476,11 +478,17 @@ static int __init mcheck_disable(char *str)
} }
/* mce=off disables machine check. Note you can reenable it later /* mce=off disables machine check. Note you can reenable it later
using sysfs */ using sysfs.
mce=bootlog Log MCEs from before booting. Disabled by default to work
around buggy BIOS that leave bogus MCEs. */
static int __init mcheck_enable(char *str) static int __init mcheck_enable(char *str)
{ {
if (*str == '=')
str++;
if (!strcmp(str, "off")) if (!strcmp(str, "off"))
mce_dont_init = 1; mce_dont_init = 1;
else if (!strcmp(str, "bootlog"))
mce_bootlog = 1;
else else
printk("mce= argument %s ignored. Please use /sys", str); printk("mce= argument %s ignored. Please use /sys", str);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment