2 * Non Fatal Machine Check Exception Reporting
4 * (C) Copyright 2002 Dave Jones. <davej@redhat.com>
6 * This file contains routines to check for non-fatal MCEs every 15s
9 #include <linux/interrupt.h>
10 #include <linux/workqueue.h>
11 #include <linux/jiffies.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/types.h>
15 #include <linux/init.h>
16 #include <linux/smp.h>
18 #include <asm/processor.h>
19 #include <asm/system.h>
25 #define MCE_RATE (15*HZ) /* timer rate is 15s */
27 static void mce_checkregs(void *info
)
32 for (i
= firstbank
; i
< nr_mce_banks
; i
++) {
33 rdmsr(MSR_IA32_MC0_STATUS
+i
*4, low
, high
);
35 if (!(high
& (1<<31)))
38 printk(KERN_INFO
"MCE: The hardware reports a non fatal, "
39 "correctable incident occurred on CPU %d.\n",
42 printk(KERN_INFO
"Bank %d: %08x%08x\n", i
, high
, low
);
45 * Scrub the error so we don't pick it up in MCE_RATE
48 wrmsr(MSR_IA32_MC0_STATUS
+i
*4, 0UL, 0UL);
52 add_taint(TAINT_MACHINE_CHECK
);
56 static void mce_work_fn(struct work_struct
*work
);
57 static DECLARE_DELAYED_WORK(mce_work
, mce_work_fn
);
59 static void mce_work_fn(struct work_struct
*work
)
61 on_each_cpu(mce_checkregs
, NULL
, 1);
62 schedule_delayed_work(&mce_work
, round_jiffies_relative(MCE_RATE
));
65 static int __init
init_nonfatal_mce_checker(void)
67 struct cpuinfo_x86
*c
= &boot_cpu_data
;
69 /* Check for MCE support */
70 if (!cpu_has(c
, X86_FEATURE_MCE
))
73 /* Check for PPro style MCA */
74 if (!cpu_has(c
, X86_FEATURE_MCA
))
77 /* Some Athlons misbehave when we frob bank 0 */
78 if (boot_cpu_data
.x86_vendor
== X86_VENDOR_AMD
&&
79 boot_cpu_data
.x86
== 6)
85 * Check for non-fatal errors every MCE_RATE s
87 schedule_delayed_work(&mce_work
, round_jiffies_relative(MCE_RATE
));
88 printk(KERN_INFO
"Machine check exception polling timer started.\n");
92 module_init(init_nonfatal_mce_checker
);
94 MODULE_LICENSE("GPL");