aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/mce.h2
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c44
-rw-r--r--drivers/acpi/acpi_extlog.c2
-rw-r--r--drivers/edac/i7core_edac.c2
-rw-r--r--drivers/edac/mce_amd.c2
-rw-r--r--drivers/edac/sb_edac.c2
6 files changed, 7 insertions, 47 deletions
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index dfaa4de1dbb4..982dfc3679ad 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -140,7 +140,7 @@ struct mce_vendor_flags {
140extern struct mce_vendor_flags mce_flags; 140extern struct mce_vendor_flags mce_flags;
141 141
142extern struct mca_config mca_cfg; 142extern struct mca_config mca_cfg;
143extern void mce_register_decode_chain(struct notifier_block *nb, bool drain); 143extern void mce_register_decode_chain(struct notifier_block *nb);
144extern void mce_unregister_decode_chain(struct notifier_block *nb); 144extern void mce_unregister_decode_chain(struct notifier_block *nb);
145 145
146#include <linux/percpu.h> 146#include <linux/percpu.h>
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index 9568bb55bfe2..32b586ee006a 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -199,55 +199,15 @@ void mce_log(struct mce *mce)
199 set_bit(0, &mce_need_notify); 199 set_bit(0, &mce_need_notify);
200} 200}
201 201
202static void drain_mcelog_buffer(void)
203{
204 unsigned int next, i, prev = 0;
205
206 next = ACCESS_ONCE(mcelog.next);
207
208 do {
209 struct mce *m;
210
211 /* drain what was logged during boot */
212 for (i = prev; i < next; i++) {
213 unsigned long start = jiffies;
214 unsigned retries = 1;
215
216 m = &mcelog.entry[i];
217
218 while (!m->finished) {
219 if (time_after_eq(jiffies, start + 2*retries))
220 retries++;
221
222 cpu_relax();
223
224 if (!m->finished && retries >= 4) {
225 pr_err("skipping error being logged currently!\n");
226 break;
227 }
228 }
229 smp_rmb();
230 atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, m);
231 }
232
233 memset(mcelog.entry + prev, 0, (next - prev) * sizeof(*m));
234 prev = next;
235 next = cmpxchg(&mcelog.next, prev, 0);
236 } while (next != prev);
237}
238
239static struct notifier_block mce_srao_nb; 202static struct notifier_block mce_srao_nb;
240 203
241void mce_register_decode_chain(struct notifier_block *nb, bool drain) 204void mce_register_decode_chain(struct notifier_block *nb)
242{ 205{
243 /* Ensure SRAO notifier has the highest priority in the decode chain. */ 206 /* Ensure SRAO notifier has the highest priority in the decode chain. */
244 if (nb != &mce_srao_nb && nb->priority == INT_MAX) 207 if (nb != &mce_srao_nb && nb->priority == INT_MAX)
245 nb->priority -= 1; 208 nb->priority -= 1;
246 209
247 atomic_notifier_chain_register(&x86_mce_decoder_chain, nb); 210 atomic_notifier_chain_register(&x86_mce_decoder_chain, nb);
248
249 if (drain)
250 drain_mcelog_buffer();
251} 211}
252EXPORT_SYMBOL_GPL(mce_register_decode_chain); 212EXPORT_SYMBOL_GPL(mce_register_decode_chain);
253 213
@@ -2028,7 +1988,7 @@ __setup("mce", mcheck_enable);
2028int __init mcheck_init(void) 1988int __init mcheck_init(void)
2029{ 1989{
2030 mcheck_intel_therm_init(); 1990 mcheck_intel_therm_init();
2031 mce_register_decode_chain(&mce_srao_nb, false); 1991 mce_register_decode_chain(&mce_srao_nb);
2032 mcheck_vendor_init_severity(); 1992 mcheck_vendor_init_severity();
2033 1993
2034 INIT_WORK(&mce_work, mce_process_work); 1994 INIT_WORK(&mce_work, mce_process_work);
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
index 07e012e74c1b..b3842ffc19ba 100644
--- a/drivers/acpi/acpi_extlog.c
+++ b/drivers/acpi/acpi_extlog.c
@@ -286,7 +286,7 @@ static int __init extlog_init(void)
286 */ 286 */
287 old_edac_report_status = get_edac_report_status(); 287 old_edac_report_status = get_edac_report_status();
288 set_edac_report_status(EDAC_REPORTING_DISABLED); 288 set_edac_report_status(EDAC_REPORTING_DISABLED);
289 mce_register_decode_chain(&extlog_mce_dec, true); 289 mce_register_decode_chain(&extlog_mce_dec);
290 /* enable OS to be involved to take over management from BIOS */ 290 /* enable OS to be involved to take over management from BIOS */
291 ((struct extlog_l1_head *)extlog_l1_addr)->flags |= FLAG_OS_OPTIN; 291 ((struct extlog_l1_head *)extlog_l1_addr)->flags |= FLAG_OS_OPTIN;
292 292
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
index 13d77f4a892c..01087a38da22 100644
--- a/drivers/edac/i7core_edac.c
+++ b/drivers/edac/i7core_edac.c
@@ -2424,7 +2424,7 @@ static int __init i7core_init(void)
2424 pci_rc = pci_register_driver(&i7core_driver); 2424 pci_rc = pci_register_driver(&i7core_driver);
2425 2425
2426 if (pci_rc >= 0) { 2426 if (pci_rc >= 0) {
2427 mce_register_decode_chain(&i7_mce_dec, true); 2427 mce_register_decode_chain(&i7_mce_dec);
2428 return 0; 2428 return 0;
2429 } 2429 }
2430 2430
diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c
index aca31a237073..58586d59bf8e 100644
--- a/drivers/edac/mce_amd.c
+++ b/drivers/edac/mce_amd.c
@@ -895,7 +895,7 @@ static int __init mce_amd_init(void)
895 895
896 pr_info("MCE: In-kernel MCE decoding enabled.\n"); 896 pr_info("MCE: In-kernel MCE decoding enabled.\n");
897 897
898 mce_register_decode_chain(&amd_mce_dec_nb, true); 898 mce_register_decode_chain(&amd_mce_dec_nb);
899 899
900 return 0; 900 return 0;
901} 901}
diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c
index 5780e26c3e58..ca7831168298 100644
--- a/drivers/edac/sb_edac.c
+++ b/drivers/edac/sb_edac.c
@@ -2591,7 +2591,7 @@ static int __init sbridge_init(void)
2591 2591
2592 pci_rc = pci_register_driver(&sbridge_driver); 2592 pci_rc = pci_register_driver(&sbridge_driver);
2593 if (pci_rc >= 0) { 2593 if (pci_rc >= 0) {
2594 mce_register_decode_chain(&sbridge_mce_dec, true); 2594 mce_register_decode_chain(&sbridge_mce_dec);
2595 if (get_edac_report_status() == EDAC_REPORTING_DISABLED) 2595 if (get_edac_report_status() == EDAC_REPORTING_DISABLED)
2596 sbridge_printk(KERN_WARNING, "Loading driver, error reporting disabled.\n"); 2596 sbridge_printk(KERN_WARNING, "Loading driver, error reporting disabled.\n");
2597 return 0; 2597 return 0;