aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/edac_mce_amd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/edac/edac_mce_amd.c')
-rw-r--r--drivers/edac/edac_mce_amd.c57
1 files changed, 28 insertions, 29 deletions
diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c
index 444c2cc4472d..0ba92d65db43 100644
--- a/drivers/edac/edac_mce_amd.c
+++ b/drivers/edac/edac_mce_amd.c
@@ -2,7 +2,7 @@
2#include "edac_mce_amd.h" 2#include "edac_mce_amd.h"
3 3
4static bool report_gart_errors; 4static bool report_gart_errors;
5static void (*nb_bus_decoder)(int node_id, struct err_regs *regs, int ecc_type); 5static void (*nb_bus_decoder)(int node_id, struct err_regs *regs);
6 6
7void amd_report_gart_errors(bool v) 7void amd_report_gart_errors(bool v)
8{ 8{
@@ -10,13 +10,13 @@ void amd_report_gart_errors(bool v)
10} 10}
11EXPORT_SYMBOL_GPL(amd_report_gart_errors); 11EXPORT_SYMBOL_GPL(amd_report_gart_errors);
12 12
13void amd_register_ecc_decoder(void (*f)(int, struct err_regs *, int)) 13void amd_register_ecc_decoder(void (*f)(int, struct err_regs *))
14{ 14{
15 nb_bus_decoder = f; 15 nb_bus_decoder = f;
16} 16}
17EXPORT_SYMBOL_GPL(amd_register_ecc_decoder); 17EXPORT_SYMBOL_GPL(amd_register_ecc_decoder);
18 18
19void amd_unregister_ecc_decoder(void (*f)(int, struct err_regs *, int)) 19void amd_unregister_ecc_decoder(void (*f)(int, struct err_regs *))
20{ 20{
21 if (nb_bus_decoder) { 21 if (nb_bus_decoder) {
22 WARN_ON(nb_bus_decoder != f); 22 WARN_ON(nb_bus_decoder != f);
@@ -130,7 +130,6 @@ EXPORT_SYMBOL_GPL(ext_msgs);
130 130
131void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors) 131void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
132{ 132{
133 int ecc;
134 u32 ec = ERROR_CODE(regs->nbsl); 133 u32 ec = ERROR_CODE(regs->nbsl);
135 u32 xec = EXT_ERROR_CODE(regs->nbsl); 134 u32 xec = EXT_ERROR_CODE(regs->nbsl);
136 135
@@ -151,21 +150,6 @@ void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
151 pr_cont(", core: %d\n", ilog2((regs->nbsh & 0xf))); 150 pr_cont(", core: %d\n", ilog2((regs->nbsh & 0xf)));
152 } 151 }
153 152
154 pr_emerg(" Error: %sorrected",
155 ((regs->nbsh & K8_NBSH_UC_ERR) ? "Unc" : "C"));
156 pr_cont(", Report Error: %s",
157 ((regs->nbsh & K8_NBSH_ERR_EN) ? "yes" : "no"));
158 pr_cont(", MiscV: %svalid, CPU context corrupt: %s",
159 ((regs->nbsh & K8_NBSH_MISCV) ? "" : "In"),
160 ((regs->nbsh & K8_NBSH_PCC) ? "yes" : "no"));
161
162 /* do the two bits[14:13] together */
163 ecc = regs->nbsh & (0x3 << 13);
164 if (ecc)
165 pr_cont(", %sECC Error", ((ecc == 2) ? "C" : "U"));
166
167 pr_cont("\n");
168
169 if (TLB_ERROR(ec)) { 153 if (TLB_ERROR(ec)) {
170 /* 154 /*
171 * GART errors are intended to help graphics driver developers 155 * GART errors are intended to help graphics driver developers
@@ -191,7 +175,7 @@ void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
191 } else if (BUS_ERROR(ec)) { 175 } else if (BUS_ERROR(ec)) {
192 pr_emerg(" Bus (Link/DRAM) error\n"); 176 pr_emerg(" Bus (Link/DRAM) error\n");
193 if (nb_bus_decoder) 177 if (nb_bus_decoder)
194 nb_bus_decoder(node_id, regs, ecc); 178 nb_bus_decoder(node_id, regs);
195 } else { 179 } else {
196 /* shouldn't reach here! */ 180 /* shouldn't reach here! */
197 pr_warning("%s: unknown MCE error 0x%x\n", __func__, ec); 181 pr_warning("%s: unknown MCE error 0x%x\n", __func__, ec);
@@ -204,16 +188,31 @@ EXPORT_SYMBOL_GPL(amd_decode_nb_mce);
204void decode_mce(struct mce *m) 188void decode_mce(struct mce *m)
205{ 189{
206 struct err_regs regs; 190 struct err_regs regs;
207 int node; 191 int node, ecc;
208 192
209 if (m->bank != 4) 193 pr_emerg("MC%d_STATUS:\n", m->bank);
210 return;
211 194
212 regs.nbsl = (u32) m->status; 195 pr_emerg(" Error: %sorrected, Report: %s, MiscV: %svalid, "
213 regs.nbsh = (u32)(m->status >> 32); 196 "CPU context corrupt: %s",
214 regs.nbeal = (u32) m->addr; 197 ((m->status & MCI_STATUS_UC) ? "Unc" : "C"),
215 regs.nbeah = (u32)(m->addr >> 32); 198 ((m->status & MCI_STATUS_EN) ? "yes" : "no"),
216 node = topology_cpu_node_id(m->extcpu); 199 ((m->status & MCI_STATUS_MISCV) ? "" : "in"),
200 ((m->status & MCI_STATUS_PCC) ? "yes" : "no"));
217 201
218 amd_decode_nb_mce(node, &regs, 1); 202 /* do the two bits[14:13] together */
203 ecc = m->status & (3ULL << 45);
204 if (ecc)
205 pr_cont(", %sECC Error", ((ecc == 2) ? "C" : "U"));
206
207 pr_cont("\n");
208
209 if (m->bank == 4) {
210 regs.nbsl = (u32) m->status;
211 regs.nbsh = (u32)(m->status >> 32);
212 regs.nbeal = (u32) m->addr;
213 regs.nbeah = (u32)(m->addr >> 32);
214 node = per_cpu(cpu_llc_id, m->extcpu);
215
216 amd_decode_nb_mce(node, &regs, 1);
217 }
219} 218}