blob: 0ee1c0a115a2bf8fce553e4215118b6ad0186005 [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 +02009static u8 nb_err_cpumask = 0xf;
10
Borislav Petkov549d0422009-07-24 13:51:42 +020011static bool report_gart_errors;
Borislav Petkovb0b07a22011-08-24 18:44:22 +020012static void (*nb_bus_decoder)(int node_id, struct mce *m);
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 Petkovb0b07a22011-08-24 18:44:22 +020020void amd_register_ecc_decoder(void (*f)(int, struct mce *))
Borislav Petkov549d0422009-07-24 13:51:42 +020021{
22 nb_bus_decoder = f;
23}
24EXPORT_SYMBOL_GPL(amd_register_ecc_decoder);
25
Borislav Petkovb0b07a22011-08-24 18:44:22 +020026void amd_unregister_ecc_decoder(void (*f)(int, struct mce *))
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 Thompsonb52401ce2009-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 Thompsonb52401ce2009-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 Thompsonb52401ce2009-05-06 17:57:20 +020048
Borislav Petkov63375832010-09-06 18:13:39 +020049/* memory transaction type */
Doug Thompsonb52401ce2009-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 Thompsonb52401ce2009-05-06 17:57:20 +020052};
Borislav Petkovb70ef012009-06-25 19:32:38 +020053EXPORT_SYMBOL_GPL(rrrr_msgs);
Doug Thompsonb52401ce2009-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 Thompsonb52401ce2009-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 Thompsonb52401ce2009-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 Thompsonb52401ce2009-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 Thompsonb52401ce2009-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 Petkov8259a7e2010-09-22 15:28:59 +0200115static const char * const fr_ex_mce_desc[] = {
116 "CPU Watchdog timer expire",
117 "Wakeup array dest tag",
118 "AG payload array",
119 "EX payload array",
120 "IDRF array",
121 "Retire dispatch queue",
122 "Mapper checkpoint array",
123 "Physical register file EX0 port",
124 "Physical register file EX1 port",
125 "Physical register file AG0 port",
126 "Physical register file AG1 port",
127 "Flag register file",
128 "DE correctable error could not be corrected"
129};
130
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200131static bool f12h_dc_mce(u16 ec, u8 xec)
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200132{
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200133 bool ret = false;
134
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200135 if (MEM_ERROR(ec)) {
Borislav Petkov62452882010-09-22 16:08:37 +0200136 u8 ll = LL(ec);
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200137 ret = true;
138
139 if (ll == LL_L2)
140 pr_cont("during L1 linefill from L2.\n");
141 else if (ll == LL_L1)
Borislav Petkov62452882010-09-22 16:08:37 +0200142 pr_cont("Data/Tag %s error.\n", R4_MSG(ec));
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200143 else
144 ret = false;
145 }
146 return ret;
147}
148
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200149static bool f10h_dc_mce(u16 ec, u8 xec)
Borislav Petkov9be0bb12010-09-16 15:08:14 +0200150{
Borislav Petkov62452882010-09-22 16:08:37 +0200151 if (R4(ec) == R4_GEN && LL(ec) == LL_L1) {
Borislav Petkov9be0bb12010-09-16 15:08:14 +0200152 pr_cont("during data scrub.\n");
153 return true;
154 }
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200155 return f12h_dc_mce(ec, xec);
Borislav Petkov9be0bb12010-09-16 15:08:14 +0200156}
157
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200158static bool k8_dc_mce(u16 ec, u8 xec)
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200159{
160 if (BUS_ERROR(ec)) {
161 pr_cont("during system linefill.\n");
162 return true;
163 }
164
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200165 return f10h_dc_mce(ec, xec);
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200166}
167
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200168static bool f14h_dc_mce(u16 ec, u8 xec)
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200169{
Borislav Petkov62452882010-09-22 16:08:37 +0200170 u8 r4 = R4(ec);
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200171 bool ret = true;
172
173 if (MEM_ERROR(ec)) {
174
Borislav Petkov62452882010-09-22 16:08:37 +0200175 if (TT(ec) != TT_DATA || LL(ec) != LL_L1)
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200176 return false;
177
178 switch (r4) {
179 case R4_DRD:
180 case R4_DWR:
181 pr_cont("Data/Tag parity error due to %s.\n",
182 (r4 == R4_DRD ? "load/hw prf" : "store"));
183 break;
184 case R4_EVICT:
185 pr_cont("Copyback parity error on a tag miss.\n");
186 break;
187 case R4_SNOOP:
188 pr_cont("Tag parity error during snoop.\n");
189 break;
190 default:
191 ret = false;
192 }
193 } else if (BUS_ERROR(ec)) {
194
Borislav Petkov62452882010-09-22 16:08:37 +0200195 if ((II(ec) != II_MEM && II(ec) != II_IO) || LL(ec) != LL_LG)
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200196 return false;
197
198 pr_cont("System read data error on a ");
199
200 switch (r4) {
201 case R4_RD:
202 pr_cont("TLB reload.\n");
203 break;
204 case R4_DWR:
205 pr_cont("store.\n");
206 break;
207 case R4_DRD:
208 pr_cont("load.\n");
209 break;
210 default:
211 ret = false;
212 }
213 } else {
214 ret = false;
215 }
216
217 return ret;
218}
219
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200220static bool f15h_dc_mce(u16 ec, u8 xec)
221{
222 bool ret = true;
223
224 if (MEM_ERROR(ec)) {
225
226 switch (xec) {
227 case 0x0:
228 pr_cont("Data Array access error.\n");
229 break;
230
231 case 0x1:
232 pr_cont("UC error during a linefill from L2/NB.\n");
233 break;
234
235 case 0x2:
236 case 0x11:
237 pr_cont("STQ access error.\n");
238 break;
239
240 case 0x3:
241 pr_cont("SCB access error.\n");
242 break;
243
244 case 0x10:
245 pr_cont("Tag error.\n");
246 break;
247
248 case 0x12:
249 pr_cont("LDQ access error.\n");
250 break;
251
252 default:
253 ret = false;
254 }
255 } else if (BUS_ERROR(ec)) {
256
257 if (!xec)
Borislav Petkov344f0a02011-11-15 17:10:58 +0100258 pr_cont("System Read Data Error.\n");
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200259 else
Borislav Petkov344f0a02011-11-15 17:10:58 +0100260 pr_cont(" Internal error condition type %d.\n", xec);
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200261 } else
262 ret = false;
263
264 return ret;
265}
266
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200267static void amd_decode_dc_mce(struct mce *m)
Borislav Petkov51966242009-07-28 13:50:43 +0200268{
Borislav Petkov62452882010-09-22 16:08:37 +0200269 u16 ec = EC(m->status);
270 u8 xec = XEC(m->status, xec_mask);
Borislav Petkov51966242009-07-28 13:50:43 +0200271
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200272 pr_emerg(HW_ERR "Data Cache Error: ");
Borislav Petkov51966242009-07-28 13:50:43 +0200273
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200274 /* TLB error signatures are the same across families */
275 if (TLB_ERROR(ec)) {
Borislav Petkov62452882010-09-22 16:08:37 +0200276 if (TT(ec) == TT_DATA) {
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200277 pr_cont("%s TLB %s.\n", LL_MSG(ec),
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200278 ((xec == 2) ? "locked miss"
279 : (xec ? "multimatch" : "parity")));
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200280 return;
281 }
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200282 } else if (fam_ops->dc_mce(ec, xec))
283 ;
284 else
285 pr_emerg(HW_ERR "Corrupted DC MCE info?\n");
Borislav Petkov51966242009-07-28 13:50:43 +0200286}
287
Borislav Petkov86039cd2010-11-08 15:03:35 +0100288static bool k8_ic_mce(u16 ec, u8 xec)
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200289{
Borislav Petkov62452882010-09-22 16:08:37 +0200290 u8 ll = LL(ec);
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200291 bool ret = true;
292
293 if (!MEM_ERROR(ec))
294 return false;
295
296 if (ll == 0x2)
297 pr_cont("during a linefill from L2.\n");
298 else if (ll == 0x1) {
Borislav Petkov62452882010-09-22 16:08:37 +0200299 switch (R4(ec)) {
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200300 case R4_IRD:
301 pr_cont("Parity error during data load.\n");
302 break;
303
304 case R4_EVICT:
305 pr_cont("Copyback Parity/Victim error.\n");
306 break;
307
308 case R4_SNOOP:
309 pr_cont("Tag Snoop error.\n");
310 break;
311
312 default:
313 ret = false;
314 break;
315 }
316 } else
317 ret = false;
318
319 return ret;
320}
321
Borislav Petkov86039cd2010-11-08 15:03:35 +0100322static bool f14h_ic_mce(u16 ec, u8 xec)
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200323{
Borislav Petkov62452882010-09-22 16:08:37 +0200324 u8 r4 = R4(ec);
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200325 bool ret = true;
326
327 if (MEM_ERROR(ec)) {
Borislav Petkov62452882010-09-22 16:08:37 +0200328 if (TT(ec) != 0 || LL(ec) != 1)
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200329 ret = false;
330
331 if (r4 == R4_IRD)
332 pr_cont("Data/tag array parity error for a tag hit.\n");
333 else if (r4 == R4_SNOOP)
334 pr_cont("Tag error during snoop/victimization.\n");
335 else
336 ret = false;
337 }
338 return ret;
339}
340
Borislav Petkov86039cd2010-11-08 15:03:35 +0100341static bool f15h_ic_mce(u16 ec, u8 xec)
342{
343 bool ret = true;
344
345 if (!MEM_ERROR(ec))
346 return false;
347
348 switch (xec) {
349 case 0x0 ... 0xa:
350 pr_cont("%s.\n", f15h_ic_mce_desc[xec]);
351 break;
352
353 case 0xd:
354 pr_cont("%s.\n", f15h_ic_mce_desc[xec-2]);
355 break;
356
357 case 0x10 ... 0x14:
358 pr_cont("Decoder %s parity error.\n", f15h_ic_mce_desc[xec-4]);
359 break;
360
361 default:
362 ret = false;
363 }
364 return ret;
365}
366
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200367static void amd_decode_ic_mce(struct mce *m)
Borislav Petkovab5535e2009-07-28 14:06:26 +0200368{
Borislav Petkov62452882010-09-22 16:08:37 +0200369 u16 ec = EC(m->status);
370 u8 xec = XEC(m->status, xec_mask);
Borislav Petkovab5535e2009-07-28 14:06:26 +0200371
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200372 pr_emerg(HW_ERR "Instruction Cache Error: ");
Borislav Petkovab5535e2009-07-28 14:06:26 +0200373
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200374 if (TLB_ERROR(ec))
375 pr_cont("%s TLB %s.\n", LL_MSG(ec),
376 (xec ? "multimatch" : "parity error"));
377 else if (BUS_ERROR(ec)) {
Borislav Petkov525906b2010-10-15 15:27:02 +0200378 bool k8 = (boot_cpu_data.x86 == 0xf && (m->status & BIT_64(58)));
Borislav Petkovab5535e2009-07-28 14:06:26 +0200379
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200380 pr_cont("during %s.\n", (k8 ? "system linefill" : "NB data read"));
Borislav Petkov86039cd2010-11-08 15:03:35 +0100381 } else if (fam_ops->ic_mce(ec, xec))
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200382 ;
383 else
384 pr_emerg(HW_ERR "Corrupted IC MCE info?\n");
Borislav Petkovab5535e2009-07-28 14:06:26 +0200385}
386
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200387static void amd_decode_bu_mce(struct mce *m)
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200388{
Borislav Petkov62452882010-09-22 16:08:37 +0200389 u16 ec = EC(m->status);
390 u8 xec = XEC(m->status, xec_mask);
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200391
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200392 pr_emerg(HW_ERR "Bus Unit Error");
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200393
394 if (xec == 0x1)
395 pr_cont(" in the write data buffers.\n");
396 else if (xec == 0x3)
397 pr_cont(" in the victim data buffers.\n");
398 else if (xec == 0x2 && MEM_ERROR(ec))
Borislav Petkov62452882010-09-22 16:08:37 +0200399 pr_cont(": %s error in the L2 cache tags.\n", R4_MSG(ec));
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200400 else if (xec == 0x0) {
401 if (TLB_ERROR(ec))
402 pr_cont(": %s error in a Page Descriptor Cache or "
403 "Guest TLB.\n", TT_MSG(ec));
404 else if (BUS_ERROR(ec))
405 pr_cont(": %s/ECC error in data read from NB: %s.\n",
Borislav Petkov62452882010-09-22 16:08:37 +0200406 R4_MSG(ec), PP_MSG(ec));
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200407 else if (MEM_ERROR(ec)) {
Borislav Petkov62452882010-09-22 16:08:37 +0200408 u8 r4 = R4(ec);
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200409
Borislav Petkov62452882010-09-22 16:08:37 +0200410 if (r4 >= 0x7)
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200411 pr_cont(": %s error during data copyback.\n",
Borislav Petkov62452882010-09-22 16:08:37 +0200412 R4_MSG(ec));
413 else if (r4 <= 0x1)
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200414 pr_cont(": %s parity/ECC error during data "
Borislav Petkov62452882010-09-22 16:08:37 +0200415 "access from L2.\n", R4_MSG(ec));
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200416 else
417 goto wrong_bu_mce;
418 } else
419 goto wrong_bu_mce;
420 } else
421 goto wrong_bu_mce;
422
423 return;
424
425wrong_bu_mce:
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200426 pr_emerg(HW_ERR "Corrupted BU MCE info?\n");
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200427}
428
Borislav Petkov70fdb492010-09-21 20:45:10 +0200429static void amd_decode_cu_mce(struct mce *m)
430{
Borislav Petkov62452882010-09-22 16:08:37 +0200431 u16 ec = EC(m->status);
432 u8 xec = XEC(m->status, xec_mask);
Borislav Petkov70fdb492010-09-21 20:45:10 +0200433
434 pr_emerg(HW_ERR "Combined Unit Error: ");
435
436 if (TLB_ERROR(ec)) {
437 if (xec == 0x0)
438 pr_cont("Data parity TLB read error.\n");
439 else if (xec == 0x1)
440 pr_cont("Poison data provided for TLB fill.\n");
441 else
442 goto wrong_cu_mce;
443 } else if (BUS_ERROR(ec)) {
444 if (xec > 2)
445 goto wrong_cu_mce;
446
447 pr_cont("Error during attempted NB data read.\n");
448 } else if (MEM_ERROR(ec)) {
449 switch (xec) {
450 case 0x4 ... 0xc:
451 pr_cont("%s.\n", f15h_cu_mce_desc[xec - 0x4]);
452 break;
453
454 case 0x10 ... 0x14:
455 pr_cont("%s.\n", f15h_cu_mce_desc[xec - 0x7]);
456 break;
457
458 default:
459 goto wrong_cu_mce;
460 }
461 }
462
463 return;
464
465wrong_cu_mce:
466 pr_emerg(HW_ERR "Corrupted CU MCE info?\n");
467}
468
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200469static void amd_decode_ls_mce(struct mce *m)
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200470{
Borislav Petkov62452882010-09-22 16:08:37 +0200471 u16 ec = EC(m->status);
472 u8 xec = XEC(m->status, xec_mask);
Borislav Petkovded50622010-08-27 17:03:34 +0200473
Borislav Petkovb18434c2010-09-22 11:53:32 +0200474 if (boot_cpu_data.x86 >= 0x14) {
Borislav Petkovded50622010-08-27 17:03:34 +0200475 pr_emerg("You shouldn't be seeing an LS MCE on this cpu family,"
476 " please report on LKML.\n");
477 return;
478 }
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200479
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200480 pr_emerg(HW_ERR "Load Store Error");
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200481
482 if (xec == 0x0) {
Borislav Petkov62452882010-09-22 16:08:37 +0200483 u8 r4 = R4(ec);
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200484
Borislav Petkovded50622010-08-27 17:03:34 +0200485 if (!BUS_ERROR(ec) || (r4 != R4_DRD && r4 != R4_DWR))
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200486 goto wrong_ls_mce;
487
Borislav Petkov62452882010-09-22 16:08:37 +0200488 pr_cont(" during %s.\n", R4_MSG(ec));
Borislav Petkovded50622010-08-27 17:03:34 +0200489 } else
490 goto wrong_ls_mce;
491
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200492 return;
493
494wrong_ls_mce:
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200495 pr_emerg(HW_ERR "Corrupted LS MCE info?\n");
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200496}
497
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200498static bool k8_nb_mce(u16 ec, u8 xec)
499{
500 bool ret = true;
501
502 switch (xec) {
503 case 0x1:
504 pr_cont("CRC error detected on HT link.\n");
505 break;
506
507 case 0x5:
508 pr_cont("Invalid GART PTE entry during GART table walk.\n");
509 break;
510
511 case 0x6:
512 pr_cont("Unsupported atomic RMW received from an IO link.\n");
513 break;
514
515 case 0x0:
516 case 0x8:
Borislav Petkovf0157b32010-10-05 19:07:16 +0200517 if (boot_cpu_data.x86 == 0x11)
518 return false;
519
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200520 pr_cont("DRAM ECC error detected on the NB.\n");
521 break;
522
523 case 0xd:
524 pr_cont("Parity error on the DRAM addr/ctl signals.\n");
525 break;
526
527 default:
528 ret = false;
529 break;
530 }
531
532 return ret;
533}
534
535static bool f10h_nb_mce(u16 ec, u8 xec)
536{
537 bool ret = true;
538 u8 offset = 0;
539
540 if (k8_nb_mce(ec, xec))
541 return true;
542
543 switch(xec) {
544 case 0xa ... 0xc:
545 offset = 10;
546 break;
547
548 case 0xe:
549 offset = 11;
550 break;
551
552 case 0xf:
553 if (TLB_ERROR(ec))
554 pr_cont("GART Table Walk data error.\n");
555 else if (BUS_ERROR(ec))
556 pr_cont("DMA Exclusion Vector Table Walk error.\n");
557 else
558 ret = false;
559
560 goto out;
561 break;
562
Borislav Petkov05cd6672010-09-22 15:06:24 +0200563 case 0x19:
564 if (boot_cpu_data.x86 == 0x15)
565 pr_cont("Compute Unit Data Error.\n");
566 else
567 ret = false;
568
569 goto out;
570 break;
571
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200572 case 0x1c ... 0x1f:
573 offset = 24;
574 break;
575
576 default:
577 ret = false;
578
579 goto out;
580 break;
581 }
582
583 pr_cont("%s.\n", f10h_nb_mce_desc[xec - offset]);
584
585out:
586 return ret;
587}
588
Borislav Petkovcb9d5ec2010-09-16 17:36:12 +0200589static bool nb_noop_mce(u16 ec, u8 xec)
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200590{
591 return false;
592}
593
Borislav Petkovb0b07a22011-08-24 18:44:22 +0200594void amd_decode_nb_mce(struct mce *m)
Borislav Petkov549d0422009-07-24 13:51:42 +0200595{
Borislav Petkovdf71a052011-01-19 18:15:10 +0100596 struct cpuinfo_x86 *c = &boot_cpu_data;
Borislav Petkovb0b07a22011-08-24 18:44:22 +0200597 int node_id = amd_get_nb_id(m->extcpu);
598 u16 ec = EC(m->status);
599 u8 xec = XEC(m->status, 0x1f);
Borislav Petkov549d0422009-07-24 13:51:42 +0200600
Borislav Petkov295d8cd2011-08-24 17:47:11 +0200601 pr_emerg(HW_ERR "Northbridge Error (node %d): ", node_id);
Borislav Petkov6d5db462010-11-25 15:40:27 +0100602
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200603 switch (xec) {
604 case 0x2:
605 pr_cont("Sync error (sync packets on HT link detected).\n");
606 return;
Borislav Petkovd93cc222009-07-28 10:56:15 +0200607
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200608 case 0x3:
609 pr_cont("HT Master abort.\n");
610 return;
611
612 case 0x4:
613 pr_cont("HT Target abort.\n");
614 return;
615
616 case 0x7:
617 pr_cont("NB Watchdog timeout.\n");
618 return;
619
620 case 0x9:
621 pr_cont("SVM DMA Exclusion Vector error.\n");
622 return;
623
624 default:
625 break;
626 }
627
628 if (!fam_ops->nb_mce(ec, xec))
629 goto wrong_nb_mce;
630
Borislav Petkovdf71a052011-01-19 18:15:10 +0100631 if (c->x86 == 0xf || c->x86 == 0x10 || c->x86 == 0x15)
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200632 if ((xec == 0x8 || xec == 0x0) && nb_bus_decoder)
Borislav Petkovb0b07a22011-08-24 18:44:22 +0200633 nb_bus_decoder(node_id, m);
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200634
635 return;
636
637wrong_nb_mce:
638 pr_emerg(HW_ERR "Corrupted NB MCE info?\n");
Borislav Petkovd93cc222009-07-28 10:56:15 +0200639}
640EXPORT_SYMBOL_GPL(amd_decode_nb_mce);
641
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200642static void amd_decode_fr_mce(struct mce *m)
Borislav Petkov53bd5fe2009-07-28 14:20:46 +0200643{
Borislav Petkov8259a7e2010-09-22 15:28:59 +0200644 struct cpuinfo_x86 *c = &boot_cpu_data;
Borislav Petkov62452882010-09-22 16:08:37 +0200645 u8 xec = XEC(m->status, xec_mask);
Borislav Petkov8259a7e2010-09-22 15:28:59 +0200646
647 if (c->x86 == 0xf || c->x86 == 0x11)
Borislav Petkovfe4ea262010-08-31 18:38:24 +0200648 goto wrong_fr_mce;
649
Borislav Petkov8259a7e2010-09-22 15:28:59 +0200650 if (c->x86 != 0x15 && xec != 0x0)
651 goto wrong_fr_mce;
652
653 pr_emerg(HW_ERR "%s Error: ",
654 (c->x86 == 0x15 ? "Execution Unit" : "FIROB"));
655
656 if (xec == 0x0 || xec == 0xc)
657 pr_cont("%s.\n", fr_ex_mce_desc[xec]);
658 else if (xec < 0xd)
659 pr_cont("%s parity error.\n", fr_ex_mce_desc[xec]);
660 else
661 goto wrong_fr_mce;
662
663 return;
Borislav Petkovfe4ea262010-08-31 18:38:24 +0200664
665wrong_fr_mce:
666 pr_emerg(HW_ERR "Corrupted FR MCE info?\n");
Borislav Petkov53bd5fe2009-07-28 14:20:46 +0200667}
668
Borislav Petkovb8f85c42010-09-22 15:37:58 +0200669static void amd_decode_fp_mce(struct mce *m)
670{
Borislav Petkov62452882010-09-22 16:08:37 +0200671 u8 xec = XEC(m->status, xec_mask);
Borislav Petkovb8f85c42010-09-22 15:37:58 +0200672
673 pr_emerg(HW_ERR "Floating Point Unit Error: ");
674
675 switch (xec) {
676 case 0x1:
677 pr_cont("Free List");
678 break;
679
680 case 0x2:
681 pr_cont("Physical Register File");
682 break;
683
684 case 0x3:
685 pr_cont("Retire Queue");
686 break;
687
688 case 0x4:
689 pr_cont("Scheduler table");
690 break;
691
692 case 0x5:
693 pr_cont("Status Register File");
694 break;
695
696 default:
697 goto wrong_fp_mce;
698 break;
699 }
700
701 pr_cont(" parity error.\n");
702
703 return;
704
705wrong_fp_mce:
706 pr_emerg(HW_ERR "Corrupted FP MCE info?\n");
707}
708
Borislav Petkov63375832010-09-06 18:13:39 +0200709static inline void amd_decode_err_code(u16 ec)
Borislav Petkovd93cc222009-07-28 10:56:15 +0200710{
Borislav Petkovfa7ae8c2010-09-22 17:42:27 +0200711
712 pr_emerg(HW_ERR "cache level: %s", LL_MSG(ec));
713
714 if (BUS_ERROR(ec))
715 pr_cont(", mem/io: %s", II_MSG(ec));
716 else
717 pr_cont(", tx: %s", TT_MSG(ec));
718
719 if (MEM_ERROR(ec) || BUS_ERROR(ec)) {
720 pr_cont(", mem-tx: %s", R4_MSG(ec));
721
722 if (BUS_ERROR(ec))
723 pr_cont(", part-proc: %s (%s)", PP_MSG(ec), TO_MSG(ec));
724 }
725
726 pr_cont("\n");
Borislav Petkov549d0422009-07-24 13:51:42 +0200727}
Borislav Petkov549d0422009-07-24 13:51:42 +0200728
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200729/*
730 * Filter out unwanted MCE signatures here.
731 */
732static bool amd_filter_mce(struct mce *m)
733{
734 u8 xec = (m->status >> 16) & 0x1f;
735
736 /*
737 * NB GART TLB error reporting is disabled by default.
738 */
739 if (m->bank == 4 && xec == 0x5 && !report_gart_errors)
740 return true;
741
742 return false;
743}
744
Borislav Petkov9cdeb402010-09-02 18:33:24 +0200745int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
Borislav Petkov549d0422009-07-24 13:51:42 +0200746{
Borislav Petkovfb253192009-10-07 13:20:38 +0200747 struct mce *m = (struct mce *)data;
Borislav Petkovfa7ae8c2010-09-22 17:42:27 +0200748 struct cpuinfo_x86 *c = &boot_cpu_data;
Borislav Petkovb0b07a22011-08-24 18:44:22 +0200749 int ecc;
Borislav Petkov549d0422009-07-24 13:51:42 +0200750
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200751 if (amd_filter_mce(m))
752 return NOTIFY_STOP;
753
Borislav Petkov086be782011-09-30 16:34:44 +0200754 pr_emerg(HW_ERR "CPU:%d\tMC%d_STATUS[%s|%s|%s|%s|%s",
Borislav Petkovbff7b812011-08-04 19:25:24 +0200755 m->extcpu, m->bank,
Borislav Petkovfa7ae8c2010-09-22 17:42:27 +0200756 ((m->status & MCI_STATUS_OVER) ? "Over" : "-"),
757 ((m->status & MCI_STATUS_UC) ? "UE" : "CE"),
758 ((m->status & MCI_STATUS_MISCV) ? "MiscV" : "-"),
759 ((m->status & MCI_STATUS_PCC) ? "PCC" : "-"),
760 ((m->status & MCI_STATUS_ADDRV) ? "AddrV" : "-"));
Borislav Petkov549d0422009-07-24 13:51:42 +0200761
Borislav Petkovfa7ae8c2010-09-22 17:42:27 +0200762 if (c->x86 == 0x15)
763 pr_cont("|%s|%s",
Randy Dunlap50adbbd2010-11-13 11:44:26 -0500764 ((m->status & BIT_64(44)) ? "Deferred" : "-"),
765 ((m->status & BIT_64(43)) ? "Poison" : "-"));
Borislav Petkov549d0422009-07-24 13:51:42 +0200766
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200767 /* do the two bits[14:13] together */
Borislav Petkov35d824b2010-04-30 15:19:02 +0200768 ecc = (m->status >> 45) & 0x3;
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200769 if (ecc)
Borislav Petkovfa7ae8c2010-09-22 17:42:27 +0200770 pr_cont("|%sECC", ((ecc == 2) ? "C" : "U"));
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200771
Borislav Petkovfa7ae8c2010-09-22 17:42:27 +0200772 pr_cont("]: 0x%016llx\n", m->status);
773
Borislav Petkov086be782011-09-30 16:34:44 +0200774 if (m->status & MCI_STATUS_ADDRV)
775 pr_emerg(HW_ERR "\tMC%d_ADDR: 0x%016llx\n", m->bank, m->addr);
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200776
Borislav Petkov51966242009-07-28 13:50:43 +0200777 switch (m->bank) {
778 case 0:
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200779 amd_decode_dc_mce(m);
Borislav Petkov51966242009-07-28 13:50:43 +0200780 break;
Borislav Petkovd93cc222009-07-28 10:56:15 +0200781
Borislav Petkovab5535e2009-07-28 14:06:26 +0200782 case 1:
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200783 amd_decode_ic_mce(m);
Borislav Petkovab5535e2009-07-28 14:06:26 +0200784 break;
785
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200786 case 2:
Borislav Petkovfa7ae8c2010-09-22 17:42:27 +0200787 if (c->x86 == 0x15)
Borislav Petkov70fdb492010-09-21 20:45:10 +0200788 amd_decode_cu_mce(m);
789 else
790 amd_decode_bu_mce(m);
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200791 break;
792
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200793 case 3:
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200794 amd_decode_ls_mce(m);
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200795 break;
796
Borislav Petkov51966242009-07-28 13:50:43 +0200797 case 4:
Borislav Petkovb0b07a22011-08-24 18:44:22 +0200798 amd_decode_nb_mce(m);
Borislav Petkov51966242009-07-28 13:50:43 +0200799 break;
800
Borislav Petkov53bd5fe2009-07-28 14:20:46 +0200801 case 5:
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200802 amd_decode_fr_mce(m);
Borislav Petkov53bd5fe2009-07-28 14:20:46 +0200803 break;
804
Borislav Petkovb8f85c42010-09-22 15:37:58 +0200805 case 6:
806 amd_decode_fp_mce(m);
807 break;
808
Borislav Petkov51966242009-07-28 13:50:43 +0200809 default:
810 break;
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200811 }
Borislav Petkov51966242009-07-28 13:50:43 +0200812
813 amd_decode_err_code(m->status & 0xffff);
Borislav Petkovfb253192009-10-07 13:20:38 +0200814
815 return NOTIFY_STOP;
Borislav Petkov549d0422009-07-24 13:51:42 +0200816}
Borislav Petkov9cdeb402010-09-02 18:33:24 +0200817EXPORT_SYMBOL_GPL(amd_decode_mce);
Ingo Molnarf436f8b2009-10-01 16:14:32 +0200818
Borislav Petkovfb253192009-10-07 13:20:38 +0200819static struct notifier_block amd_mce_dec_nb = {
820 .notifier_call = amd_decode_mce,
821};
822
Ingo Molnarf436f8b2009-10-01 16:14:32 +0200823static int __init mce_amd_init(void)
824{
Borislav Petkovbad11e02010-09-22 17:44:51 +0200825 struct cpuinfo_x86 *c = &boot_cpu_data;
826
827 if (c->x86_vendor != X86_VENDOR_AMD)
Borislav Petkove045c292010-08-06 18:55:45 +0200828 return 0;
829
Borislav Petkovbad11e02010-09-22 17:44:51 +0200830 if ((c->x86 < 0xf || c->x86 > 0x12) &&
831 (c->x86 != 0x14 || c->x86_model > 0xf) &&
832 (c->x86 != 0x15 || c->x86_model > 0xf))
Borislav Petkove045c292010-08-06 18:55:45 +0200833 return 0;
834
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200835 fam_ops = kzalloc(sizeof(struct amd_decoder_ops), GFP_KERNEL);
836 if (!fam_ops)
837 return -ENOMEM;
838
Borislav Petkovbad11e02010-09-22 17:44:51 +0200839 switch (c->x86) {
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200840 case 0xf:
841 fam_ops->dc_mce = k8_dc_mce;
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200842 fam_ops->ic_mce = k8_ic_mce;
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200843 fam_ops->nb_mce = k8_nb_mce;
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200844 break;
845
846 case 0x10:
847 fam_ops->dc_mce = f10h_dc_mce;
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200848 fam_ops->ic_mce = k8_ic_mce;
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200849 fam_ops->nb_mce = f10h_nb_mce;
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200850 break;
851
Borislav Petkovf0157b32010-10-05 19:07:16 +0200852 case 0x11:
853 fam_ops->dc_mce = k8_dc_mce;
854 fam_ops->ic_mce = k8_ic_mce;
855 fam_ops->nb_mce = f10h_nb_mce;
856 break;
857
Borislav Petkov9be0bb12010-09-16 15:08:14 +0200858 case 0x12:
859 fam_ops->dc_mce = f12h_dc_mce;
Borislav Petkove7281eb2010-09-16 16:45:22 +0200860 fam_ops->ic_mce = k8_ic_mce;
Borislav Petkovcb9d5ec2010-09-16 17:36:12 +0200861 fam_ops->nb_mce = nb_noop_mce;
Borislav Petkov9be0bb12010-09-16 15:08:14 +0200862 break;
863
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200864 case 0x14:
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200865 nb_err_cpumask = 0x3;
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200866 fam_ops->dc_mce = f14h_dc_mce;
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200867 fam_ops->ic_mce = f14h_ic_mce;
Borislav Petkovcb9d5ec2010-09-16 17:36:12 +0200868 fam_ops->nb_mce = nb_noop_mce;
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200869 break;
870
Borislav Petkov2be64bf2010-09-17 19:11:47 +0200871 case 0x15:
872 xec_mask = 0x1f;
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200873 fam_ops->dc_mce = f15h_dc_mce;
Borislav Petkov86039cd2010-11-08 15:03:35 +0100874 fam_ops->ic_mce = f15h_ic_mce;
Borislav Petkov05cd6672010-09-22 15:06:24 +0200875 fam_ops->nb_mce = f10h_nb_mce;
Borislav Petkov2be64bf2010-09-17 19:11:47 +0200876 break;
877
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200878 default:
Borislav Petkovbad11e02010-09-22 17:44:51 +0200879 printk(KERN_WARNING "Huh? What family is that: %d?!\n", c->x86);
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200880 kfree(fam_ops);
881 return -EINVAL;
882 }
883
Borislav Petkov9530d602010-09-06 15:05:45 +0200884 pr_info("MCE: In-kernel MCE decoding enabled.\n");
885
Borislav Petkov3653ada2011-12-04 15:12:09 +0100886 mce_register_decode_chain(&amd_mce_dec_nb);
Ingo Molnarf436f8b2009-10-01 16:14:32 +0200887
888 return 0;
889}
890early_initcall(mce_amd_init);
Borislav Petkov0d18b2e2009-10-02 15:31:48 +0200891
892#ifdef MODULE
893static void __exit mce_amd_exit(void)
894{
Borislav Petkov3653ada2011-12-04 15:12:09 +0100895 mce_unregister_decode_chain(&amd_mce_dec_nb);
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200896 kfree(fam_ops);
Borislav Petkov0d18b2e2009-10-02 15:31:48 +0200897}
898
899MODULE_DESCRIPTION("AMD MCE decoder");
900MODULE_ALIAS("edac-mce-amd");
901MODULE_LICENSE("GPL");
902module_exit(mce_amd_exit);
903#endif