blob: 44e6cdaff663d2fb83852342333290202752679b [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 Thompsonb52401c2009-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 +02009static u8 nb_err_cpumask = 0xf;
10
Borislav Petkov549d0422009-07-24 13:51:42 +020011static bool report_gart_errors;
Borislav Petkov7cfd4a82010-09-01 14:45:20 +020012static void (*nb_bus_decoder)(int node_id, struct mce *m, u32 nbcfg);
Borislav Petkov549d0422009-07-24 13:51:42 +020013
14void amd_report_gart_errors(bool v)
15{
16 report_gart_errors = v;
17}
18EXPORT_SYMBOL_GPL(amd_report_gart_errors);
19
Borislav Petkov7cfd4a82010-09-01 14:45:20 +020020void amd_register_ecc_decoder(void (*f)(int, struct mce *, u32))
Borislav Petkov549d0422009-07-24 13:51:42 +020021{
22 nb_bus_decoder = f;
23}
24EXPORT_SYMBOL_GPL(amd_register_ecc_decoder);
25
Borislav Petkov7cfd4a82010-09-01 14:45:20 +020026void amd_unregister_ecc_decoder(void (*f)(int, struct mce *, u32))
Borislav Petkov549d0422009-07-24 13:51:42 +020027{
28 if (nb_bus_decoder) {
29 WARN_ON(nb_bus_decoder != f);
30
31 nb_bus_decoder = NULL;
32 }
33}
34EXPORT_SYMBOL_GPL(amd_unregister_ecc_decoder);
35
Doug Thompsonb52401c2009-05-06 17:57:20 +020036/*
37 * string representation for the different MCA reported error types, see F3x48
38 * or MSR0000_0411.
39 */
Borislav Petkov63375832010-09-06 18:13:39 +020040
41/* transaction type */
42const char *tt_msgs[] = { "INSN", "DATA", "GEN", "RESV" };
Borislav Petkovb70ef012009-06-25 19:32:38 +020043EXPORT_SYMBOL_GPL(tt_msgs);
Doug Thompsonb52401c2009-05-06 17:57:20 +020044
Borislav Petkov63375832010-09-06 18:13:39 +020045/* cache level */
46const char *ll_msgs[] = { "RESV", "L1", "L2", "L3/GEN" };
Borislav Petkovb70ef012009-06-25 19:32:38 +020047EXPORT_SYMBOL_GPL(ll_msgs);
Doug Thompsonb52401c2009-05-06 17:57:20 +020048
Borislav Petkov63375832010-09-06 18:13:39 +020049/* memory transaction type */
Doug Thompsonb52401c2009-05-06 17:57:20 +020050const char *rrrr_msgs[] = {
Borislav Petkov63375832010-09-06 18:13:39 +020051 "GEN", "RD", "WR", "DRD", "DWR", "IRD", "PRF", "EV", "SNP"
Doug Thompsonb52401c2009-05-06 17:57:20 +020052};
Borislav Petkovb70ef012009-06-25 19:32:38 +020053EXPORT_SYMBOL_GPL(rrrr_msgs);
Doug Thompsonb52401c2009-05-06 17:57:20 +020054
Borislav Petkov63375832010-09-06 18:13:39 +020055/* participating processor */
56const char *pp_msgs[] = { "SRC", "RES", "OBS", "GEN" };
Borislav Petkovb70ef012009-06-25 19:32:38 +020057EXPORT_SYMBOL_GPL(pp_msgs);
Doug Thompsonb52401c2009-05-06 17:57:20 +020058
Borislav Petkov63375832010-09-06 18:13:39 +020059/* request timeout */
60const char *to_msgs[] = { "no timeout", "timed out" };
Borislav Petkovb70ef012009-06-25 19:32:38 +020061EXPORT_SYMBOL_GPL(to_msgs);
Doug Thompsonb52401c2009-05-06 17:57:20 +020062
Borislav Petkov63375832010-09-06 18:13:39 +020063/* memory or i/o */
64const char *ii_msgs[] = { "MEM", "RESV", "IO", "GEN" };
Borislav Petkovb70ef012009-06-25 19:32:38 +020065EXPORT_SYMBOL_GPL(ii_msgs);
Doug Thompsonb52401c2009-05-06 17:57:20 +020066
Borislav Petkov5ce88f62010-08-31 18:28:08 +020067static const char *f10h_nb_mce_desc[] = {
68 "HT link data error",
69 "Protocol error (link, L3, probe filter, etc.)",
70 "Parity error in NB-internal arrays",
71 "Link Retry due to IO link transmission error",
72 "L3 ECC data cache error",
73 "ECC error in L3 cache tag",
74 "L3 LRU parity bits error",
75 "ECC Error in the Probe Filter directory"
Doug Thompsonb52401c2009-05-06 17:57:20 +020076};
Borislav Petkov549d0422009-07-24 13:51:42 +020077
Borislav Petkov86039cd2010-11-08 15:03:35 +010078static const char * const f15h_ic_mce_desc[] = {
79 "UC during a demand linefill from L2",
80 "Parity error during data load from IC",
81 "Parity error for IC valid bit",
82 "Main tag parity error",
83 "Parity error in prediction queue",
84 "PFB data/address parity error",
85 "Parity error in the branch status reg",
86 "PFB promotion address error",
87 "Tag error during probe/victimization",
88 "Parity error for IC probe tag valid bit",
89 "PFB non-cacheable bit parity error",
90 "PFB valid bit parity error", /* xec = 0xd */
91 "patch RAM", /* xec = 010 */
92 "uop queue",
93 "insn buffer",
94 "predecode buffer",
95 "fetch address FIFO"
96};
97
Borislav Petkov70fdb492010-09-21 20:45:10 +020098static const char * const f15h_cu_mce_desc[] = {
99 "Fill ECC error on data fills", /* xec = 0x4 */
100 "Fill parity error on insn fills",
101 "Prefetcher request FIFO parity error",
102 "PRQ address parity error",
103 "PRQ data parity error",
104 "WCC Tag ECC error",
105 "WCC Data ECC error",
106 "WCB Data parity error",
107 "VB Data/ECC error",
108 "L2 Tag ECC error", /* xec = 0x10 */
109 "Hard L2 Tag ECC error",
110 "Multiple hits on L2 tag",
111 "XAB parity error",
112 "PRB address parity error"
113};
114
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200115static bool f12h_dc_mce(u16 ec, u8 xec)
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200116{
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200117 bool ret = false;
118
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200119 if (MEM_ERROR(ec)) {
120 u8 ll = ec & 0x3;
121 ret = true;
122
123 if (ll == LL_L2)
124 pr_cont("during L1 linefill from L2.\n");
125 else if (ll == LL_L1)
126 pr_cont("Data/Tag %s error.\n", RRRR_MSG(ec));
127 else
128 ret = false;
129 }
130 return ret;
131}
132
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200133static bool f10h_dc_mce(u16 ec, u8 xec)
Borislav Petkov9be0bb12010-09-16 15:08:14 +0200134{
135 u8 r4 = (ec >> 4) & 0xf;
136 u8 ll = ec & 0x3;
137
138 if (r4 == R4_GEN && ll == LL_L1) {
139 pr_cont("during data scrub.\n");
140 return true;
141 }
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200142 return f12h_dc_mce(ec, xec);
Borislav Petkov9be0bb12010-09-16 15:08:14 +0200143}
144
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200145static bool k8_dc_mce(u16 ec, u8 xec)
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200146{
147 if (BUS_ERROR(ec)) {
148 pr_cont("during system linefill.\n");
149 return true;
150 }
151
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200152 return f10h_dc_mce(ec, xec);
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200153}
154
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200155static bool f14h_dc_mce(u16 ec, u8 xec)
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200156{
157 u8 r4 = (ec >> 4) & 0xf;
158 u8 ll = ec & 0x3;
159 u8 tt = (ec >> 2) & 0x3;
160 u8 ii = tt;
161 bool ret = true;
162
163 if (MEM_ERROR(ec)) {
164
165 if (tt != TT_DATA || ll != LL_L1)
166 return false;
167
168 switch (r4) {
169 case R4_DRD:
170 case R4_DWR:
171 pr_cont("Data/Tag parity error due to %s.\n",
172 (r4 == R4_DRD ? "load/hw prf" : "store"));
173 break;
174 case R4_EVICT:
175 pr_cont("Copyback parity error on a tag miss.\n");
176 break;
177 case R4_SNOOP:
178 pr_cont("Tag parity error during snoop.\n");
179 break;
180 default:
181 ret = false;
182 }
183 } else if (BUS_ERROR(ec)) {
184
185 if ((ii != II_MEM && ii != II_IO) || ll != LL_LG)
186 return false;
187
188 pr_cont("System read data error on a ");
189
190 switch (r4) {
191 case R4_RD:
192 pr_cont("TLB reload.\n");
193 break;
194 case R4_DWR:
195 pr_cont("store.\n");
196 break;
197 case R4_DRD:
198 pr_cont("load.\n");
199 break;
200 default:
201 ret = false;
202 }
203 } else {
204 ret = false;
205 }
206
207 return ret;
208}
209
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200210static bool f15h_dc_mce(u16 ec, u8 xec)
211{
212 bool ret = true;
213
214 if (MEM_ERROR(ec)) {
215
216 switch (xec) {
217 case 0x0:
218 pr_cont("Data Array access error.\n");
219 break;
220
221 case 0x1:
222 pr_cont("UC error during a linefill from L2/NB.\n");
223 break;
224
225 case 0x2:
226 case 0x11:
227 pr_cont("STQ access error.\n");
228 break;
229
230 case 0x3:
231 pr_cont("SCB access error.\n");
232 break;
233
234 case 0x10:
235 pr_cont("Tag error.\n");
236 break;
237
238 case 0x12:
239 pr_cont("LDQ access error.\n");
240 break;
241
242 default:
243 ret = false;
244 }
245 } else if (BUS_ERROR(ec)) {
246
247 if (!xec)
248 pr_cont("during system linefill.\n");
249 else
250 pr_cont(" Internal %s condition.\n",
251 ((xec == 1) ? "livelock" : "deadlock"));
252 } else
253 ret = false;
254
255 return ret;
256}
257
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200258static void amd_decode_dc_mce(struct mce *m)
Borislav Petkov51966242009-07-28 13:50:43 +0200259{
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200260 u16 ec = m->status & 0xffff;
Borislav Petkov2be64bf2010-09-17 19:11:47 +0200261 u8 xec = (m->status >> 16) & xec_mask;
Borislav Petkov51966242009-07-28 13:50:43 +0200262
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200263 pr_emerg(HW_ERR "Data Cache Error: ");
Borislav Petkov51966242009-07-28 13:50:43 +0200264
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200265 /* TLB error signatures are the same across families */
266 if (TLB_ERROR(ec)) {
267 u8 tt = (ec >> 2) & 0x3;
Borislav Petkov51966242009-07-28 13:50:43 +0200268
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200269 if (tt == TT_DATA) {
270 pr_cont("%s TLB %s.\n", LL_MSG(ec),
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200271 ((xec == 2) ? "locked miss"
272 : (xec ? "multimatch" : "parity")));
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200273 return;
274 }
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200275 } else if (fam_ops->dc_mce(ec, xec))
276 ;
277 else
278 pr_emerg(HW_ERR "Corrupted DC MCE info?\n");
Borislav Petkov51966242009-07-28 13:50:43 +0200279}
280
Borislav Petkov86039cd2010-11-08 15:03:35 +0100281static bool k8_ic_mce(u16 ec, u8 xec)
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200282{
283 u8 ll = ec & 0x3;
284 u8 r4 = (ec >> 4) & 0xf;
285 bool ret = true;
286
287 if (!MEM_ERROR(ec))
288 return false;
289
290 if (ll == 0x2)
291 pr_cont("during a linefill from L2.\n");
292 else if (ll == 0x1) {
293 switch (r4) {
294 case R4_IRD:
295 pr_cont("Parity error during data load.\n");
296 break;
297
298 case R4_EVICT:
299 pr_cont("Copyback Parity/Victim error.\n");
300 break;
301
302 case R4_SNOOP:
303 pr_cont("Tag Snoop error.\n");
304 break;
305
306 default:
307 ret = false;
308 break;
309 }
310 } else
311 ret = false;
312
313 return ret;
314}
315
Borislav Petkov86039cd2010-11-08 15:03:35 +0100316static bool f14h_ic_mce(u16 ec, u8 xec)
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200317{
318 u8 ll = ec & 0x3;
319 u8 tt = (ec >> 2) & 0x3;
320 u8 r4 = (ec >> 4) & 0xf;
321 bool ret = true;
322
323 if (MEM_ERROR(ec)) {
324 if (tt != 0 || ll != 1)
325 ret = false;
326
327 if (r4 == R4_IRD)
328 pr_cont("Data/tag array parity error for a tag hit.\n");
329 else if (r4 == R4_SNOOP)
330 pr_cont("Tag error during snoop/victimization.\n");
331 else
332 ret = false;
333 }
334 return ret;
335}
336
Borislav Petkov86039cd2010-11-08 15:03:35 +0100337static bool f15h_ic_mce(u16 ec, u8 xec)
338{
339 bool ret = true;
340
341 if (!MEM_ERROR(ec))
342 return false;
343
344 switch (xec) {
345 case 0x0 ... 0xa:
346 pr_cont("%s.\n", f15h_ic_mce_desc[xec]);
347 break;
348
349 case 0xd:
350 pr_cont("%s.\n", f15h_ic_mce_desc[xec-2]);
351 break;
352
353 case 0x10 ... 0x14:
354 pr_cont("Decoder %s parity error.\n", f15h_ic_mce_desc[xec-4]);
355 break;
356
357 default:
358 ret = false;
359 }
360 return ret;
361}
362
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200363static void amd_decode_ic_mce(struct mce *m)
Borislav Petkovab5535e2009-07-28 14:06:26 +0200364{
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200365 u16 ec = m->status & 0xffff;
Borislav Petkov2be64bf2010-09-17 19:11:47 +0200366 u8 xec = (m->status >> 16) & xec_mask;
Borislav Petkovab5535e2009-07-28 14:06:26 +0200367
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200368 pr_emerg(HW_ERR "Instruction Cache Error: ");
Borislav Petkovab5535e2009-07-28 14:06:26 +0200369
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200370 if (TLB_ERROR(ec))
371 pr_cont("%s TLB %s.\n", LL_MSG(ec),
372 (xec ? "multimatch" : "parity error"));
373 else if (BUS_ERROR(ec)) {
Borislav Petkov525906b2010-10-15 15:27:02 +0200374 bool k8 = (boot_cpu_data.x86 == 0xf && (m->status & BIT_64(58)));
Borislav Petkovab5535e2009-07-28 14:06:26 +0200375
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200376 pr_cont("during %s.\n", (k8 ? "system linefill" : "NB data read"));
Borislav Petkov86039cd2010-11-08 15:03:35 +0100377 } else if (fam_ops->ic_mce(ec, xec))
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200378 ;
379 else
380 pr_emerg(HW_ERR "Corrupted IC MCE info?\n");
Borislav Petkovab5535e2009-07-28 14:06:26 +0200381}
382
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200383static void amd_decode_bu_mce(struct mce *m)
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200384{
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200385 u32 ec = m->status & 0xffff;
Borislav Petkov2be64bf2010-09-17 19:11:47 +0200386 u32 xec = (m->status >> 16) & xec_mask;
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200387
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200388 pr_emerg(HW_ERR "Bus Unit Error");
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200389
390 if (xec == 0x1)
391 pr_cont(" in the write data buffers.\n");
392 else if (xec == 0x3)
393 pr_cont(" in the victim data buffers.\n");
394 else if (xec == 0x2 && MEM_ERROR(ec))
395 pr_cont(": %s error in the L2 cache tags.\n", RRRR_MSG(ec));
396 else if (xec == 0x0) {
397 if (TLB_ERROR(ec))
398 pr_cont(": %s error in a Page Descriptor Cache or "
399 "Guest TLB.\n", TT_MSG(ec));
400 else if (BUS_ERROR(ec))
401 pr_cont(": %s/ECC error in data read from NB: %s.\n",
402 RRRR_MSG(ec), PP_MSG(ec));
403 else if (MEM_ERROR(ec)) {
404 u8 rrrr = (ec >> 4) & 0xf;
405
406 if (rrrr >= 0x7)
407 pr_cont(": %s error during data copyback.\n",
408 RRRR_MSG(ec));
409 else if (rrrr <= 0x1)
410 pr_cont(": %s parity/ECC error during data "
411 "access from L2.\n", RRRR_MSG(ec));
412 else
413 goto wrong_bu_mce;
414 } else
415 goto wrong_bu_mce;
416 } else
417 goto wrong_bu_mce;
418
419 return;
420
421wrong_bu_mce:
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200422 pr_emerg(HW_ERR "Corrupted BU MCE info?\n");
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200423}
424
Borislav Petkov70fdb492010-09-21 20:45:10 +0200425static void amd_decode_cu_mce(struct mce *m)
426{
427 u16 ec = m->status & 0xffff;
428 u8 xec = (m->status >> 16) & xec_mask;
429
430 pr_emerg(HW_ERR "Combined Unit Error: ");
431
432 if (TLB_ERROR(ec)) {
433 if (xec == 0x0)
434 pr_cont("Data parity TLB read error.\n");
435 else if (xec == 0x1)
436 pr_cont("Poison data provided for TLB fill.\n");
437 else
438 goto wrong_cu_mce;
439 } else if (BUS_ERROR(ec)) {
440 if (xec > 2)
441 goto wrong_cu_mce;
442
443 pr_cont("Error during attempted NB data read.\n");
444 } else if (MEM_ERROR(ec)) {
445 switch (xec) {
446 case 0x4 ... 0xc:
447 pr_cont("%s.\n", f15h_cu_mce_desc[xec - 0x4]);
448 break;
449
450 case 0x10 ... 0x14:
451 pr_cont("%s.\n", f15h_cu_mce_desc[xec - 0x7]);
452 break;
453
454 default:
455 goto wrong_cu_mce;
456 }
457 }
458
459 return;
460
461wrong_cu_mce:
462 pr_emerg(HW_ERR "Corrupted CU MCE info?\n");
463}
464
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200465static void amd_decode_ls_mce(struct mce *m)
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200466{
Borislav Petkovded50622010-08-27 17:03:34 +0200467 u16 ec = m->status & 0xffff;
Borislav Petkov2be64bf2010-09-17 19:11:47 +0200468 u8 xec = (m->status >> 16) & xec_mask;
Borislav Petkovded50622010-08-27 17:03:34 +0200469
Borislav Petkovb18434c2010-09-22 11:53:32 +0200470 if (boot_cpu_data.x86 >= 0x14) {
Borislav Petkovded50622010-08-27 17:03:34 +0200471 pr_emerg("You shouldn't be seeing an LS MCE on this cpu family,"
472 " please report on LKML.\n");
473 return;
474 }
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200475
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200476 pr_emerg(HW_ERR "Load Store Error");
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200477
478 if (xec == 0x0) {
Borislav Petkovded50622010-08-27 17:03:34 +0200479 u8 r4 = (ec >> 4) & 0xf;
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200480
Borislav Petkovded50622010-08-27 17:03:34 +0200481 if (!BUS_ERROR(ec) || (r4 != R4_DRD && r4 != R4_DWR))
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200482 goto wrong_ls_mce;
483
484 pr_cont(" during %s.\n", RRRR_MSG(ec));
Borislav Petkovded50622010-08-27 17:03:34 +0200485 } else
486 goto wrong_ls_mce;
487
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200488 return;
489
490wrong_ls_mce:
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200491 pr_emerg(HW_ERR "Corrupted LS MCE info?\n");
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200492}
493
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200494static bool k8_nb_mce(u16 ec, u8 xec)
495{
496 bool ret = true;
497
498 switch (xec) {
499 case 0x1:
500 pr_cont("CRC error detected on HT link.\n");
501 break;
502
503 case 0x5:
504 pr_cont("Invalid GART PTE entry during GART table walk.\n");
505 break;
506
507 case 0x6:
508 pr_cont("Unsupported atomic RMW received from an IO link.\n");
509 break;
510
511 case 0x0:
512 case 0x8:
Borislav Petkovf0157b32010-10-05 19:07:16 +0200513 if (boot_cpu_data.x86 == 0x11)
514 return false;
515
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200516 pr_cont("DRAM ECC error detected on the NB.\n");
517 break;
518
519 case 0xd:
520 pr_cont("Parity error on the DRAM addr/ctl signals.\n");
521 break;
522
523 default:
524 ret = false;
525 break;
526 }
527
528 return ret;
529}
530
531static bool f10h_nb_mce(u16 ec, u8 xec)
532{
533 bool ret = true;
534 u8 offset = 0;
535
536 if (k8_nb_mce(ec, xec))
537 return true;
538
539 switch(xec) {
540 case 0xa ... 0xc:
541 offset = 10;
542 break;
543
544 case 0xe:
545 offset = 11;
546 break;
547
548 case 0xf:
549 if (TLB_ERROR(ec))
550 pr_cont("GART Table Walk data error.\n");
551 else if (BUS_ERROR(ec))
552 pr_cont("DMA Exclusion Vector Table Walk error.\n");
553 else
554 ret = false;
555
556 goto out;
557 break;
558
559 case 0x1c ... 0x1f:
560 offset = 24;
561 break;
562
563 default:
564 ret = false;
565
566 goto out;
567 break;
568 }
569
570 pr_cont("%s.\n", f10h_nb_mce_desc[xec - offset]);
571
572out:
573 return ret;
574}
575
Borislav Petkovcb9d5ec2010-09-16 17:36:12 +0200576static bool nb_noop_mce(u16 ec, u8 xec)
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200577{
578 return false;
579}
580
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200581void amd_decode_nb_mce(int node_id, struct mce *m, u32 nbcfg)
Borislav Petkov549d0422009-07-24 13:51:42 +0200582{
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200583 u8 xec = (m->status >> 16) & 0x1f;
584 u16 ec = m->status & 0xffff;
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200585 u32 nbsh = (u32)(m->status >> 32);
Borislav Petkov549d0422009-07-24 13:51:42 +0200586
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200587 pr_emerg(HW_ERR "Northbridge Error, node %d: ", node_id);
Borislav Petkov549d0422009-07-24 13:51:42 +0200588
589 /*
590 * F10h, revD can disable ErrCpu[3:0] so check that first and also the
591 * value encoding has changed so interpret those differently
592 */
593 if ((boot_cpu_data.x86 == 0x10) &&
Borislav Petkovcec79242009-10-27 19:12:02 +0100594 (boot_cpu_data.x86_model > 7)) {
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200595 if (nbsh & K8_NBSH_ERR_CPU_VAL)
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200596 pr_cont(", core: %u", (u8)(nbsh & nb_err_cpumask));
Borislav Petkov549d0422009-07-24 13:51:42 +0200597 } else {
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200598 u8 assoc_cpus = nbsh & nb_err_cpumask;
Borislav Petkov5b89d2f2010-03-09 20:38:48 +0100599
600 if (assoc_cpus > 0)
601 pr_cont(", core: %d", fls(assoc_cpus) - 1);
Borislav Petkov549d0422009-07-24 13:51:42 +0200602 }
603
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200604 switch (xec) {
605 case 0x2:
606 pr_cont("Sync error (sync packets on HT link detected).\n");
607 return;
Borislav Petkovd93cc222009-07-28 10:56:15 +0200608
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200609 case 0x3:
610 pr_cont("HT Master abort.\n");
611 return;
612
613 case 0x4:
614 pr_cont("HT Target abort.\n");
615 return;
616
617 case 0x7:
618 pr_cont("NB Watchdog timeout.\n");
619 return;
620
621 case 0x9:
622 pr_cont("SVM DMA Exclusion Vector error.\n");
623 return;
624
625 default:
626 break;
627 }
628
629 if (!fam_ops->nb_mce(ec, xec))
630 goto wrong_nb_mce;
631
632 if (boot_cpu_data.x86 == 0xf || boot_cpu_data.x86 == 0x10)
633 if ((xec == 0x8 || xec == 0x0) && nb_bus_decoder)
634 nb_bus_decoder(node_id, m, nbcfg);
635
636 return;
637
638wrong_nb_mce:
639 pr_emerg(HW_ERR "Corrupted NB MCE info?\n");
Borislav Petkovd93cc222009-07-28 10:56:15 +0200640}
641EXPORT_SYMBOL_GPL(amd_decode_nb_mce);
642
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200643static void amd_decode_fr_mce(struct mce *m)
Borislav Petkov53bd5fe2009-07-28 14:20:46 +0200644{
Borislav Petkovf0157b32010-10-05 19:07:16 +0200645 if (boot_cpu_data.x86 == 0xf ||
646 boot_cpu_data.x86 == 0x11)
Borislav Petkovfe4ea262010-08-31 18:38:24 +0200647 goto wrong_fr_mce;
648
Borislav Petkov53bd5fe2009-07-28 14:20:46 +0200649 /* we have only one error signature so match all fields at once. */
Borislav Petkovfe4ea262010-08-31 18:38:24 +0200650 if ((m->status & 0xffff) == 0x0f0f) {
651 pr_emerg(HW_ERR "FR Error: CPU Watchdog timer expire.\n");
652 return;
653 }
654
655wrong_fr_mce:
656 pr_emerg(HW_ERR "Corrupted FR MCE info?\n");
Borislav Petkov53bd5fe2009-07-28 14:20:46 +0200657}
658
Borislav Petkov63375832010-09-06 18:13:39 +0200659static inline void amd_decode_err_code(u16 ec)
Borislav Petkovd93cc222009-07-28 10:56:15 +0200660{
Borislav Petkov549d0422009-07-24 13:51:42 +0200661 if (TLB_ERROR(ec)) {
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200662 pr_emerg(HW_ERR "Transaction: %s, Cache Level: %s\n",
Borislav Petkov549d0422009-07-24 13:51:42 +0200663 TT_MSG(ec), LL_MSG(ec));
664 } else if (MEM_ERROR(ec)) {
Borislav Petkov63375832010-09-06 18:13:39 +0200665 pr_emerg(HW_ERR "Transaction: %s, Type: %s, Cache Level: %s\n",
Borislav Petkov549d0422009-07-24 13:51:42 +0200666 RRRR_MSG(ec), TT_MSG(ec), LL_MSG(ec));
667 } else if (BUS_ERROR(ec)) {
Borislav Petkov63375832010-09-06 18:13:39 +0200668 pr_emerg(HW_ERR "Transaction: %s (%s), %s, Cache Level: %s, "
Borislav Petkovd93cc222009-07-28 10:56:15 +0200669 "Participating Processor: %s\n",
670 RRRR_MSG(ec), II_MSG(ec), TO_MSG(ec), LL_MSG(ec),
671 PP_MSG(ec));
672 } else
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200673 pr_emerg(HW_ERR "Huh? Unknown MCE error 0x%x\n", ec);
Borislav Petkov549d0422009-07-24 13:51:42 +0200674}
Borislav Petkov549d0422009-07-24 13:51:42 +0200675
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200676/*
677 * Filter out unwanted MCE signatures here.
678 */
679static bool amd_filter_mce(struct mce *m)
680{
681 u8 xec = (m->status >> 16) & 0x1f;
682
683 /*
684 * NB GART TLB error reporting is disabled by default.
685 */
686 if (m->bank == 4 && xec == 0x5 && !report_gart_errors)
687 return true;
688
689 return false;
690}
691
Borislav Petkov9cdeb402010-09-02 18:33:24 +0200692int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
Borislav Petkov549d0422009-07-24 13:51:42 +0200693{
Borislav Petkovfb253192009-10-07 13:20:38 +0200694 struct mce *m = (struct mce *)data;
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200695 int node, ecc;
Borislav Petkov549d0422009-07-24 13:51:42 +0200696
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200697 if (amd_filter_mce(m))
698 return NOTIFY_STOP;
699
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200700 pr_emerg(HW_ERR "MC%d_STATUS: ", m->bank);
Borislav Petkov549d0422009-07-24 13:51:42 +0200701
Borislav Petkov37b73702010-08-24 18:21:42 +0200702 pr_cont("%sorrected error, other errors lost: %s, "
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200703 "CPU context corrupt: %s",
704 ((m->status & MCI_STATUS_UC) ? "Unc" : "C"),
Borislav Petkov37b73702010-08-24 18:21:42 +0200705 ((m->status & MCI_STATUS_OVER) ? "yes" : "no"),
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200706 ((m->status & MCI_STATUS_PCC) ? "yes" : "no"));
Borislav Petkov549d0422009-07-24 13:51:42 +0200707
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200708 /* do the two bits[14:13] together */
Borislav Petkov35d824b2010-04-30 15:19:02 +0200709 ecc = (m->status >> 45) & 0x3;
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200710 if (ecc)
711 pr_cont(", %sECC Error", ((ecc == 2) ? "C" : "U"));
712
713 pr_cont("\n");
714
Borislav Petkov51966242009-07-28 13:50:43 +0200715 switch (m->bank) {
716 case 0:
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200717 amd_decode_dc_mce(m);
Borislav Petkov51966242009-07-28 13:50:43 +0200718 break;
Borislav Petkovd93cc222009-07-28 10:56:15 +0200719
Borislav Petkovab5535e2009-07-28 14:06:26 +0200720 case 1:
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200721 amd_decode_ic_mce(m);
Borislav Petkovab5535e2009-07-28 14:06:26 +0200722 break;
723
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200724 case 2:
Borislav Petkov70fdb492010-09-21 20:45:10 +0200725 if (boot_cpu_data.x86 == 0x15)
726 amd_decode_cu_mce(m);
727 else
728 amd_decode_bu_mce(m);
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200729 break;
730
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200731 case 3:
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200732 amd_decode_ls_mce(m);
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200733 break;
734
Borislav Petkov51966242009-07-28 13:50:43 +0200735 case 4:
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200736 node = amd_get_nb_id(m->extcpu);
737 amd_decode_nb_mce(node, m, 0);
Borislav Petkov51966242009-07-28 13:50:43 +0200738 break;
739
Borislav Petkov53bd5fe2009-07-28 14:20:46 +0200740 case 5:
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200741 amd_decode_fr_mce(m);
Borislav Petkov53bd5fe2009-07-28 14:20:46 +0200742 break;
743
Borislav Petkov51966242009-07-28 13:50:43 +0200744 default:
745 break;
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200746 }
Borislav Petkov51966242009-07-28 13:50:43 +0200747
748 amd_decode_err_code(m->status & 0xffff);
Borislav Petkovfb253192009-10-07 13:20:38 +0200749
750 return NOTIFY_STOP;
Borislav Petkov549d0422009-07-24 13:51:42 +0200751}
Borislav Petkov9cdeb402010-09-02 18:33:24 +0200752EXPORT_SYMBOL_GPL(amd_decode_mce);
Ingo Molnarf436f8b2009-10-01 16:14:32 +0200753
Borislav Petkovfb253192009-10-07 13:20:38 +0200754static struct notifier_block amd_mce_dec_nb = {
755 .notifier_call = amd_decode_mce,
756};
757
Ingo Molnarf436f8b2009-10-01 16:14:32 +0200758static int __init mce_amd_init(void)
759{
Borislav Petkove045c292010-08-06 18:55:45 +0200760 if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
761 return 0;
762
Borislav Petkovfda75612010-09-22 16:12:03 +0200763 if ((boot_cpu_data.x86 < 0xf || boot_cpu_data.x86 > 0x12) &&
Borislav Petkov9530d602010-09-06 15:05:45 +0200764 (boot_cpu_data.x86 != 0x14 || boot_cpu_data.x86_model > 0xf))
Borislav Petkove045c292010-08-06 18:55:45 +0200765 return 0;
766
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200767 fam_ops = kzalloc(sizeof(struct amd_decoder_ops), GFP_KERNEL);
768 if (!fam_ops)
769 return -ENOMEM;
770
771 switch (boot_cpu_data.x86) {
772 case 0xf:
773 fam_ops->dc_mce = k8_dc_mce;
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200774 fam_ops->ic_mce = k8_ic_mce;
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200775 fam_ops->nb_mce = k8_nb_mce;
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200776 break;
777
778 case 0x10:
779 fam_ops->dc_mce = f10h_dc_mce;
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200780 fam_ops->ic_mce = k8_ic_mce;
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200781 fam_ops->nb_mce = f10h_nb_mce;
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200782 break;
783
Borislav Petkovf0157b32010-10-05 19:07:16 +0200784 case 0x11:
785 fam_ops->dc_mce = k8_dc_mce;
786 fam_ops->ic_mce = k8_ic_mce;
787 fam_ops->nb_mce = f10h_nb_mce;
788 break;
789
Borislav Petkov9be0bb12010-09-16 15:08:14 +0200790 case 0x12:
791 fam_ops->dc_mce = f12h_dc_mce;
Borislav Petkove7281eb2010-09-16 16:45:22 +0200792 fam_ops->ic_mce = k8_ic_mce;
Borislav Petkovcb9d5ec2010-09-16 17:36:12 +0200793 fam_ops->nb_mce = nb_noop_mce;
Borislav Petkov9be0bb12010-09-16 15:08:14 +0200794 break;
795
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200796 case 0x14:
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200797 nb_err_cpumask = 0x3;
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200798 fam_ops->dc_mce = f14h_dc_mce;
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200799 fam_ops->ic_mce = f14h_ic_mce;
Borislav Petkovcb9d5ec2010-09-16 17:36:12 +0200800 fam_ops->nb_mce = nb_noop_mce;
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200801 break;
802
Borislav Petkov2be64bf2010-09-17 19:11:47 +0200803 case 0x15:
804 xec_mask = 0x1f;
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200805 fam_ops->dc_mce = f15h_dc_mce;
Borislav Petkov86039cd2010-11-08 15:03:35 +0100806 fam_ops->ic_mce = f15h_ic_mce;
Borislav Petkov2be64bf2010-09-17 19:11:47 +0200807 break;
808
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200809 default:
810 printk(KERN_WARNING "Huh? What family is that: %d?!\n",
811 boot_cpu_data.x86);
812 kfree(fam_ops);
813 return -EINVAL;
814 }
815
Borislav Petkov9530d602010-09-06 15:05:45 +0200816 pr_info("MCE: In-kernel MCE decoding enabled.\n");
817
Borislav Petkove045c292010-08-06 18:55:45 +0200818 atomic_notifier_chain_register(&x86_mce_decoder_chain, &amd_mce_dec_nb);
Ingo Molnarf436f8b2009-10-01 16:14:32 +0200819
820 return 0;
821}
822early_initcall(mce_amd_init);
Borislav Petkov0d18b2e2009-10-02 15:31:48 +0200823
824#ifdef MODULE
825static void __exit mce_amd_exit(void)
826{
Borislav Petkovfb253192009-10-07 13:20:38 +0200827 atomic_notifier_chain_unregister(&x86_mce_decoder_chain, &amd_mce_dec_nb);
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200828 kfree(fam_ops);
Borislav Petkov0d18b2e2009-10-02 15:31:48 +0200829}
830
831MODULE_DESCRIPTION("AMD MCE decoder");
832MODULE_ALIAS("edac-mce-amd");
833MODULE_LICENSE("GPL");
834module_exit(mce_amd_exit);
835#endif