aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/edac')
-rw-r--r--drivers/edac/amd64_edac.c8
-rw-r--r--drivers/edac/edac_mce_amd.c57
-rw-r--r--drivers/edac/edac_mce_amd.h4
3 files changed, 34 insertions, 35 deletions
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 2080b1e2e8a2..c81ca2cf8dc7 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -2283,10 +2283,11 @@ static void amd64_handle_ue(struct mem_ctl_info *mci,
2283} 2283}
2284 2284
2285static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci, 2285static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci,
2286 struct err_regs *info, int ecc_type) 2286 struct err_regs *info)
2287{ 2287{
2288 u32 ec = ERROR_CODE(info->nbsl); 2288 u32 ec = ERROR_CODE(info->nbsl);
2289 u32 xec = EXT_ERROR_CODE(info->nbsl); 2289 u32 xec = EXT_ERROR_CODE(info->nbsl);
2290 int ecc_type = info->nbsh & (0x3 << 13);
2290 2291
2291 pr_emerg(" Transaction type: %s(%s), %s, Cache Level: %s, %s\n", 2292 pr_emerg(" Transaction type: %s(%s), %s, Cache Level: %s, %s\n",
2292 RRRR_MSG(ec), II_MSG(ec), TO_MSG(ec), LL_MSG(ec), PP_MSG(ec)); 2293 RRRR_MSG(ec), II_MSG(ec), TO_MSG(ec), LL_MSG(ec), PP_MSG(ec));
@@ -2316,12 +2317,11 @@ static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci,
2316 edac_mc_handle_ce_no_info(mci, EDAC_MOD_STR "Error Overflow"); 2317 edac_mc_handle_ce_no_info(mci, EDAC_MOD_STR "Error Overflow");
2317} 2318}
2318 2319
2319void amd64_decode_bus_error(int node_id, struct err_regs *regs, 2320void amd64_decode_bus_error(int node_id, struct err_regs *regs)
2320 int ecc_type)
2321{ 2321{
2322 struct mem_ctl_info *mci = mci_lookup[node_id]; 2322 struct mem_ctl_info *mci = mci_lookup[node_id];
2323 2323
2324 __amd64_decode_bus_error(mci, regs, ecc_type); 2324 __amd64_decode_bus_error(mci, regs);
2325 2325
2326 /* 2326 /*
2327 * Check the UE bit of the NB status high register, if set generate some 2327 * Check the UE bit of the NB status high register, if set generate some
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}
diff --git a/drivers/edac/edac_mce_amd.h b/drivers/edac/edac_mce_amd.h
index 9114dc62782b..df23ee065f79 100644
--- a/drivers/edac/edac_mce_amd.h
+++ b/drivers/edac/edac_mce_amd.h
@@ -62,8 +62,8 @@ struct err_regs {
62 62
63 63
64void amd_report_gart_errors(bool); 64void amd_report_gart_errors(bool);
65void amd_register_ecc_decoder(void (*f)(int, struct err_regs *, int)); 65void amd_register_ecc_decoder(void (*f)(int, struct err_regs *));
66void amd_unregister_ecc_decoder(void (*f)(int, struct err_regs *, int)); 66void amd_unregister_ecc_decoder(void (*f)(int, struct err_regs *));
67void amd_decode_nb_mce(int, struct err_regs *, int); 67void amd_decode_nb_mce(int, struct err_regs *, int);
68 68
69#endif /* _EDAC_MCE_AMD_H */ 69#endif /* _EDAC_MCE_AMD_H */