blob: ba35b7ea3686027dd463ce1e893552e02a70106a [file] [log] [blame]
Borislav Petkovb70ef012009-06-25 19:32:38 +02001#include <linux/module.h>
Borislav Petkov888ab8e2010-08-18 15:11:35 +02002#include <linux/slab.h>
3
Borislav Petkov47ca08a2010-09-27 15:30:39 +02004#include "mce_amd.h"
Doug Thompsonb52401ce2009-05-06 17:57:20 +02005
Borislav Petkov888ab8e2010-08-18 15:11:35 +02006static struct amd_decoder_ops *fam_ops;
7
Borislav Petkov2be64bf2010-09-17 19:11:47 +02008static u8 xec_mask = 0xf;
Borislav Petkov5ce88f62010-08-31 18:28:08 +02009
Borislav Petkov549d0422009-07-24 13:51:42 +020010static bool report_gart_errors;
Yazen Ghannam5c332202016-11-17 17:57:29 -050011static void (*decode_dram_ecc)(int node_id, struct mce *m);
Borislav Petkov549d0422009-07-24 13:51:42 +020012
13void amd_report_gart_errors(bool v)
14{
15 report_gart_errors = v;
16}
17EXPORT_SYMBOL_GPL(amd_report_gart_errors);
18
Borislav Petkovb0b07a22011-08-24 18:44:22 +020019void amd_register_ecc_decoder(void (*f)(int, struct mce *))
Borislav Petkov549d0422009-07-24 13:51:42 +020020{
Yazen Ghannam5c332202016-11-17 17:57:29 -050021 decode_dram_ecc = f;
Borislav Petkov549d0422009-07-24 13:51:42 +020022}
23EXPORT_SYMBOL_GPL(amd_register_ecc_decoder);
24
Borislav Petkovb0b07a22011-08-24 18:44:22 +020025void amd_unregister_ecc_decoder(void (*f)(int, struct mce *))
Borislav Petkov549d0422009-07-24 13:51:42 +020026{
Yazen Ghannam5c332202016-11-17 17:57:29 -050027 if (decode_dram_ecc) {
28 WARN_ON(decode_dram_ecc != f);
Borislav Petkov549d0422009-07-24 13:51:42 +020029
Yazen Ghannam5c332202016-11-17 17:57:29 -050030 decode_dram_ecc = NULL;
Borislav Petkov549d0422009-07-24 13:51:42 +020031 }
32}
33EXPORT_SYMBOL_GPL(amd_unregister_ecc_decoder);
34
Doug Thompsonb52401ce2009-05-06 17:57:20 +020035/*
36 * string representation for the different MCA reported error types, see F3x48
37 * or MSR0000_0411.
38 */
Borislav Petkov63375832010-09-06 18:13:39 +020039
40/* transaction type */
Borislav Petkov0f086692012-12-23 12:40:45 +010041static const char * const tt_msgs[] = { "INSN", "DATA", "GEN", "RESV" };
Doug Thompsonb52401ce2009-05-06 17:57:20 +020042
Borislav Petkov63375832010-09-06 18:13:39 +020043/* cache level */
Borislav Petkov0f086692012-12-23 12:40:45 +010044static const char * const ll_msgs[] = { "RESV", "L1", "L2", "L3/GEN" };
Doug Thompsonb52401ce2009-05-06 17:57:20 +020045
Borislav Petkov63375832010-09-06 18:13:39 +020046/* memory transaction type */
Borislav Petkov0f086692012-12-23 12:40:45 +010047static const char * const rrrr_msgs[] = {
Borislav Petkov63375832010-09-06 18:13:39 +020048 "GEN", "RD", "WR", "DRD", "DWR", "IRD", "PRF", "EV", "SNP"
Doug Thompsonb52401ce2009-05-06 17:57:20 +020049};
50
Borislav Petkov63375832010-09-06 18:13:39 +020051/* participating processor */
Borislav Petkovebe2aea2011-11-29 19:03:25 +010052const char * const pp_msgs[] = { "SRC", "RES", "OBS", "GEN" };
Borislav Petkovb70ef012009-06-25 19:32:38 +020053EXPORT_SYMBOL_GPL(pp_msgs);
Doug Thompsonb52401ce2009-05-06 17:57:20 +020054
Borislav Petkov63375832010-09-06 18:13:39 +020055/* request timeout */
Borislav Petkov0f086692012-12-23 12:40:45 +010056static const char * const to_msgs[] = { "no timeout", "timed out" };
Doug Thompsonb52401ce2009-05-06 17:57:20 +020057
Borislav Petkov63375832010-09-06 18:13:39 +020058/* memory or i/o */
Borislav Petkov0f086692012-12-23 12:40:45 +010059static const char * const ii_msgs[] = { "MEM", "RESV", "IO", "GEN" };
Doug Thompsonb52401ce2009-05-06 17:57:20 +020060
Jacob Shin980eec82012-12-18 15:06:11 -060061/* internal error type */
Borislav Petkov0f086692012-12-23 12:40:45 +010062static const char * const uu_msgs[] = { "RESV", "RESV", "HWA", "RESV" };
Jacob Shin980eec82012-12-18 15:06:11 -060063
Borislav Petkovf05c41a2012-09-11 18:57:43 +020064static const char * const f15h_mc1_mce_desc[] = {
Borislav Petkov86039cd2010-11-08 15:03:35 +010065 "UC during a demand linefill from L2",
66 "Parity error during data load from IC",
67 "Parity error for IC valid bit",
68 "Main tag parity error",
69 "Parity error in prediction queue",
70 "PFB data/address parity error",
71 "Parity error in the branch status reg",
72 "PFB promotion address error",
73 "Tag error during probe/victimization",
74 "Parity error for IC probe tag valid bit",
75 "PFB non-cacheable bit parity error",
76 "PFB valid bit parity error", /* xec = 0xd */
Borislav Petkov6c1173a2011-11-21 19:45:34 +010077 "Microcode Patch Buffer", /* xec = 010 */
Borislav Petkov86039cd2010-11-08 15:03:35 +010078 "uop queue",
79 "insn buffer",
80 "predecode buffer",
Aravind Gopalakrishnaneba4bfb2014-07-14 16:58:19 +020081 "fetch address FIFO",
82 "dispatch uop queue"
Borislav Petkov86039cd2010-11-08 15:03:35 +010083};
84
Borislav Petkovf05c41a2012-09-11 18:57:43 +020085static const char * const f15h_mc2_mce_desc[] = {
Borislav Petkov70fdb492010-09-21 20:45:10 +020086 "Fill ECC error on data fills", /* xec = 0x4 */
87 "Fill parity error on insn fills",
88 "Prefetcher request FIFO parity error",
89 "PRQ address parity error",
90 "PRQ data parity error",
91 "WCC Tag ECC error",
92 "WCC Data ECC error",
93 "WCB Data parity error",
Borislav Petkovb64a99c2011-11-23 14:50:44 +010094 "VB Data ECC or parity error",
Borislav Petkov70fdb492010-09-21 20:45:10 +020095 "L2 Tag ECC error", /* xec = 0x10 */
96 "Hard L2 Tag ECC error",
97 "Multiple hits on L2 tag",
98 "XAB parity error",
99 "PRB address parity error"
100};
101
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200102static const char * const mc4_mce_desc[] = {
Borislav Petkov68782672011-11-24 21:29:57 +0100103 "DRAM ECC error detected on the NB",
104 "CRC error detected on HT link",
105 "Link-defined sync error packets detected on HT link",
106 "HT Master abort",
107 "HT Target abort",
108 "Invalid GART PTE entry during GART table walk",
109 "Unsupported atomic RMW received from an IO link",
110 "Watchdog timeout due to lack of progress",
111 "DRAM ECC error detected on the NB",
112 "SVM DMA Exclusion Vector error",
113 "HT data error detected on link",
114 "Protocol error (link, L3, probe filter)",
115 "NB internal arrays parity error",
116 "DRAM addr/ctl signals parity error",
117 "IO link transmission error",
118 "L3 data cache ECC error", /* xec = 0x1c */
119 "L3 cache tag error",
120 "L3 LRU parity bits error",
121 "ECC Error in the Probe Filter directory"
122};
123
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200124static const char * const mc5_mce_desc[] = {
Borislav Petkov8259a7e2010-09-22 15:28:59 +0200125 "CPU Watchdog timer expire",
126 "Wakeup array dest tag",
127 "AG payload array",
128 "EX payload array",
129 "IDRF array",
130 "Retire dispatch queue",
131 "Mapper checkpoint array",
132 "Physical register file EX0 port",
133 "Physical register file EX1 port",
134 "Physical register file AG0 port",
135 "Physical register file AG1 port",
136 "Flag register file",
Aravind Gopalakrishnanaad19e52013-06-05 15:50:03 -0500137 "DE error occurred",
138 "Retire status queue"
Borislav Petkov8259a7e2010-09-22 15:28:59 +0200139};
140
Aravind Gopalakrishnanbc4febe2014-11-04 11:41:08 -0600141static const char * const mc6_mce_desc[] = {
142 "Hardware Assertion",
143 "Free List",
144 "Physical Register File",
145 "Retire Queue",
146 "Scheduler table",
147 "Status Register File",
148};
149
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100150/* Scalable MCA error strings */
Yazen Ghannam856095b2016-09-12 09:59:33 +0200151static const char * const smca_ls_mce_desc[] = {
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100152 "Load queue parity",
153 "Store queue parity",
154 "Miss address buffer payload parity",
155 "L1 TLB parity",
Yazen Ghannam856095b2016-09-12 09:59:33 +0200156 "Reserved",
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100157 "DC tag error type 6",
158 "DC tag error type 1",
159 "Internal error type 1",
160 "Internal error type 2",
161 "Sys Read data error thread 0",
162 "Sys read data error thread 1",
163 "DC tag error type 2",
164 "DC data error type 1 (poison comsumption)",
165 "DC data error type 2",
166 "DC data error type 3",
167 "DC tag error type 4",
168 "L2 TLB parity",
169 "PDC parity error",
170 "DC tag error type 3",
171 "DC tag error type 5",
172 "L2 fill data error",
173};
174
Yazen Ghannam856095b2016-09-12 09:59:33 +0200175static const char * const smca_if_mce_desc[] = {
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100176 "microtag probe port parity error",
177 "IC microtag or full tag multi-hit error",
178 "IC full tag parity",
179 "IC data array parity",
180 "Decoupling queue phys addr parity error",
181 "L0 ITLB parity error",
182 "L1 ITLB parity error",
183 "L2 ITLB parity error",
184 "BPQ snoop parity on Thread 0",
185 "BPQ snoop parity on Thread 1",
186 "L1 BTB multi-match error",
187 "L2 BTB multi-match error",
Yazen Ghannamc019b952016-09-12 09:59:32 +0200188 "L2 Cache Response Poison error",
189 "System Read Data error",
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100190};
191
Yazen Ghannam856095b2016-09-12 09:59:33 +0200192static const char * const smca_l2_mce_desc[] = {
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100193 "L2M tag multi-way-hit error",
194 "L2M tag ECC error",
195 "L2M data ECC error",
196 "HW assert",
197};
198
Yazen Ghannam856095b2016-09-12 09:59:33 +0200199static const char * const smca_de_mce_desc[] = {
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100200 "uop cache tag parity error",
201 "uop cache data parity error",
202 "Insn buffer parity error",
Yazen Ghannamc019b952016-09-12 09:59:32 +0200203 "uop queue parity error",
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100204 "Insn dispatch queue parity error",
205 "Fetch address FIFO parity",
206 "Patch RAM data parity",
207 "Patch RAM sequencer parity",
208 "uop buffer parity"
209};
210
Yazen Ghannam856095b2016-09-12 09:59:33 +0200211static const char * const smca_ex_mce_desc[] = {
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100212 "Watchdog timeout error",
213 "Phy register file parity",
214 "Flag register file parity",
215 "Immediate displacement register file parity",
216 "Address generator payload parity",
217 "EX payload parity",
218 "Checkpoint queue parity",
219 "Retire dispatch queue parity",
Yazen Ghannamc019b952016-09-12 09:59:32 +0200220 "Retire status queue parity error",
221 "Scheduling queue parity error",
222 "Branch buffer queue parity error",
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100223};
224
Yazen Ghannam856095b2016-09-12 09:59:33 +0200225static const char * const smca_fp_mce_desc[] = {
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100226 "Physical register file parity",
227 "Freelist parity error",
228 "Schedule queue parity",
229 "NSQ parity error",
230 "Retire queue parity",
231 "Status register file parity",
Yazen Ghannamc019b952016-09-12 09:59:32 +0200232 "Hardware assertion",
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100233};
234
Yazen Ghannam856095b2016-09-12 09:59:33 +0200235static const char * const smca_l3_mce_desc[] = {
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100236 "Shadow tag macro ECC error",
237 "Shadow tag macro multi-way-hit error",
238 "L3M tag ECC error",
239 "L3M tag multi-way-hit error",
240 "L3M data ECC error",
241 "XI parity, L3 fill done channel error",
242 "L3 victim queue parity",
243 "L3 HW assert",
244};
245
Yazen Ghannam856095b2016-09-12 09:59:33 +0200246static const char * const smca_cs_mce_desc[] = {
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100247 "Illegal request from transport layer",
248 "Address violation",
249 "Security violation",
250 "Illegal response from transport layer",
251 "Unexpected response",
252 "Parity error on incoming request or probe response data",
253 "Parity error on incoming read response data",
254 "Atomic request parity",
255 "ECC error on probe filter access",
256};
257
Yazen Ghannam856095b2016-09-12 09:59:33 +0200258static const char * const smca_pie_mce_desc[] = {
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100259 "HW assert",
260 "Internal PIE register security violation",
261 "Error on GMI link",
262 "Poison data written to internal PIE register",
263};
264
Yazen Ghannam856095b2016-09-12 09:59:33 +0200265static const char * const smca_umc_mce_desc[] = {
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100266 "DRAM ECC error",
267 "Data poison error on DRAM",
268 "SDP parity error",
269 "Advanced peripheral bus error",
270 "Command/address parity error",
271 "Write data CRC error",
272};
273
Yazen Ghannam856095b2016-09-12 09:59:33 +0200274static const char * const smca_pb_mce_desc[] = {
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100275 "Parameter Block RAM ECC error",
276};
277
Yazen Ghannam856095b2016-09-12 09:59:33 +0200278static const char * const smca_psp_mce_desc[] = {
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100279 "PSP RAM ECC or parity error",
280};
281
Yazen Ghannam856095b2016-09-12 09:59:33 +0200282static const char * const smca_smu_mce_desc[] = {
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100283 "SMU RAM ECC or parity error",
284};
285
Yazen Ghannam58968202016-09-12 09:59:34 +0200286struct smca_mce_desc {
287 const char * const *descs;
288 unsigned int num_descs;
289};
290
291static struct smca_mce_desc smca_mce_descs[] = {
292 [SMCA_LS] = { smca_ls_mce_desc, ARRAY_SIZE(smca_ls_mce_desc) },
293 [SMCA_IF] = { smca_if_mce_desc, ARRAY_SIZE(smca_if_mce_desc) },
294 [SMCA_L2_CACHE] = { smca_l2_mce_desc, ARRAY_SIZE(smca_l2_mce_desc) },
295 [SMCA_DE] = { smca_de_mce_desc, ARRAY_SIZE(smca_de_mce_desc) },
296 [SMCA_EX] = { smca_ex_mce_desc, ARRAY_SIZE(smca_ex_mce_desc) },
297 [SMCA_FP] = { smca_fp_mce_desc, ARRAY_SIZE(smca_fp_mce_desc) },
298 [SMCA_L3_CACHE] = { smca_l3_mce_desc, ARRAY_SIZE(smca_l3_mce_desc) },
299 [SMCA_CS] = { smca_cs_mce_desc, ARRAY_SIZE(smca_cs_mce_desc) },
300 [SMCA_PIE] = { smca_pie_mce_desc, ARRAY_SIZE(smca_pie_mce_desc) },
301 [SMCA_UMC] = { smca_umc_mce_desc, ARRAY_SIZE(smca_umc_mce_desc) },
302 [SMCA_PB] = { smca_pb_mce_desc, ARRAY_SIZE(smca_pb_mce_desc) },
303 [SMCA_PSP] = { smca_psp_mce_desc, ARRAY_SIZE(smca_psp_mce_desc) },
304 [SMCA_SMU] = { smca_smu_mce_desc, ARRAY_SIZE(smca_smu_mce_desc) },
305};
306
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200307static bool f12h_mc0_mce(u16 ec, u8 xec)
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200308{
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200309 bool ret = false;
310
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200311 if (MEM_ERROR(ec)) {
Borislav Petkov62452882010-09-22 16:08:37 +0200312 u8 ll = LL(ec);
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200313 ret = true;
314
315 if (ll == LL_L2)
316 pr_cont("during L1 linefill from L2.\n");
317 else if (ll == LL_L1)
Borislav Petkov62452882010-09-22 16:08:37 +0200318 pr_cont("Data/Tag %s error.\n", R4_MSG(ec));
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200319 else
320 ret = false;
321 }
322 return ret;
323}
324
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200325static bool f10h_mc0_mce(u16 ec, u8 xec)
Borislav Petkov9be0bb12010-09-16 15:08:14 +0200326{
Borislav Petkov62452882010-09-22 16:08:37 +0200327 if (R4(ec) == R4_GEN && LL(ec) == LL_L1) {
Borislav Petkov9be0bb12010-09-16 15:08:14 +0200328 pr_cont("during data scrub.\n");
329 return true;
330 }
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200331 return f12h_mc0_mce(ec, xec);
Borislav Petkov9be0bb12010-09-16 15:08:14 +0200332}
333
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200334static bool k8_mc0_mce(u16 ec, u8 xec)
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200335{
336 if (BUS_ERROR(ec)) {
337 pr_cont("during system linefill.\n");
338 return true;
339 }
340
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200341 return f10h_mc0_mce(ec, xec);
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200342}
343
Jacob Shin980eec82012-12-18 15:06:11 -0600344static bool cat_mc0_mce(u16 ec, u8 xec)
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200345{
Borislav Petkov62452882010-09-22 16:08:37 +0200346 u8 r4 = R4(ec);
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200347 bool ret = true;
348
349 if (MEM_ERROR(ec)) {
350
Borislav Petkov62452882010-09-22 16:08:37 +0200351 if (TT(ec) != TT_DATA || LL(ec) != LL_L1)
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200352 return false;
353
354 switch (r4) {
355 case R4_DRD:
356 case R4_DWR:
357 pr_cont("Data/Tag parity error due to %s.\n",
358 (r4 == R4_DRD ? "load/hw prf" : "store"));
359 break;
360 case R4_EVICT:
361 pr_cont("Copyback parity error on a tag miss.\n");
362 break;
363 case R4_SNOOP:
364 pr_cont("Tag parity error during snoop.\n");
365 break;
366 default:
367 ret = false;
368 }
369 } else if (BUS_ERROR(ec)) {
370
Borislav Petkov62452882010-09-22 16:08:37 +0200371 if ((II(ec) != II_MEM && II(ec) != II_IO) || LL(ec) != LL_LG)
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200372 return false;
373
374 pr_cont("System read data error on a ");
375
376 switch (r4) {
377 case R4_RD:
378 pr_cont("TLB reload.\n");
379 break;
380 case R4_DWR:
381 pr_cont("store.\n");
382 break;
383 case R4_DRD:
384 pr_cont("load.\n");
385 break;
386 default:
387 ret = false;
388 }
389 } else {
390 ret = false;
391 }
392
393 return ret;
394}
395
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200396static bool f15h_mc0_mce(u16 ec, u8 xec)
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200397{
398 bool ret = true;
399
400 if (MEM_ERROR(ec)) {
401
402 switch (xec) {
403 case 0x0:
404 pr_cont("Data Array access error.\n");
405 break;
406
407 case 0x1:
408 pr_cont("UC error during a linefill from L2/NB.\n");
409 break;
410
411 case 0x2:
412 case 0x11:
413 pr_cont("STQ access error.\n");
414 break;
415
416 case 0x3:
417 pr_cont("SCB access error.\n");
418 break;
419
420 case 0x10:
421 pr_cont("Tag error.\n");
422 break;
423
424 case 0x12:
425 pr_cont("LDQ access error.\n");
426 break;
427
428 default:
429 ret = false;
430 }
431 } else if (BUS_ERROR(ec)) {
432
433 if (!xec)
Borislav Petkov344f0a02011-11-15 17:10:58 +0100434 pr_cont("System Read Data Error.\n");
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200435 else
Borislav Petkov344f0a02011-11-15 17:10:58 +0100436 pr_cont(" Internal error condition type %d.\n", xec);
Aravind Gopalakrishnaneba4bfb2014-07-14 16:58:19 +0200437 } else if (INT_ERROR(ec)) {
438 if (xec <= 0x1f)
439 pr_cont("Hardware Assert.\n");
440 else
441 ret = false;
442
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200443 } else
444 ret = false;
445
446 return ret;
447}
448
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200449static void decode_mc0_mce(struct mce *m)
Borislav Petkov51966242009-07-28 13:50:43 +0200450{
Borislav Petkov62452882010-09-22 16:08:37 +0200451 u16 ec = EC(m->status);
452 u8 xec = XEC(m->status, xec_mask);
Borislav Petkov51966242009-07-28 13:50:43 +0200453
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200454 pr_emerg(HW_ERR "MC0 Error: ");
Borislav Petkov51966242009-07-28 13:50:43 +0200455
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200456 /* TLB error signatures are the same across families */
457 if (TLB_ERROR(ec)) {
Borislav Petkov62452882010-09-22 16:08:37 +0200458 if (TT(ec) == TT_DATA) {
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200459 pr_cont("%s TLB %s.\n", LL_MSG(ec),
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200460 ((xec == 2) ? "locked miss"
461 : (xec ? "multimatch" : "parity")));
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200462 return;
463 }
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200464 } else if (fam_ops->mc0_mce(ec, xec))
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200465 ;
466 else
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200467 pr_emerg(HW_ERR "Corrupted MC0 MCE info?\n");
Borislav Petkov51966242009-07-28 13:50:43 +0200468}
469
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200470static bool k8_mc1_mce(u16 ec, u8 xec)
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200471{
Borislav Petkov62452882010-09-22 16:08:37 +0200472 u8 ll = LL(ec);
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200473 bool ret = true;
474
475 if (!MEM_ERROR(ec))
476 return false;
477
478 if (ll == 0x2)
479 pr_cont("during a linefill from L2.\n");
480 else if (ll == 0x1) {
Borislav Petkov62452882010-09-22 16:08:37 +0200481 switch (R4(ec)) {
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200482 case R4_IRD:
483 pr_cont("Parity error during data load.\n");
484 break;
485
486 case R4_EVICT:
487 pr_cont("Copyback Parity/Victim error.\n");
488 break;
489
490 case R4_SNOOP:
491 pr_cont("Tag Snoop error.\n");
492 break;
493
494 default:
495 ret = false;
496 break;
497 }
498 } else
499 ret = false;
500
501 return ret;
502}
503
Jacob Shin980eec82012-12-18 15:06:11 -0600504static bool cat_mc1_mce(u16 ec, u8 xec)
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200505{
Borislav Petkov62452882010-09-22 16:08:37 +0200506 u8 r4 = R4(ec);
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200507 bool ret = true;
508
Jacob Shin980eec82012-12-18 15:06:11 -0600509 if (!MEM_ERROR(ec))
510 return false;
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200511
Jacob Shin980eec82012-12-18 15:06:11 -0600512 if (TT(ec) != TT_INSTR)
513 return false;
514
515 if (r4 == R4_IRD)
516 pr_cont("Data/tag array parity error for a tag hit.\n");
517 else if (r4 == R4_SNOOP)
518 pr_cont("Tag error during snoop/victimization.\n");
519 else if (xec == 0x0)
520 pr_cont("Tag parity error from victim castout.\n");
521 else if (xec == 0x2)
522 pr_cont("Microcode patch RAM parity error.\n");
523 else
524 ret = false;
525
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200526 return ret;
527}
528
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200529static bool f15h_mc1_mce(u16 ec, u8 xec)
Borislav Petkov86039cd2010-11-08 15:03:35 +0100530{
531 bool ret = true;
532
533 if (!MEM_ERROR(ec))
534 return false;
535
536 switch (xec) {
537 case 0x0 ... 0xa:
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200538 pr_cont("%s.\n", f15h_mc1_mce_desc[xec]);
Borislav Petkov86039cd2010-11-08 15:03:35 +0100539 break;
540
541 case 0xd:
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200542 pr_cont("%s.\n", f15h_mc1_mce_desc[xec-2]);
Borislav Petkov86039cd2010-11-08 15:03:35 +0100543 break;
544
Borislav Petkov6c1173a2011-11-21 19:45:34 +0100545 case 0x10:
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200546 pr_cont("%s.\n", f15h_mc1_mce_desc[xec-4]);
Borislav Petkov6c1173a2011-11-21 19:45:34 +0100547 break;
548
Aravind Gopalakrishnaneba4bfb2014-07-14 16:58:19 +0200549 case 0x11 ... 0x15:
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200550 pr_cont("Decoder %s parity error.\n", f15h_mc1_mce_desc[xec-4]);
Borislav Petkov86039cd2010-11-08 15:03:35 +0100551 break;
552
553 default:
554 ret = false;
555 }
556 return ret;
557}
558
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200559static void decode_mc1_mce(struct mce *m)
Borislav Petkovab5535e2009-07-28 14:06:26 +0200560{
Borislav Petkov62452882010-09-22 16:08:37 +0200561 u16 ec = EC(m->status);
562 u8 xec = XEC(m->status, xec_mask);
Borislav Petkovab5535e2009-07-28 14:06:26 +0200563
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200564 pr_emerg(HW_ERR "MC1 Error: ");
Borislav Petkovab5535e2009-07-28 14:06:26 +0200565
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200566 if (TLB_ERROR(ec))
567 pr_cont("%s TLB %s.\n", LL_MSG(ec),
568 (xec ? "multimatch" : "parity error"));
569 else if (BUS_ERROR(ec)) {
Borislav Petkov525906b2010-10-15 15:27:02 +0200570 bool k8 = (boot_cpu_data.x86 == 0xf && (m->status & BIT_64(58)));
Borislav Petkovab5535e2009-07-28 14:06:26 +0200571
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200572 pr_cont("during %s.\n", (k8 ? "system linefill" : "NB data read"));
Aravind Gopalakrishnaneba4bfb2014-07-14 16:58:19 +0200573 } else if (INT_ERROR(ec)) {
574 if (xec <= 0x3f)
575 pr_cont("Hardware Assert.\n");
576 else
577 goto wrong_mc1_mce;
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200578 } else if (fam_ops->mc1_mce(ec, xec))
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200579 ;
580 else
Aravind Gopalakrishnaneba4bfb2014-07-14 16:58:19 +0200581 goto wrong_mc1_mce;
582
583 return;
584
585wrong_mc1_mce:
586 pr_emerg(HW_ERR "Corrupted MC1 MCE info?\n");
Borislav Petkovab5535e2009-07-28 14:06:26 +0200587}
588
Jacob Shin4a73d3d2012-12-18 15:06:10 -0600589static bool k8_mc2_mce(u16 ec, u8 xec)
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200590{
Jacob Shin4a73d3d2012-12-18 15:06:10 -0600591 bool ret = true;
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200592
593 if (xec == 0x1)
594 pr_cont(" in the write data buffers.\n");
595 else if (xec == 0x3)
596 pr_cont(" in the victim data buffers.\n");
597 else if (xec == 0x2 && MEM_ERROR(ec))
Borislav Petkov62452882010-09-22 16:08:37 +0200598 pr_cont(": %s error in the L2 cache tags.\n", R4_MSG(ec));
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200599 else if (xec == 0x0) {
600 if (TLB_ERROR(ec))
Borislav Petkov50872cc2014-11-22 13:41:01 +0100601 pr_cont("%s error in a Page Descriptor Cache or Guest TLB.\n",
602 TT_MSG(ec));
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200603 else if (BUS_ERROR(ec))
604 pr_cont(": %s/ECC error in data read from NB: %s.\n",
Borislav Petkov62452882010-09-22 16:08:37 +0200605 R4_MSG(ec), PP_MSG(ec));
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200606 else if (MEM_ERROR(ec)) {
Borislav Petkov62452882010-09-22 16:08:37 +0200607 u8 r4 = R4(ec);
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200608
Borislav Petkov62452882010-09-22 16:08:37 +0200609 if (r4 >= 0x7)
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200610 pr_cont(": %s error during data copyback.\n",
Borislav Petkov62452882010-09-22 16:08:37 +0200611 R4_MSG(ec));
612 else if (r4 <= 0x1)
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200613 pr_cont(": %s parity/ECC error during data "
Borislav Petkov62452882010-09-22 16:08:37 +0200614 "access from L2.\n", R4_MSG(ec));
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200615 else
Jacob Shin4a73d3d2012-12-18 15:06:10 -0600616 ret = false;
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200617 } else
Jacob Shin4a73d3d2012-12-18 15:06:10 -0600618 ret = false;
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200619 } else
Jacob Shin4a73d3d2012-12-18 15:06:10 -0600620 ret = false;
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200621
Jacob Shin4a73d3d2012-12-18 15:06:10 -0600622 return ret;
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200623}
624
Jacob Shin4a73d3d2012-12-18 15:06:10 -0600625static bool f15h_mc2_mce(u16 ec, u8 xec)
Borislav Petkov70fdb492010-09-21 20:45:10 +0200626{
Jacob Shin4a73d3d2012-12-18 15:06:10 -0600627 bool ret = true;
Borislav Petkov70fdb492010-09-21 20:45:10 +0200628
629 if (TLB_ERROR(ec)) {
630 if (xec == 0x0)
631 pr_cont("Data parity TLB read error.\n");
632 else if (xec == 0x1)
633 pr_cont("Poison data provided for TLB fill.\n");
634 else
Jacob Shin4a73d3d2012-12-18 15:06:10 -0600635 ret = false;
Borislav Petkov70fdb492010-09-21 20:45:10 +0200636 } else if (BUS_ERROR(ec)) {
637 if (xec > 2)
Jacob Shin4a73d3d2012-12-18 15:06:10 -0600638 ret = false;
Borislav Petkov70fdb492010-09-21 20:45:10 +0200639
640 pr_cont("Error during attempted NB data read.\n");
641 } else if (MEM_ERROR(ec)) {
642 switch (xec) {
643 case 0x4 ... 0xc:
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200644 pr_cont("%s.\n", f15h_mc2_mce_desc[xec - 0x4]);
Borislav Petkov70fdb492010-09-21 20:45:10 +0200645 break;
646
647 case 0x10 ... 0x14:
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200648 pr_cont("%s.\n", f15h_mc2_mce_desc[xec - 0x7]);
Borislav Petkov70fdb492010-09-21 20:45:10 +0200649 break;
650
651 default:
Jacob Shin4a73d3d2012-12-18 15:06:10 -0600652 ret = false;
Borislav Petkov70fdb492010-09-21 20:45:10 +0200653 }
Aravind Gopalakrishnaneba4bfb2014-07-14 16:58:19 +0200654 } else if (INT_ERROR(ec)) {
655 if (xec <= 0x3f)
656 pr_cont("Hardware Assert.\n");
657 else
658 ret = false;
Borislav Petkov70fdb492010-09-21 20:45:10 +0200659 }
660
Jacob Shin4a73d3d2012-12-18 15:06:10 -0600661 return ret;
662}
Borislav Petkov70fdb492010-09-21 20:45:10 +0200663
Jacob Shin980eec82012-12-18 15:06:11 -0600664static bool f16h_mc2_mce(u16 ec, u8 xec)
665{
666 u8 r4 = R4(ec);
667
668 if (!MEM_ERROR(ec))
669 return false;
670
671 switch (xec) {
672 case 0x04 ... 0x05:
673 pr_cont("%cBUFF parity error.\n", (r4 == R4_RD) ? 'I' : 'O');
674 break;
675
676 case 0x09 ... 0x0b:
677 case 0x0d ... 0x0f:
678 pr_cont("ECC error in L2 tag (%s).\n",
679 ((r4 == R4_GEN) ? "BankReq" :
680 ((r4 == R4_SNOOP) ? "Prb" : "Fill")));
681 break;
682
683 case 0x10 ... 0x19:
684 case 0x1b:
685 pr_cont("ECC error in L2 data array (%s).\n",
686 (((r4 == R4_RD) && !(xec & 0x3)) ? "Hit" :
687 ((r4 == R4_GEN) ? "Attr" :
688 ((r4 == R4_EVICT) ? "Vict" : "Fill"))));
689 break;
690
691 case 0x1c ... 0x1d:
692 case 0x1f:
693 pr_cont("Parity error in L2 attribute bits (%s).\n",
694 ((r4 == R4_RD) ? "Hit" :
695 ((r4 == R4_GEN) ? "Attr" : "Fill")));
696 break;
697
698 default:
699 return false;
700 }
701
702 return true;
703}
704
Jacob Shin4a73d3d2012-12-18 15:06:10 -0600705static void decode_mc2_mce(struct mce *m)
706{
707 u16 ec = EC(m->status);
708 u8 xec = XEC(m->status, xec_mask);
709
710 pr_emerg(HW_ERR "MC2 Error: ");
711
712 if (!fam_ops->mc2_mce(ec, xec))
713 pr_cont(HW_ERR "Corrupted MC2 MCE info?\n");
Borislav Petkov70fdb492010-09-21 20:45:10 +0200714}
715
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200716static void decode_mc3_mce(struct mce *m)
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200717{
Borislav Petkov62452882010-09-22 16:08:37 +0200718 u16 ec = EC(m->status);
719 u8 xec = XEC(m->status, xec_mask);
Borislav Petkovded50622010-08-27 17:03:34 +0200720
Borislav Petkovb18434c2010-09-22 11:53:32 +0200721 if (boot_cpu_data.x86 >= 0x14) {
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200722 pr_emerg("You shouldn't be seeing MC3 MCE on this cpu family,"
Borislav Petkovded50622010-08-27 17:03:34 +0200723 " please report on LKML.\n");
724 return;
725 }
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200726
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200727 pr_emerg(HW_ERR "MC3 Error");
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200728
729 if (xec == 0x0) {
Borislav Petkov62452882010-09-22 16:08:37 +0200730 u8 r4 = R4(ec);
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200731
Borislav Petkovded50622010-08-27 17:03:34 +0200732 if (!BUS_ERROR(ec) || (r4 != R4_DRD && r4 != R4_DWR))
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200733 goto wrong_mc3_mce;
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200734
Borislav Petkov62452882010-09-22 16:08:37 +0200735 pr_cont(" during %s.\n", R4_MSG(ec));
Borislav Petkovded50622010-08-27 17:03:34 +0200736 } else
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200737 goto wrong_mc3_mce;
Borislav Petkovded50622010-08-27 17:03:34 +0200738
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200739 return;
740
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200741 wrong_mc3_mce:
742 pr_emerg(HW_ERR "Corrupted MC3 MCE info?\n");
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200743}
744
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200745static void decode_mc4_mce(struct mce *m)
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200746{
Borislav Petkov68782672011-11-24 21:29:57 +0100747 struct cpuinfo_x86 *c = &boot_cpu_data;
748 int node_id = amd_get_nb_id(m->extcpu);
749 u16 ec = EC(m->status);
750 u8 xec = XEC(m->status, 0x1f);
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200751 u8 offset = 0;
752
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200753 pr_emerg(HW_ERR "MC4 Error (node %d): ", node_id);
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200754
Borislav Petkov68782672011-11-24 21:29:57 +0100755 switch (xec) {
756 case 0x0 ... 0xe:
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200757
Borislav Petkov68782672011-11-24 21:29:57 +0100758 /* special handling for DRAM ECCs */
759 if (xec == 0x0 || xec == 0x8) {
760 /* no ECCs on F11h */
761 if (c->x86 == 0x11)
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200762 goto wrong_mc4_mce;
Borislav Petkov68782672011-11-24 21:29:57 +0100763
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200764 pr_cont("%s.\n", mc4_mce_desc[xec]);
Borislav Petkov68782672011-11-24 21:29:57 +0100765
Yazen Ghannam5c332202016-11-17 17:57:29 -0500766 if (decode_dram_ecc)
767 decode_dram_ecc(node_id, m);
Borislav Petkov68782672011-11-24 21:29:57 +0100768 return;
769 }
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200770 break;
771
772 case 0xf:
773 if (TLB_ERROR(ec))
774 pr_cont("GART Table Walk data error.\n");
775 else if (BUS_ERROR(ec))
776 pr_cont("DMA Exclusion Vector Table Walk error.\n");
777 else
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200778 goto wrong_mc4_mce;
Borislav Petkov68782672011-11-24 21:29:57 +0100779 return;
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200780
Borislav Petkov05cd6672010-09-22 15:06:24 +0200781 case 0x19:
Jacob Shin980eec82012-12-18 15:06:11 -0600782 if (boot_cpu_data.x86 == 0x15 || boot_cpu_data.x86 == 0x16)
Borislav Petkov05cd6672010-09-22 15:06:24 +0200783 pr_cont("Compute Unit Data Error.\n");
784 else
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200785 goto wrong_mc4_mce;
Borislav Petkov68782672011-11-24 21:29:57 +0100786 return;
Borislav Petkov05cd6672010-09-22 15:06:24 +0200787
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200788 case 0x1c ... 0x1f:
Borislav Petkov68782672011-11-24 21:29:57 +0100789 offset = 13;
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200790 break;
791
792 default:
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200793 goto wrong_mc4_mce;
Borislav Petkov68782672011-11-24 21:29:57 +0100794 }
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200795
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200796 pr_cont("%s.\n", mc4_mce_desc[xec - offset]);
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200797 return;
798
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200799 wrong_mc4_mce:
800 pr_emerg(HW_ERR "Corrupted MC4 MCE info?\n");
Borislav Petkovd93cc222009-07-28 10:56:15 +0200801}
Borislav Petkovd93cc222009-07-28 10:56:15 +0200802
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200803static void decode_mc5_mce(struct mce *m)
Borislav Petkov53bd5fe2009-07-28 14:20:46 +0200804{
Borislav Petkov8259a7e2010-09-22 15:28:59 +0200805 struct cpuinfo_x86 *c = &boot_cpu_data;
Aravind Gopalakrishnaneba4bfb2014-07-14 16:58:19 +0200806 u16 ec = EC(m->status);
Borislav Petkov62452882010-09-22 16:08:37 +0200807 u8 xec = XEC(m->status, xec_mask);
Borislav Petkov8259a7e2010-09-22 15:28:59 +0200808
809 if (c->x86 == 0xf || c->x86 == 0x11)
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200810 goto wrong_mc5_mce;
Borislav Petkovfe4ea262010-08-31 18:38:24 +0200811
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200812 pr_emerg(HW_ERR "MC5 Error: ");
Borislav Petkov8259a7e2010-09-22 15:28:59 +0200813
Aravind Gopalakrishnaneba4bfb2014-07-14 16:58:19 +0200814 if (INT_ERROR(ec)) {
815 if (xec <= 0x1f) {
816 pr_cont("Hardware Assert.\n");
817 return;
818 } else
819 goto wrong_mc5_mce;
820 }
821
Borislav Petkov8259a7e2010-09-22 15:28:59 +0200822 if (xec == 0x0 || xec == 0xc)
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200823 pr_cont("%s.\n", mc5_mce_desc[xec]);
Aravind Gopalakrishnanaad19e52013-06-05 15:50:03 -0500824 else if (xec <= 0xd)
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200825 pr_cont("%s parity error.\n", mc5_mce_desc[xec]);
Borislav Petkov8259a7e2010-09-22 15:28:59 +0200826 else
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200827 goto wrong_mc5_mce;
Borislav Petkov8259a7e2010-09-22 15:28:59 +0200828
829 return;
Borislav Petkovfe4ea262010-08-31 18:38:24 +0200830
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200831 wrong_mc5_mce:
832 pr_emerg(HW_ERR "Corrupted MC5 MCE info?\n");
Borislav Petkov53bd5fe2009-07-28 14:20:46 +0200833}
834
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200835static void decode_mc6_mce(struct mce *m)
Borislav Petkovb8f85c42010-09-22 15:37:58 +0200836{
Borislav Petkov62452882010-09-22 16:08:37 +0200837 u8 xec = XEC(m->status, xec_mask);
Borislav Petkovb8f85c42010-09-22 15:37:58 +0200838
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200839 pr_emerg(HW_ERR "MC6 Error: ");
Borislav Petkovb8f85c42010-09-22 15:37:58 +0200840
Aravind Gopalakrishnanbc4febe2014-11-04 11:41:08 -0600841 if (xec > 0x5)
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200842 goto wrong_mc6_mce;
Borislav Petkovb8f85c42010-09-22 15:37:58 +0200843
Aravind Gopalakrishnanbc4febe2014-11-04 11:41:08 -0600844 pr_cont("%s parity error.\n", mc6_mce_desc[xec]);
Borislav Petkovb8f85c42010-09-22 15:37:58 +0200845 return;
846
Borislav Petkovf05c41a2012-09-11 18:57:43 +0200847 wrong_mc6_mce:
848 pr_emerg(HW_ERR "Corrupted MC6 MCE info?\n");
Borislav Petkovb8f85c42010-09-22 15:37:58 +0200849}
850
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100851/* Decode errors according to Scalable MCA specification */
852static void decode_smca_errors(struct mce *m)
853{
Borislav Petkov1ce9cd72016-11-02 12:48:01 +0100854 struct smca_hwid *hwid;
Yazen Ghannam58968202016-09-12 09:59:34 +0200855 unsigned int bank_type;
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100856 const char *ip_name;
Yazen Ghannam58968202016-09-12 09:59:34 +0200857 u8 xec = XEC(m->status, xec_mask);
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100858
Yazen Ghannam58968202016-09-12 09:59:34 +0200859 if (m->bank >= ARRAY_SIZE(smca_banks))
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100860 return;
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100861
Yazen Ghannama8846752016-09-12 09:59:40 +0200862 if (boot_cpu_data.x86 >= 0x17 && m->bank == 4)
863 pr_emerg(HW_ERR "Bank 4 is reserved on Fam17h.\n");
864
Borislav Petkov1ce9cd72016-11-02 12:48:01 +0100865 hwid = smca_banks[m->bank].hwid;
866 if (!hwid)
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100867 return;
Yazen Ghannam58968202016-09-12 09:59:34 +0200868
Borislav Petkov1ce9cd72016-11-02 12:48:01 +0100869 bank_type = hwid->bank_type;
Borislav Petkovc09a8c42016-11-03 21:12:33 +0100870 ip_name = smca_get_long_name(bank_type);
Yazen Ghannam58968202016-09-12 09:59:34 +0200871
872 pr_emerg(HW_ERR "%s Extended Error Code: %d\n", ip_name, xec);
873
874 /* Only print the decode of valid error codes */
875 if (xec < smca_mce_descs[bank_type].num_descs &&
Borislav Petkov1ce9cd72016-11-02 12:48:01 +0100876 (hwid->xec_bitmap & BIT_ULL(xec))) {
Yazen Ghannam58968202016-09-12 09:59:34 +0200877 pr_emerg(HW_ERR "%s Error: ", ip_name);
878 pr_cont("%s.\n", smca_mce_descs[bank_type].descs[xec]);
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100879 }
Yazen Ghannam5c332202016-11-17 17:57:29 -0500880
881 /*
882 * amd_get_nb_id() returns the last level cache id.
883 * The last level cache on Fam17h is 1 level below the node.
884 */
885 if (bank_type == SMCA_UMC && xec == 0 && decode_dram_ecc)
886 decode_dram_ecc(amd_get_nb_id(m->extcpu) >> 1, m);
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100887}
888
Borislav Petkov63375832010-09-06 18:13:39 +0200889static inline void amd_decode_err_code(u16 ec)
Borislav Petkovd93cc222009-07-28 10:56:15 +0200890{
Jacob Shin980eec82012-12-18 15:06:11 -0600891 if (INT_ERROR(ec)) {
892 pr_emerg(HW_ERR "internal: %s\n", UU_MSG(ec));
893 return;
894 }
Borislav Petkovfa7ae8c2010-09-22 17:42:27 +0200895
896 pr_emerg(HW_ERR "cache level: %s", LL_MSG(ec));
897
898 if (BUS_ERROR(ec))
899 pr_cont(", mem/io: %s", II_MSG(ec));
900 else
901 pr_cont(", tx: %s", TT_MSG(ec));
902
903 if (MEM_ERROR(ec) || BUS_ERROR(ec)) {
904 pr_cont(", mem-tx: %s", R4_MSG(ec));
905
906 if (BUS_ERROR(ec))
907 pr_cont(", part-proc: %s (%s)", PP_MSG(ec), TO_MSG(ec));
908 }
909
910 pr_cont("\n");
Borislav Petkov549d0422009-07-24 13:51:42 +0200911}
Borislav Petkov549d0422009-07-24 13:51:42 +0200912
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200913/*
914 * Filter out unwanted MCE signatures here.
915 */
916static bool amd_filter_mce(struct mce *m)
917{
918 u8 xec = (m->status >> 16) & 0x1f;
919
920 /*
921 * NB GART TLB error reporting is disabled by default.
922 */
923 if (m->bank == 4 && xec == 0x5 && !report_gart_errors)
924 return true;
925
926 return false;
927}
928
Borislav Petkovd5c67702012-09-14 20:25:37 +0200929static const char *decode_error_status(struct mce *m)
930{
931 if (m->status & MCI_STATUS_UC) {
932 if (m->status & MCI_STATUS_PCC)
933 return "System Fatal error.";
934 if (m->mcgstatus & MCG_STATUS_RIPV)
935 return "Uncorrected, software restartable error.";
936 return "Uncorrected, software containable error.";
937 }
938
939 if (m->status & MCI_STATUS_DEFERRED)
Yazen Ghannam67d7fd32017-01-24 16:32:23 -0600940 return "Deferred error, no action required.";
Borislav Petkovd5c67702012-09-14 20:25:37 +0200941
942 return "Corrected error, no action required.";
943}
944
Borislav Petkov1fbcd902017-01-23 19:35:11 +0100945static int
946amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
Borislav Petkov549d0422009-07-24 13:51:42 +0200947{
Borislav Petkovfb253192009-10-07 13:20:38 +0200948 struct mce *m = (struct mce *)data;
Borislav Petkovf89f8382012-09-13 15:14:22 +0200949 struct cpuinfo_x86 *c = &cpu_data(m->extcpu);
Borislav Petkovb0b07a22011-08-24 18:44:22 +0200950 int ecc;
Borislav Petkov549d0422009-07-24 13:51:42 +0200951
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200952 if (amd_filter_mce(m))
953 return NOTIFY_STOP;
954
Borislav Petkovfd0f5fff2014-02-17 20:51:52 +0100955 pr_emerg(HW_ERR "%s\n", decode_error_status(m));
956
957 pr_emerg(HW_ERR "CPU:%d (%x:%x:%x) MC%d_STATUS[%s|%s|%s|%s|%s",
958 m->extcpu,
959 c->x86, c->x86_model, c->x86_mask,
960 m->bank,
961 ((m->status & MCI_STATUS_OVER) ? "Over" : "-"),
Aravind Gopalakrishnan99e1dfb2015-07-13 06:53:02 -0500962 ((m->status & MCI_STATUS_UC) ? "UE" :
963 (m->status & MCI_STATUS_DEFERRED) ? "-" : "CE"),
Borislav Petkovfd0f5fff2014-02-17 20:51:52 +0100964 ((m->status & MCI_STATUS_MISCV) ? "MiscV" : "-"),
965 ((m->status & MCI_STATUS_PCC) ? "PCC" : "-"),
966 ((m->status & MCI_STATUS_ADDRV) ? "AddrV" : "-"));
967
Yazen Ghannama6c14dc2016-11-18 09:10:22 -0500968 if (c->x86 >= 0x15) {
969 pr_cont("|%s", (m->status & MCI_STATUS_DEFERRED ? "Deferred" : "-"));
970
971 /* F15h, bank4, bit 43 is part of McaStatSubCache. */
972 if (c->x86 != 0x15 || m->bank != 4)
973 pr_cont("|%s", (m->status & MCI_STATUS_POISON ? "Poison" : "-"));
974 }
Borislav Petkovfd0f5fff2014-02-17 20:51:52 +0100975
Yazen Ghannama348ed82016-05-11 14:58:28 +0200976 if (boot_cpu_has(X86_FEATURE_SMCA)) {
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100977 u32 low, high;
978 u32 addr = MSR_AMD64_SMCA_MCx_CONFIG(m->bank);
979
Yazen Ghannamb300e872016-09-12 09:59:29 +0200980 pr_cont("|%s", ((m->status & MCI_STATUS_SYNDV) ? "SyndV" : "-"));
981
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +0100982 if (!rdmsr_safe(addr, &low, &high) &&
983 (low & MCI_CONFIG_MCAX))
984 pr_cont("|%s", ((m->status & MCI_STATUS_TCC) ? "TCC" : "-"));
985 }
986
Borislav Petkovfd0f5fff2014-02-17 20:51:52 +0100987 /* do the two bits[14:13] together */
988 ecc = (m->status >> 45) & 0x3;
989 if (ecc)
990 pr_cont("|%sECC", ((ecc == 2) ? "C" : "U"));
991
992 pr_cont("]: 0x%016llx\n", m->status);
993
994 if (m->status & MCI_STATUS_ADDRV)
Yazen Ghannam75bf2f62017-02-15 14:56:22 -0600995 pr_emerg(HW_ERR "Error Addr: 0x%016llx\n", m->addr);
Borislav Petkovfd0f5fff2014-02-17 20:51:52 +0100996
Yazen Ghannama348ed82016-05-11 14:58:28 +0200997 if (boot_cpu_has(X86_FEATURE_SMCA)) {
Yazen Ghannam75bf2f62017-02-15 14:56:22 -0600998 pr_emerg(HW_ERR "IPID: 0x%016llx", m->ipid);
999
Yazen Ghannamb300e872016-09-12 09:59:29 +02001000 if (m->status & MCI_STATUS_SYNDV)
1001 pr_cont(", Syndrome: 0x%016llx", m->synd);
1002
1003 pr_cont("\n");
1004
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +01001005 decode_smca_errors(m);
1006 goto err_code;
Yazen Ghannam75bf2f62017-02-15 14:56:22 -06001007 }
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +01001008
Borislav Petkov0bceab62017-01-23 19:35:12 +01001009 if (m->tsc)
1010 pr_emerg(HW_ERR "TSC: %llu\n", m->tsc);
1011
Borislav Petkovfd0f5fff2014-02-17 20:51:52 +01001012 if (!fam_ops)
1013 goto err_code;
1014
Borislav Petkov51966242009-07-28 13:50:43 +02001015 switch (m->bank) {
1016 case 0:
Borislav Petkovf05c41a2012-09-11 18:57:43 +02001017 decode_mc0_mce(m);
Borislav Petkov51966242009-07-28 13:50:43 +02001018 break;
Borislav Petkovd93cc222009-07-28 10:56:15 +02001019
Borislav Petkovab5535e2009-07-28 14:06:26 +02001020 case 1:
Borislav Petkovf05c41a2012-09-11 18:57:43 +02001021 decode_mc1_mce(m);
Borislav Petkovab5535e2009-07-28 14:06:26 +02001022 break;
1023
Borislav Petkov56cad2d2009-07-28 14:14:24 +02001024 case 2:
Jacob Shin4a73d3d2012-12-18 15:06:10 -06001025 decode_mc2_mce(m);
Borislav Petkov56cad2d2009-07-28 14:14:24 +02001026 break;
1027
Borislav Petkovf9350ef2009-07-28 14:17:30 +02001028 case 3:
Borislav Petkovf05c41a2012-09-11 18:57:43 +02001029 decode_mc3_mce(m);
Borislav Petkovf9350ef2009-07-28 14:17:30 +02001030 break;
1031
Borislav Petkov51966242009-07-28 13:50:43 +02001032 case 4:
Borislav Petkovf05c41a2012-09-11 18:57:43 +02001033 decode_mc4_mce(m);
Borislav Petkov51966242009-07-28 13:50:43 +02001034 break;
1035
Borislav Petkov53bd5fe2009-07-28 14:20:46 +02001036 case 5:
Borislav Petkovf05c41a2012-09-11 18:57:43 +02001037 decode_mc5_mce(m);
Borislav Petkov53bd5fe2009-07-28 14:20:46 +02001038 break;
1039
Borislav Petkovb8f85c42010-09-22 15:37:58 +02001040 case 6:
Borislav Petkovf05c41a2012-09-11 18:57:43 +02001041 decode_mc6_mce(m);
Borislav Petkovb8f85c42010-09-22 15:37:58 +02001042 break;
1043
Borislav Petkov51966242009-07-28 13:50:43 +02001044 default:
1045 break;
Borislav Petkovb69b29d2009-07-27 16:21:14 +02001046 }
Borislav Petkov51966242009-07-28 13:50:43 +02001047
Borislav Petkovfd0f5fff2014-02-17 20:51:52 +01001048 err_code:
Borislav Petkov51966242009-07-28 13:50:43 +02001049 amd_decode_err_code(m->status & 0xffff);
Borislav Petkovfb253192009-10-07 13:20:38 +02001050
1051 return NOTIFY_STOP;
Borislav Petkov549d0422009-07-24 13:51:42 +02001052}
Ingo Molnarf436f8b2009-10-01 16:14:32 +02001053
Borislav Petkovfb253192009-10-07 13:20:38 +02001054static struct notifier_block amd_mce_dec_nb = {
1055 .notifier_call = amd_decode_mce,
Borislav Petkov9026cc82017-01-23 19:35:14 +01001056 .priority = MCE_PRIO_EDAC,
Borislav Petkovfb253192009-10-07 13:20:38 +02001057};
1058
Ingo Molnarf436f8b2009-10-01 16:14:32 +02001059static int __init mce_amd_init(void)
1060{
Borislav Petkovbad11e02010-09-22 17:44:51 +02001061 struct cpuinfo_x86 *c = &boot_cpu_data;
1062
1063 if (c->x86_vendor != X86_VENDOR_AMD)
Borislav Petkovfd0f5fff2014-02-17 20:51:52 +01001064 return -ENODEV;
Borislav Petkove045c292010-08-06 18:55:45 +02001065
Borislav Petkov888ab8e2010-08-18 15:11:35 +02001066 fam_ops = kzalloc(sizeof(struct amd_decoder_ops), GFP_KERNEL);
1067 if (!fam_ops)
1068 return -ENOMEM;
1069
Borislav Petkovbad11e02010-09-22 17:44:51 +02001070 switch (c->x86) {
Borislav Petkov888ab8e2010-08-18 15:11:35 +02001071 case 0xf:
Borislav Petkovf05c41a2012-09-11 18:57:43 +02001072 fam_ops->mc0_mce = k8_mc0_mce;
1073 fam_ops->mc1_mce = k8_mc1_mce;
Jacob Shin4a73d3d2012-12-18 15:06:10 -06001074 fam_ops->mc2_mce = k8_mc2_mce;
Borislav Petkov888ab8e2010-08-18 15:11:35 +02001075 break;
1076
1077 case 0x10:
Borislav Petkovf05c41a2012-09-11 18:57:43 +02001078 fam_ops->mc0_mce = f10h_mc0_mce;
1079 fam_ops->mc1_mce = k8_mc1_mce;
Jacob Shin4a73d3d2012-12-18 15:06:10 -06001080 fam_ops->mc2_mce = k8_mc2_mce;
Borislav Petkov888ab8e2010-08-18 15:11:35 +02001081 break;
1082
Borislav Petkovf0157b32010-10-05 19:07:16 +02001083 case 0x11:
Borislav Petkovf05c41a2012-09-11 18:57:43 +02001084 fam_ops->mc0_mce = k8_mc0_mce;
1085 fam_ops->mc1_mce = k8_mc1_mce;
Jacob Shin4a73d3d2012-12-18 15:06:10 -06001086 fam_ops->mc2_mce = k8_mc2_mce;
Borislav Petkovf0157b32010-10-05 19:07:16 +02001087 break;
1088
Borislav Petkov9be0bb12010-09-16 15:08:14 +02001089 case 0x12:
Borislav Petkovf05c41a2012-09-11 18:57:43 +02001090 fam_ops->mc0_mce = f12h_mc0_mce;
1091 fam_ops->mc1_mce = k8_mc1_mce;
Jacob Shin4a73d3d2012-12-18 15:06:10 -06001092 fam_ops->mc2_mce = k8_mc2_mce;
Borislav Petkov9be0bb12010-09-16 15:08:14 +02001093 break;
1094
Borislav Petkov888ab8e2010-08-18 15:11:35 +02001095 case 0x14:
Jacob Shin980eec82012-12-18 15:06:11 -06001096 fam_ops->mc0_mce = cat_mc0_mce;
1097 fam_ops->mc1_mce = cat_mc1_mce;
Jacob Shin4a73d3d2012-12-18 15:06:10 -06001098 fam_ops->mc2_mce = k8_mc2_mce;
Borislav Petkov888ab8e2010-08-18 15:11:35 +02001099 break;
1100
Borislav Petkov2be64bf2010-09-17 19:11:47 +02001101 case 0x15:
Aravind Gopalakrishnaneba4bfb2014-07-14 16:58:19 +02001102 xec_mask = c->x86_model == 0x60 ? 0x3f : 0x1f;
1103
Borislav Petkovf05c41a2012-09-11 18:57:43 +02001104 fam_ops->mc0_mce = f15h_mc0_mce;
1105 fam_ops->mc1_mce = f15h_mc1_mce;
Jacob Shin4a73d3d2012-12-18 15:06:10 -06001106 fam_ops->mc2_mce = f15h_mc2_mce;
Borislav Petkov2be64bf2010-09-17 19:11:47 +02001107 break;
1108
Jacob Shin980eec82012-12-18 15:06:11 -06001109 case 0x16:
1110 xec_mask = 0x1f;
1111 fam_ops->mc0_mce = cat_mc0_mce;
1112 fam_ops->mc1_mce = cat_mc1_mce;
1113 fam_ops->mc2_mce = f16h_mc2_mce;
1114 break;
1115
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +01001116 case 0x17:
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +01001117 xec_mask = 0x3f;
Yazen Ghannama348ed82016-05-11 14:58:28 +02001118 if (!boot_cpu_has(X86_FEATURE_SMCA)) {
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +01001119 printk(KERN_WARNING "Decoding supported only on Scalable MCA processors.\n");
1120 goto err_out;
1121 }
1122 break;
1123
Borislav Petkov888ab8e2010-08-18 15:11:35 +02001124 default:
Borislav Petkovec3e82d2012-04-04 14:21:02 +02001125 printk(KERN_WARNING "Huh? What family is it: 0x%x?!\n", c->x86);
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +01001126 goto err_out;
Borislav Petkov888ab8e2010-08-18 15:11:35 +02001127 }
1128
Borislav Petkov9530d602010-09-06 15:05:45 +02001129 pr_info("MCE: In-kernel MCE decoding enabled.\n");
1130
Borislav Petkov3653ada2011-12-04 15:12:09 +01001131 mce_register_decode_chain(&amd_mce_dec_nb);
Ingo Molnarf436f8b2009-10-01 16:14:32 +02001132
1133 return 0;
Aravind Gopalakrishnanbe0aec22016-03-07 14:02:18 +01001134
1135err_out:
1136 kfree(fam_ops);
1137 fam_ops = NULL;
1138 return -EINVAL;
Ingo Molnarf436f8b2009-10-01 16:14:32 +02001139}
1140early_initcall(mce_amd_init);
Borislav Petkov0d18b2e2009-10-02 15:31:48 +02001141
1142#ifdef MODULE
1143static void __exit mce_amd_exit(void)
1144{
Borislav Petkov3653ada2011-12-04 15:12:09 +01001145 mce_unregister_decode_chain(&amd_mce_dec_nb);
Borislav Petkov888ab8e2010-08-18 15:11:35 +02001146 kfree(fam_ops);
Borislav Petkov0d18b2e2009-10-02 15:31:48 +02001147}
1148
1149MODULE_DESCRIPTION("AMD MCE decoder");
1150MODULE_ALIAS("edac-mce-amd");
1151MODULE_LICENSE("GPL");
1152module_exit(mce_amd_exit);
1153#endif