aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/mce.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/kernel/mce.c')
-rw-r--r--arch/x86_64/kernel/mce.c42
1 files changed, 29 insertions, 13 deletions
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c
index 8aa56736cde3..969365c0771b 100644
--- a/arch/x86_64/kernel/mce.c
+++ b/arch/x86_64/kernel/mce.c
@@ -17,6 +17,7 @@
17#include <linux/fs.h> 17#include <linux/fs.h>
18#include <linux/cpu.h> 18#include <linux/cpu.h>
19#include <linux/percpu.h> 19#include <linux/percpu.h>
20#include <linux/ctype.h>
20#include <asm/processor.h> 21#include <asm/processor.h>
21#include <asm/msr.h> 22#include <asm/msr.h>
22#include <asm/mce.h> 23#include <asm/mce.h>
@@ -56,15 +57,19 @@ void mce_log(struct mce *mce)
56 smp_wmb(); 57 smp_wmb();
57 for (;;) { 58 for (;;) {
58 entry = rcu_dereference(mcelog.next); 59 entry = rcu_dereference(mcelog.next);
59 /* When the buffer fills up discard new entries. Assume 60 for (;;) {
60 that the earlier errors are the more interesting. */ 61 /* When the buffer fills up discard new entries. Assume
61 if (entry >= MCE_LOG_LEN) { 62 that the earlier errors are the more interesting. */
62 set_bit(MCE_OVERFLOW, &mcelog.flags); 63 if (entry >= MCE_LOG_LEN) {
63 return; 64 set_bit(MCE_OVERFLOW, &mcelog.flags);
65 return;
66 }
67 /* Old left over entry. Skip. */
68 if (mcelog.entry[entry].finished) {
69 entry++;
70 continue;
71 }
64 } 72 }
65 /* Old left over entry. Skip. */
66 if (mcelog.entry[entry].finished)
67 continue;
68 smp_rmb(); 73 smp_rmb();
69 next = entry + 1; 74 next = entry + 1;
70 if (cmpxchg(&mcelog.next, entry, next) == entry) 75 if (cmpxchg(&mcelog.next, entry, next) == entry)
@@ -404,9 +409,15 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, loff
404 } 409 }
405 410
406 err = 0; 411 err = 0;
407 for (i = 0; i < next; i++) { 412 for (i = 0; i < next; i++) {
408 if (!mcelog.entry[i].finished) 413 unsigned long start = jiffies;
409 continue; 414 while (!mcelog.entry[i].finished) {
415 if (!time_before(jiffies, start + 2)) {
416 memset(mcelog.entry + i,0, sizeof(struct mce));
417 continue;
418 }
419 cpu_relax();
420 }
410 smp_rmb(); 421 smp_rmb();
411 err |= copy_to_user(buf, mcelog.entry + i, sizeof(struct mce)); 422 err |= copy_to_user(buf, mcelog.entry + i, sizeof(struct mce));
412 buf += sizeof(struct mce); 423 buf += sizeof(struct mce);
@@ -479,6 +490,7 @@ static int __init mcheck_disable(char *str)
479 490
480/* mce=off disables machine check. Note you can reenable it later 491/* mce=off disables machine check. Note you can reenable it later
481 using sysfs. 492 using sysfs.
493 mce=TOLERANCELEVEL (number, see above)
482 mce=bootlog Log MCEs from before booting. Disabled by default to work 494 mce=bootlog Log MCEs from before booting. Disabled by default to work
483 around buggy BIOS that leave bogus MCEs. */ 495 around buggy BIOS that leave bogus MCEs. */
484static int __init mcheck_enable(char *str) 496static int __init mcheck_enable(char *str)
@@ -489,6 +501,8 @@ static int __init mcheck_enable(char *str)
489 mce_dont_init = 1; 501 mce_dont_init = 1;
490 else if (!strcmp(str, "bootlog")) 502 else if (!strcmp(str, "bootlog"))
491 mce_bootlog = 1; 503 mce_bootlog = 1;
504 else if (isdigit(str[0]))
505 get_option(&str, &tolerant);
492 else 506 else
493 printk("mce= argument %s ignored. Please use /sys", str); 507 printk("mce= argument %s ignored. Please use /sys", str);
494 return 0; 508 return 0;
@@ -501,10 +515,12 @@ __setup("mce", mcheck_enable);
501 * Sysfs support 515 * Sysfs support
502 */ 516 */
503 517
504/* On resume clear all MCE state. Don't want to see leftovers from the BIOS. */ 518/* On resume clear all MCE state. Don't want to see leftovers from the BIOS.
519 Only one CPU is active at this time, the others get readded later using
520 CPU hotplug. */
505static int mce_resume(struct sys_device *dev) 521static int mce_resume(struct sys_device *dev)
506{ 522{
507 on_each_cpu(mce_init, NULL, 1, 1); 523 mce_init(NULL);
508 return 0; 524 return 0;
509} 525}
510 526