diff options
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index b1598a9436d0..15ba9c972d7a 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
@@ -85,18 +85,26 @@ static DECLARE_WAIT_QUEUE_HEAD(mce_wait); | |||
85 | static DEFINE_PER_CPU(struct mce, mces_seen); | 85 | static DEFINE_PER_CPU(struct mce, mces_seen); |
86 | static int cpu_missing; | 86 | static int cpu_missing; |
87 | 87 | ||
88 | static void default_decode_mce(struct mce *m) | 88 | /* |
89 | * CPU/chipset specific EDAC code can register a notifier call here to print | ||
90 | * MCE errors in a human-readable form. | ||
91 | */ | ||
92 | ATOMIC_NOTIFIER_HEAD(x86_mce_decoder_chain); | ||
93 | EXPORT_SYMBOL_GPL(x86_mce_decoder_chain); | ||
94 | |||
95 | static int default_decode_mce(struct notifier_block *nb, unsigned long val, | ||
96 | void *data) | ||
89 | { | 97 | { |
90 | pr_emerg("No human readable MCE decoding support on this CPU type.\n"); | 98 | pr_emerg("No human readable MCE decoding support on this CPU type.\n"); |
91 | pr_emerg("Run the message through 'mcelog --ascii' to decode.\n"); | 99 | pr_emerg("Run the message through 'mcelog --ascii' to decode.\n"); |
100 | |||
101 | return NOTIFY_STOP; | ||
92 | } | 102 | } |
93 | 103 | ||
94 | /* | 104 | static struct notifier_block mce_dec_nb = { |
95 | * CPU/chipset specific EDAC code can register a callback here to print | 105 | .notifier_call = default_decode_mce, |
96 | * MCE errors in a human-readable form: | 106 | .priority = -1, |
97 | */ | 107 | }; |
98 | void (*x86_mce_decode_callback)(struct mce *m) = default_decode_mce; | ||
99 | EXPORT_SYMBOL(x86_mce_decode_callback); | ||
100 | 108 | ||
101 | /* MCA banks polled by the period polling timer for corrected events */ | 109 | /* MCA banks polled by the period polling timer for corrected events */ |
102 | DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = { | 110 | DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = { |
@@ -204,9 +212,9 @@ static void print_mce(struct mce *m) | |||
204 | 212 | ||
205 | /* | 213 | /* |
206 | * Print out human-readable details about the MCE error, | 214 | * Print out human-readable details about the MCE error, |
207 | * (if the CPU has an implementation for that): | 215 | * (if the CPU has an implementation for that) |
208 | */ | 216 | */ |
209 | x86_mce_decode_callback(m); | 217 | atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, m); |
210 | } | 218 | } |
211 | 219 | ||
212 | static void print_mce_head(void) | 220 | static void print_mce_head(void) |
@@ -1420,6 +1428,9 @@ void __cpuinit mcheck_init(struct cpuinfo_x86 *c) | |||
1420 | mce_cpu_features(c); | 1428 | mce_cpu_features(c); |
1421 | mce_init_timer(); | 1429 | mce_init_timer(); |
1422 | INIT_WORK(&__get_cpu_var(mce_work), mce_process_work); | 1430 | INIT_WORK(&__get_cpu_var(mce_work), mce_process_work); |
1431 | |||
1432 | if (raw_smp_processor_id() == 0) | ||
1433 | atomic_notifier_chain_register(&x86_mce_decoder_chain, &mce_dec_nb); | ||
1423 | } | 1434 | } |
1424 | 1435 | ||
1425 | /* | 1436 | /* |