aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/x86_64/boot-options.txt5
-rw-r--r--arch/x86_64/kernel/mce.c16
2 files changed, 17 insertions, 4 deletions
diff --git a/Documentation/x86_64/boot-options.txt b/Documentation/x86_64/boot-options.txt
index 476c0c22fbb7..678e8f192db2 100644
--- a/Documentation/x86_64/boot-options.txt
+++ b/Documentation/x86_64/boot-options.txt
@@ -6,6 +6,11 @@ only the AMD64 specific ones are listed here.
6Machine check 6Machine check
7 7
8 mce=off disable machine check 8 mce=off disable machine check
9 mce=bootlog Enable logging of machine checks left over from booting.
10 Disabled by default because some BIOS leave bogus ones.
11 If your BIOS doesn't do that it's a good idea to enable though
12 to make sure you log even machine check events that result
13 in a reboot.
9 14
10 nomce (for compatibility with i386): same as mce=off 15 nomce (for compatibility with i386): same as mce=off
11 16
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 };
36static unsigned long console_logged; 36static unsigned long console_logged;
37static int notify_user; 37static int notify_user;
38static int rip_msr; 38static int rip_msr;
39static 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. */
480static int __init mcheck_enable(char *str) 484static 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;