mcelog.entry[entry].finished = 1;
wmb();
+ mce->finished = 1;
set_bit(0, ¬ify_user);
}
"and contact your hardware vendor\n");
}
-static void mce_panic(char *msg, struct mce *backup, u64 start)
+static void mce_panic(char *msg, struct mce *final)
{
int i;
bust_spinlocks(1);
console_verbose();
+ /* First print corrected ones that are still unlogged */
for (i = 0; i < MCE_LOG_LEN; i++) {
- u64 tsc = mcelog.entry[i].tsc;
-
- if ((s64)(tsc - start) < 0)
+ struct mce *m = &mcelog.entry[i];
+ if ((m->status & MCI_STATUS_VAL) &&
+ !(m->status & MCI_STATUS_UC))
+ print_mce(m);
+ }
+ /* Now print uncorrected but with the final one last */
+ for (i = 0; i < MCE_LOG_LEN; i++) {
+ struct mce *m = &mcelog.entry[i];
+ if (!(m->status & MCI_STATUS_VAL))
continue;
- print_mce(&mcelog.entry[i]);
- if (backup && mcelog.entry[i].tsc == backup->tsc)
- backup = NULL;
+ if (!final || memcmp(m, final, sizeof(struct mce)))
+ print_mce(m);
}
- if (backup)
- print_mce(backup);
+ if (final)
+ print_mce(final);
panic(msg);
}
{
struct mce m, panicm;
int panicm_found = 0;
- u64 mcestart = 0;
int i;
/*
* If no_way_out gets set, there is no safe way to recover from this
if (!(m.mcgstatus & MCG_STATUS_RIPV))
no_way_out = 1;
- rdtscll(mcestart);
barrier();
for (i = 0; i < banks; i++) {
* has not set tolerant to an insane level, give up and die.
*/
if (no_way_out && tolerant < 3)
- mce_panic("Machine check", &panicm, mcestart);
+ mce_panic("Machine check", &panicm);
/*
* If the error seems to be unrecoverable, something should be
if (user_space) {
force_sig(SIGBUS, current);
} else if (panic_on_oops || tolerant < 2) {
- mce_panic("Uncorrected machine check",
- &panicm, mcestart);
+ mce_panic("Uncorrected machine check", &panicm);
}
}