diff options
Diffstat (limited to 'drivers/edac')
-rw-r--r-- | drivers/edac/amd64_edac.c | 8 | ||||
-rw-r--r-- | drivers/edac/edac_mce_amd.c | 57 | ||||
-rw-r--r-- | drivers/edac/edac_mce_amd.h | 4 |
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 | ||
2285 | static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci, | 2285 | static 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 | ||
2319 | void amd64_decode_bus_error(int node_id, struct err_regs *regs, | 2320 | void 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 | ||
4 | static bool report_gart_errors; | 4 | static bool report_gart_errors; |
5 | static void (*nb_bus_decoder)(int node_id, struct err_regs *regs, int ecc_type); | 5 | static void (*nb_bus_decoder)(int node_id, struct err_regs *regs); |
6 | 6 | ||
7 | void amd_report_gart_errors(bool v) | 7 | void amd_report_gart_errors(bool v) |
8 | { | 8 | { |
@@ -10,13 +10,13 @@ void amd_report_gart_errors(bool v) | |||
10 | } | 10 | } |
11 | EXPORT_SYMBOL_GPL(amd_report_gart_errors); | 11 | EXPORT_SYMBOL_GPL(amd_report_gart_errors); |
12 | 12 | ||
13 | void amd_register_ecc_decoder(void (*f)(int, struct err_regs *, int)) | 13 | void amd_register_ecc_decoder(void (*f)(int, struct err_regs *)) |
14 | { | 14 | { |
15 | nb_bus_decoder = f; | 15 | nb_bus_decoder = f; |
16 | } | 16 | } |
17 | EXPORT_SYMBOL_GPL(amd_register_ecc_decoder); | 17 | EXPORT_SYMBOL_GPL(amd_register_ecc_decoder); |
18 | 18 | ||
19 | void amd_unregister_ecc_decoder(void (*f)(int, struct err_regs *, int)) | 19 | void 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 | ||
131 | void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors) | 131 | void 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); | |||
204 | void decode_mce(struct mce *m) | 188 | void 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, ®s, 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, ®s, 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 | ||
64 | void amd_report_gart_errors(bool); | 64 | void amd_report_gart_errors(bool); |
65 | void amd_register_ecc_decoder(void (*f)(int, struct err_regs *, int)); | 65 | void amd_register_ecc_decoder(void (*f)(int, struct err_regs *)); |
66 | void amd_unregister_ecc_decoder(void (*f)(int, struct err_regs *, int)); | 66 | void amd_unregister_ecc_decoder(void (*f)(int, struct err_regs *)); |
67 | void amd_decode_nb_mce(int, struct err_regs *, int); | 67 | void amd_decode_nb_mce(int, struct err_regs *, int); |
68 | 68 | ||
69 | #endif /* _EDAC_MCE_AMD_H */ | 69 | #endif /* _EDAC_MCE_AMD_H */ |