static bool f15h_mc2_mce(u16 ec, u8 xec) { bool ret = true; if (TLB_ERROR(ec)) { if (xec == 0x0) pr_cont("Data parity TLB read error.\n"); else if (xec == 0x1) pr_cont("Poison data provided for TLB fill.\n"); else ret = false; } else if (BUS_ERROR(ec)) { if (xec > 2) ret = false; pr_cont("Error during attempted NB data read.\n"); } else if (MEM_ERROR(ec)) { switch (xec) { case 0x4 ... 0xc: pr_cont("%s.\n", f15h_mc2_mce_desc[xec - 0x4]); break; case 0x10 ... 0x14: pr_cont("%s.\n", f15h_mc2_mce_desc[xec - 0x7]); break; default: ret = false; } } else if (INT_ERROR(ec)) {
static bool k8_mc2_mce(u16 ec, u8 xec) { bool ret = true; if (xec == 0x1) pr_cont(" in the write data buffers.\n"); else if (xec == 0x3) pr_cont(" in the victim data buffers.\n"); else if (xec == 0x2 && MEM_ERROR(ec)) pr_cont(": %s error in the L2 cache tags.\n", R4_MSG(ec)); else if (xec == 0x0) { if (TLB_ERROR(ec)) pr_cont(": %s error in a Page Descriptor Cache or " "Guest TLB.\n", TT_MSG(ec)); else if (BUS_ERROR(ec)) pr_cont(": %s/ECC error in data read from NB: %s.\n", R4_MSG(ec), PP_MSG(ec)); else if (MEM_ERROR(ec)) { u8 r4 = R4(ec); if (r4 >= 0x7) pr_cont(": %s error during data copyback.\n", R4_MSG(ec)); else if (r4 <= 0x1) pr_cont(": %s parity/ECC error during data " "access from L2.\n", R4_MSG(ec)); else ret = false; } else ret = false; } else ret = false; return ret; }
static void decode_mc1_mce(struct mce *m) { u16 ec = EC(m->status); u8 xec = XEC(m->status, xec_mask); pr_emerg(HW_ERR "MC1 Error: "); if (TLB_ERROR(ec)) pr_cont("%s TLB %s.\n", LL_MSG(ec), (xec ? "multimatch" : "parity error")); else if (BUS_ERROR(ec)) { bool k8 = (boot_cpu_data.x86 == 0xf && (m->status & BIT_64(58))); pr_cont("during %s.\n", (k8 ? "system linefill" : "NB data read")); } else if (INT_ERROR(ec)) { if (xec <= 0x3f) pr_cont("Hardware Assert.\n"); else goto wrong_mc1_mce; } else if (fam_ops->mc1_mce(ec, xec)) ; else goto wrong_mc1_mce; return; wrong_mc1_mce: pr_emerg(HW_ERR "Corrupted MC1 MCE info?\n"); }
static void decode_mc4_mce(struct mce *m) { struct cpuinfo_x86 *c = &boot_cpu_data; int node_id = amd_get_nb_id(m->extcpu); u16 ec = EC(m->status); u8 xec = XEC(m->status, 0x1f); u8 offset = 0; pr_emerg(HW_ERR "MC4 Error (node %d): ", node_id); switch (xec) { case 0x0 ... 0xe: /* special handling for DRAM ECCs */ if (xec == 0x0 || xec == 0x8) { /* no ECCs on F11h */ if (c->x86 == 0x11) goto wrong_mc4_mce; pr_cont("%s.\n", mc4_mce_desc[xec]); if (nb_bus_decoder) nb_bus_decoder(node_id, m); return; } break; case 0xf: if (TLB_ERROR(ec)) pr_cont("GART Table Walk data error.\n"); else if (BUS_ERROR(ec)) pr_cont("DMA Exclusion Vector Table Walk error.\n"); else goto wrong_mc4_mce; return; case 0x19: if (boot_cpu_data.x86 == 0x15) pr_cont("Compute Unit Data Error.\n"); else goto wrong_mc4_mce; return; case 0x1c ... 0x1f: offset = 13; break; default: goto wrong_mc4_mce; } pr_cont("%s.\n", mc4_mce_desc[xec - offset]); return; wrong_mc4_mce: pr_emerg(HW_ERR "Corrupted MC4 MCE info?\n"); }
static bool f10h_nb_mce(u16 ec, u8 xec) { bool ret = true; u8 offset = 0; if (k8_nb_mce(ec, xec)) return true; switch(xec) { case 0xa ... 0xc: offset = 10; break; case 0xe: offset = 11; break; case 0xf: if (TLB_ERROR(ec)) pr_cont("GART Table Walk data error.\n"); else if (BUS_ERROR(ec)) pr_cont("DMA Exclusion Vector Table Walk error.\n"); else ret = false; goto out; break; case 0x19: if (boot_cpu_data.x86 == 0x15) pr_cont("Compute Unit Data Error.\n"); else ret = false; goto out; break; case 0x1c ... 0x1f: offset = 24; break; default: ret = false; goto out; break; } pr_cont("%s.\n", f10h_nb_mce_desc[xec - offset]); out: return ret; }
static void amd_decode_ic_mce(struct mce *m) { u16 ec = EC(m->status); u8 xec = XEC(m->status, xec_mask); pr_emerg(HW_ERR "Instruction Cache Error: "); if (TLB_ERROR(ec)) pr_cont("%s TLB %s.\n", LL_MSG(ec), (xec ? "multimatch" : "parity error")); else if (BUS_ERROR(ec)) { bool k8 = (boot_cpu_data.x86 == 0xf && (m->status & BIT_64(58))); pr_cont("during %s.\n", (k8 ? "system linefill" : "NB data read")); } else if (fam_ops->ic_mce(ec, xec)) ; else pr_emerg(HW_ERR "Corrupted IC MCE info?\n"); }
static void decode_mc0_mce(struct mce *m) { u16 ec = EC(m->status); u8 xec = XEC(m->status, xec_mask); pr_emerg(HW_ERR "MC0 Error: "); /* TLB error signatures are the same across families */ if (TLB_ERROR(ec)) { if (TT(ec) == TT_DATA) { pr_cont("%s TLB %s.\n", LL_MSG(ec), ((xec == 2) ? "locked miss" : (xec ? "multimatch" : "parity"))); return; } } else if (fam_ops->mc0_mce(ec, xec)) ; else pr_emerg(HW_ERR "Corrupted MC0 MCE info?\n"); }
static void amd_decode_dc_mce(struct mce *m) { u16 ec = EC(m->status); u8 xec = XEC(m->status, xec_mask); pr_emerg(HW_ERR "Data Cache Error: "); if (TLB_ERROR(ec)) { if (TT(ec) == TT_DATA) { pr_cont("%s TLB %s.\n", LL_MSG(ec), ((xec == 2) ? "locked miss" : (xec ? "multimatch" : "parity"))); return; } } else if (fam_ops->dc_mce(ec, xec)) ; else pr_emerg(HW_ERR "Corrupted DC MCE info?\n"); }
static void decode_mc2_mce(struct mce *m) { u16 ec = EC(m->status); u8 xec = XEC(m->status, xec_mask); pr_emerg(HW_ERR "MC2 Error"); if (xec == 0x1) pr_cont(" in the write data buffers.\n"); else if (xec == 0x3) pr_cont(" in the victim data buffers.\n"); else if (xec == 0x2 && MEM_ERROR(ec)) pr_cont(": %s error in the L2 cache tags.\n", R4_MSG(ec)); else if (xec == 0x0) { if (TLB_ERROR(ec)) pr_cont(": %s error in a Page Descriptor Cache or " "Guest TLB.\n", TT_MSG(ec)); else if (BUS_ERROR(ec)) pr_cont(": %s/ECC error in data read from NB: %s.\n", R4_MSG(ec), PP_MSG(ec)); else if (MEM_ERROR(ec)) { u8 r4 = R4(ec); if (r4 >= 0x7) pr_cont(": %s error during data copyback.\n", R4_MSG(ec)); else if (r4 <= 0x1) pr_cont(": %s parity/ECC error during data " "access from L2.\n", R4_MSG(ec)); else goto wrong_mc2_mce; } else goto wrong_mc2_mce; } else goto wrong_mc2_mce; return; wrong_mc2_mce: pr_emerg(HW_ERR "Corrupted MC2 MCE info?\n"); }
static void decode_f15_mc2_mce(struct mce *m) { u16 ec = EC(m->status); u8 xec = XEC(m->status, xec_mask); pr_emerg(HW_ERR "MC2 Error: "); if (TLB_ERROR(ec)) { if (xec == 0x0) pr_cont("Data parity TLB read error.\n"); else if (xec == 0x1) pr_cont("Poison data provided for TLB fill.\n"); else goto wrong_f15_mc2_mce; } else if (BUS_ERROR(ec)) { if (xec > 2) goto wrong_f15_mc2_mce; pr_cont("Error during attempted NB data read.\n"); } else if (MEM_ERROR(ec)) { switch (xec) { case 0x4 ... 0xc: pr_cont("%s.\n", f15h_mc2_mce_desc[xec - 0x4]); break; case 0x10 ... 0x14: pr_cont("%s.\n", f15h_mc2_mce_desc[xec - 0x7]); break; default: goto wrong_f15_mc2_mce; } } return; wrong_f15_mc2_mce: pr_emerg(HW_ERR "Corrupted MC2 MCE info?\n"); }