blob: bf6dd9978aa7863d5124460861c68f3a396d7bc2 [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 */
Borislav Petkov6c1173a2011-11-21 19:45:34 +010091 "Microcode Patch Buffer", /* xec = 010 */
Borislav Petkov86039cd2010-11-08 15:03:35 +010092 "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",
Borislav Petkovb64a99c2011-11-23 14:50:44 +0100107 "VB Data ECC or parity error",
Borislav Petkov70fdb492010-09-21 20:45:10 +0200108 "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
Borislav Petkov6c1173a2011-11-21 19:45:34 +0100357 case 0x10:
358 pr_cont("%s.\n", f15h_ic_mce_desc[xec-4]);
359 break;
360
361 case 0x11 ... 0x14:
Borislav Petkov86039cd2010-11-08 15:03:35 +0100362 pr_cont("Decoder %s parity error.\n", f15h_ic_mce_desc[xec-4]);
363 break;
364
365 default:
366 ret = false;
367 }
368 return ret;
369}
370
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200371static void amd_decode_ic_mce(struct mce *m)
Borislav Petkovab5535e2009-07-28 14:06:26 +0200372{
Borislav Petkov62452882010-09-22 16:08:37 +0200373 u16 ec = EC(m->status);
374 u8 xec = XEC(m->status, xec_mask);
Borislav Petkovab5535e2009-07-28 14:06:26 +0200375
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200376 pr_emerg(HW_ERR "Instruction Cache Error: ");
Borislav Petkovab5535e2009-07-28 14:06:26 +0200377
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200378 if (TLB_ERROR(ec))
379 pr_cont("%s TLB %s.\n", LL_MSG(ec),
380 (xec ? "multimatch" : "parity error"));
381 else if (BUS_ERROR(ec)) {
Borislav Petkov525906b2010-10-15 15:27:02 +0200382 bool k8 = (boot_cpu_data.x86 == 0xf && (m->status & BIT_64(58)));
Borislav Petkovab5535e2009-07-28 14:06:26 +0200383
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200384 pr_cont("during %s.\n", (k8 ? "system linefill" : "NB data read"));
Borislav Petkov86039cd2010-11-08 15:03:35 +0100385 } else if (fam_ops->ic_mce(ec, xec))
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200386 ;
387 else
388 pr_emerg(HW_ERR "Corrupted IC MCE info?\n");
Borislav Petkovab5535e2009-07-28 14:06:26 +0200389}
390
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200391static void amd_decode_bu_mce(struct mce *m)
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200392{
Borislav Petkov62452882010-09-22 16:08:37 +0200393 u16 ec = EC(m->status);
394 u8 xec = XEC(m->status, xec_mask);
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200395
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200396 pr_emerg(HW_ERR "Bus Unit Error");
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200397
398 if (xec == 0x1)
399 pr_cont(" in the write data buffers.\n");
400 else if (xec == 0x3)
401 pr_cont(" in the victim data buffers.\n");
402 else if (xec == 0x2 && MEM_ERROR(ec))
Borislav Petkov62452882010-09-22 16:08:37 +0200403 pr_cont(": %s error in the L2 cache tags.\n", R4_MSG(ec));
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200404 else if (xec == 0x0) {
405 if (TLB_ERROR(ec))
406 pr_cont(": %s error in a Page Descriptor Cache or "
407 "Guest TLB.\n", TT_MSG(ec));
408 else if (BUS_ERROR(ec))
409 pr_cont(": %s/ECC error in data read from NB: %s.\n",
Borislav Petkov62452882010-09-22 16:08:37 +0200410 R4_MSG(ec), PP_MSG(ec));
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200411 else if (MEM_ERROR(ec)) {
Borislav Petkov62452882010-09-22 16:08:37 +0200412 u8 r4 = R4(ec);
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200413
Borislav Petkov62452882010-09-22 16:08:37 +0200414 if (r4 >= 0x7)
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200415 pr_cont(": %s error during data copyback.\n",
Borislav Petkov62452882010-09-22 16:08:37 +0200416 R4_MSG(ec));
417 else if (r4 <= 0x1)
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200418 pr_cont(": %s parity/ECC error during data "
Borislav Petkov62452882010-09-22 16:08:37 +0200419 "access from L2.\n", R4_MSG(ec));
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200420 else
421 goto wrong_bu_mce;
422 } else
423 goto wrong_bu_mce;
424 } else
425 goto wrong_bu_mce;
426
427 return;
428
429wrong_bu_mce:
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200430 pr_emerg(HW_ERR "Corrupted BU MCE info?\n");
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200431}
432
Borislav Petkov70fdb492010-09-21 20:45:10 +0200433static void amd_decode_cu_mce(struct mce *m)
434{
Borislav Petkov62452882010-09-22 16:08:37 +0200435 u16 ec = EC(m->status);
436 u8 xec = XEC(m->status, xec_mask);
Borislav Petkov70fdb492010-09-21 20:45:10 +0200437
438 pr_emerg(HW_ERR "Combined Unit Error: ");
439
440 if (TLB_ERROR(ec)) {
441 if (xec == 0x0)
442 pr_cont("Data parity TLB read error.\n");
443 else if (xec == 0x1)
444 pr_cont("Poison data provided for TLB fill.\n");
445 else
446 goto wrong_cu_mce;
447 } else if (BUS_ERROR(ec)) {
448 if (xec > 2)
449 goto wrong_cu_mce;
450
451 pr_cont("Error during attempted NB data read.\n");
452 } else if (MEM_ERROR(ec)) {
453 switch (xec) {
454 case 0x4 ... 0xc:
455 pr_cont("%s.\n", f15h_cu_mce_desc[xec - 0x4]);
456 break;
457
458 case 0x10 ... 0x14:
459 pr_cont("%s.\n", f15h_cu_mce_desc[xec - 0x7]);
460 break;
461
462 default:
463 goto wrong_cu_mce;
464 }
465 }
466
467 return;
468
469wrong_cu_mce:
470 pr_emerg(HW_ERR "Corrupted CU MCE info?\n");
471}
472
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200473static void amd_decode_ls_mce(struct mce *m)
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200474{
Borislav Petkov62452882010-09-22 16:08:37 +0200475 u16 ec = EC(m->status);
476 u8 xec = XEC(m->status, xec_mask);
Borislav Petkovded50622010-08-27 17:03:34 +0200477
Borislav Petkovb18434c2010-09-22 11:53:32 +0200478 if (boot_cpu_data.x86 >= 0x14) {
Borislav Petkovded50622010-08-27 17:03:34 +0200479 pr_emerg("You shouldn't be seeing an LS MCE on this cpu family,"
480 " please report on LKML.\n");
481 return;
482 }
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200483
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200484 pr_emerg(HW_ERR "Load Store Error");
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200485
486 if (xec == 0x0) {
Borislav Petkov62452882010-09-22 16:08:37 +0200487 u8 r4 = R4(ec);
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200488
Borislav Petkovded50622010-08-27 17:03:34 +0200489 if (!BUS_ERROR(ec) || (r4 != R4_DRD && r4 != R4_DWR))
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200490 goto wrong_ls_mce;
491
Borislav Petkov62452882010-09-22 16:08:37 +0200492 pr_cont(" during %s.\n", R4_MSG(ec));
Borislav Petkovded50622010-08-27 17:03:34 +0200493 } else
494 goto wrong_ls_mce;
495
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200496 return;
497
498wrong_ls_mce:
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200499 pr_emerg(HW_ERR "Corrupted LS MCE info?\n");
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200500}
501
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200502static bool k8_nb_mce(u16 ec, u8 xec)
503{
504 bool ret = true;
505
506 switch (xec) {
507 case 0x1:
508 pr_cont("CRC error detected on HT link.\n");
509 break;
510
511 case 0x5:
512 pr_cont("Invalid GART PTE entry during GART table walk.\n");
513 break;
514
515 case 0x6:
516 pr_cont("Unsupported atomic RMW received from an IO link.\n");
517 break;
518
519 case 0x0:
520 case 0x8:
Borislav Petkovf0157b32010-10-05 19:07:16 +0200521 if (boot_cpu_data.x86 == 0x11)
522 return false;
523
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200524 pr_cont("DRAM ECC error detected on the NB.\n");
525 break;
526
527 case 0xd:
528 pr_cont("Parity error on the DRAM addr/ctl signals.\n");
529 break;
530
531 default:
532 ret = false;
533 break;
534 }
535
536 return ret;
537}
538
539static bool f10h_nb_mce(u16 ec, u8 xec)
540{
541 bool ret = true;
542 u8 offset = 0;
543
544 if (k8_nb_mce(ec, xec))
545 return true;
546
547 switch(xec) {
548 case 0xa ... 0xc:
549 offset = 10;
550 break;
551
552 case 0xe:
553 offset = 11;
554 break;
555
556 case 0xf:
557 if (TLB_ERROR(ec))
558 pr_cont("GART Table Walk data error.\n");
559 else if (BUS_ERROR(ec))
560 pr_cont("DMA Exclusion Vector Table Walk error.\n");
561 else
562 ret = false;
563
564 goto out;
565 break;
566
Borislav Petkov05cd6672010-09-22 15:06:24 +0200567 case 0x19:
568 if (boot_cpu_data.x86 == 0x15)
569 pr_cont("Compute Unit Data Error.\n");
570 else
571 ret = false;
572
573 goto out;
574 break;
575
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200576 case 0x1c ... 0x1f:
577 offset = 24;
578 break;
579
580 default:
581 ret = false;
582
583 goto out;
584 break;
585 }
586
587 pr_cont("%s.\n", f10h_nb_mce_desc[xec - offset]);
588
589out:
590 return ret;
591}
592
Borislav Petkovcb9d5ec2010-09-16 17:36:12 +0200593static bool nb_noop_mce(u16 ec, u8 xec)
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200594{
595 return false;
596}
597
Borislav Petkovb0b07a22011-08-24 18:44:22 +0200598void amd_decode_nb_mce(struct mce *m)
Borislav Petkov549d0422009-07-24 13:51:42 +0200599{
Borislav Petkovdf71a052011-01-19 18:15:10 +0100600 struct cpuinfo_x86 *c = &boot_cpu_data;
Borislav Petkovb0b07a22011-08-24 18:44:22 +0200601 int node_id = amd_get_nb_id(m->extcpu);
602 u16 ec = EC(m->status);
603 u8 xec = XEC(m->status, 0x1f);
Borislav Petkov549d0422009-07-24 13:51:42 +0200604
Borislav Petkov295d8cd2011-08-24 17:47:11 +0200605 pr_emerg(HW_ERR "Northbridge Error (node %d): ", node_id);
Borislav Petkov6d5db462010-11-25 15:40:27 +0100606
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200607 switch (xec) {
608 case 0x2:
609 pr_cont("Sync error (sync packets on HT link detected).\n");
610 return;
Borislav Petkovd93cc222009-07-28 10:56:15 +0200611
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200612 case 0x3:
613 pr_cont("HT Master abort.\n");
614 return;
615
616 case 0x4:
617 pr_cont("HT Target abort.\n");
618 return;
619
620 case 0x7:
621 pr_cont("NB Watchdog timeout.\n");
622 return;
623
624 case 0x9:
625 pr_cont("SVM DMA Exclusion Vector error.\n");
626 return;
627
628 default:
629 break;
630 }
631
632 if (!fam_ops->nb_mce(ec, xec))
633 goto wrong_nb_mce;
634
Borislav Petkovdf71a052011-01-19 18:15:10 +0100635 if (c->x86 == 0xf || c->x86 == 0x10 || c->x86 == 0x15)
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200636 if ((xec == 0x8 || xec == 0x0) && nb_bus_decoder)
Borislav Petkovb0b07a22011-08-24 18:44:22 +0200637 nb_bus_decoder(node_id, m);
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200638
639 return;
640
641wrong_nb_mce:
642 pr_emerg(HW_ERR "Corrupted NB MCE info?\n");
Borislav Petkovd93cc222009-07-28 10:56:15 +0200643}
644EXPORT_SYMBOL_GPL(amd_decode_nb_mce);
645
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200646static void amd_decode_fr_mce(struct mce *m)
Borislav Petkov53bd5fe2009-07-28 14:20:46 +0200647{
Borislav Petkov8259a7e2010-09-22 15:28:59 +0200648 struct cpuinfo_x86 *c = &boot_cpu_data;
Borislav Petkov62452882010-09-22 16:08:37 +0200649 u8 xec = XEC(m->status, xec_mask);
Borislav Petkov8259a7e2010-09-22 15:28:59 +0200650
651 if (c->x86 == 0xf || c->x86 == 0x11)
Borislav Petkovfe4ea262010-08-31 18:38:24 +0200652 goto wrong_fr_mce;
653
Borislav Petkov8259a7e2010-09-22 15:28:59 +0200654 if (c->x86 != 0x15 && xec != 0x0)
655 goto wrong_fr_mce;
656
657 pr_emerg(HW_ERR "%s Error: ",
658 (c->x86 == 0x15 ? "Execution Unit" : "FIROB"));
659
660 if (xec == 0x0 || xec == 0xc)
661 pr_cont("%s.\n", fr_ex_mce_desc[xec]);
662 else if (xec < 0xd)
663 pr_cont("%s parity error.\n", fr_ex_mce_desc[xec]);
664 else
665 goto wrong_fr_mce;
666
667 return;
Borislav Petkovfe4ea262010-08-31 18:38:24 +0200668
669wrong_fr_mce:
670 pr_emerg(HW_ERR "Corrupted FR MCE info?\n");
Borislav Petkov53bd5fe2009-07-28 14:20:46 +0200671}
672
Borislav Petkovb8f85c42010-09-22 15:37:58 +0200673static void amd_decode_fp_mce(struct mce *m)
674{
Borislav Petkov62452882010-09-22 16:08:37 +0200675 u8 xec = XEC(m->status, xec_mask);
Borislav Petkovb8f85c42010-09-22 15:37:58 +0200676
677 pr_emerg(HW_ERR "Floating Point Unit Error: ");
678
679 switch (xec) {
680 case 0x1:
681 pr_cont("Free List");
682 break;
683
684 case 0x2:
685 pr_cont("Physical Register File");
686 break;
687
688 case 0x3:
689 pr_cont("Retire Queue");
690 break;
691
692 case 0x4:
693 pr_cont("Scheduler table");
694 break;
695
696 case 0x5:
697 pr_cont("Status Register File");
698 break;
699
700 default:
701 goto wrong_fp_mce;
702 break;
703 }
704
705 pr_cont(" parity error.\n");
706
707 return;
708
709wrong_fp_mce:
710 pr_emerg(HW_ERR "Corrupted FP MCE info?\n");
711}
712
Borislav Petkov63375832010-09-06 18:13:39 +0200713static inline void amd_decode_err_code(u16 ec)
Borislav Petkovd93cc222009-07-28 10:56:15 +0200714{
Borislav Petkovfa7ae8c2010-09-22 17:42:27 +0200715
716 pr_emerg(HW_ERR "cache level: %s", LL_MSG(ec));
717
718 if (BUS_ERROR(ec))
719 pr_cont(", mem/io: %s", II_MSG(ec));
720 else
721 pr_cont(", tx: %s", TT_MSG(ec));
722
723 if (MEM_ERROR(ec) || BUS_ERROR(ec)) {
724 pr_cont(", mem-tx: %s", R4_MSG(ec));
725
726 if (BUS_ERROR(ec))
727 pr_cont(", part-proc: %s (%s)", PP_MSG(ec), TO_MSG(ec));
728 }
729
730 pr_cont("\n");
Borislav Petkov549d0422009-07-24 13:51:42 +0200731}
Borislav Petkov549d0422009-07-24 13:51:42 +0200732
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200733/*
734 * Filter out unwanted MCE signatures here.
735 */
736static bool amd_filter_mce(struct mce *m)
737{
738 u8 xec = (m->status >> 16) & 0x1f;
739
740 /*
741 * NB GART TLB error reporting is disabled by default.
742 */
743 if (m->bank == 4 && xec == 0x5 && !report_gart_errors)
744 return true;
745
746 return false;
747}
748
Borislav Petkov9cdeb402010-09-02 18:33:24 +0200749int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
Borislav Petkov549d0422009-07-24 13:51:42 +0200750{
Borislav Petkovfb253192009-10-07 13:20:38 +0200751 struct mce *m = (struct mce *)data;
Borislav Petkovfa7ae8c2010-09-22 17:42:27 +0200752 struct cpuinfo_x86 *c = &boot_cpu_data;
Borislav Petkovb0b07a22011-08-24 18:44:22 +0200753 int ecc;
Borislav Petkov549d0422009-07-24 13:51:42 +0200754
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200755 if (amd_filter_mce(m))
756 return NOTIFY_STOP;
757
Borislav Petkov086be782011-09-30 16:34:44 +0200758 pr_emerg(HW_ERR "CPU:%d\tMC%d_STATUS[%s|%s|%s|%s|%s",
Borislav Petkovbff7b812011-08-04 19:25:24 +0200759 m->extcpu, m->bank,
Borislav Petkovfa7ae8c2010-09-22 17:42:27 +0200760 ((m->status & MCI_STATUS_OVER) ? "Over" : "-"),
761 ((m->status & MCI_STATUS_UC) ? "UE" : "CE"),
762 ((m->status & MCI_STATUS_MISCV) ? "MiscV" : "-"),
763 ((m->status & MCI_STATUS_PCC) ? "PCC" : "-"),
764 ((m->status & MCI_STATUS_ADDRV) ? "AddrV" : "-"));
Borislav Petkov549d0422009-07-24 13:51:42 +0200765
Borislav Petkovfa7ae8c2010-09-22 17:42:27 +0200766 if (c->x86 == 0x15)
767 pr_cont("|%s|%s",
Randy Dunlap50adbbd2010-11-13 11:44:26 -0500768 ((m->status & BIT_64(44)) ? "Deferred" : "-"),
769 ((m->status & BIT_64(43)) ? "Poison" : "-"));
Borislav Petkov549d0422009-07-24 13:51:42 +0200770
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200771 /* do the two bits[14:13] together */
Borislav Petkov35d824b2010-04-30 15:19:02 +0200772 ecc = (m->status >> 45) & 0x3;
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200773 if (ecc)
Borislav Petkovfa7ae8c2010-09-22 17:42:27 +0200774 pr_cont("|%sECC", ((ecc == 2) ? "C" : "U"));
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200775
Borislav Petkovfa7ae8c2010-09-22 17:42:27 +0200776 pr_cont("]: 0x%016llx\n", m->status);
777
Borislav Petkov086be782011-09-30 16:34:44 +0200778 if (m->status & MCI_STATUS_ADDRV)
779 pr_emerg(HW_ERR "\tMC%d_ADDR: 0x%016llx\n", m->bank, m->addr);
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200780
Borislav Petkov51966242009-07-28 13:50:43 +0200781 switch (m->bank) {
782 case 0:
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200783 amd_decode_dc_mce(m);
Borislav Petkov51966242009-07-28 13:50:43 +0200784 break;
Borislav Petkovd93cc222009-07-28 10:56:15 +0200785
Borislav Petkovab5535e2009-07-28 14:06:26 +0200786 case 1:
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200787 amd_decode_ic_mce(m);
Borislav Petkovab5535e2009-07-28 14:06:26 +0200788 break;
789
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200790 case 2:
Borislav Petkovfa7ae8c2010-09-22 17:42:27 +0200791 if (c->x86 == 0x15)
Borislav Petkov70fdb492010-09-21 20:45:10 +0200792 amd_decode_cu_mce(m);
793 else
794 amd_decode_bu_mce(m);
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200795 break;
796
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200797 case 3:
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200798 amd_decode_ls_mce(m);
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200799 break;
800
Borislav Petkov51966242009-07-28 13:50:43 +0200801 case 4:
Borislav Petkovb0b07a22011-08-24 18:44:22 +0200802 amd_decode_nb_mce(m);
Borislav Petkov51966242009-07-28 13:50:43 +0200803 break;
804
Borislav Petkov53bd5fe2009-07-28 14:20:46 +0200805 case 5:
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200806 amd_decode_fr_mce(m);
Borislav Petkov53bd5fe2009-07-28 14:20:46 +0200807 break;
808
Borislav Petkovb8f85c42010-09-22 15:37:58 +0200809 case 6:
810 amd_decode_fp_mce(m);
811 break;
812
Borislav Petkov51966242009-07-28 13:50:43 +0200813 default:
814 break;
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200815 }
Borislav Petkov51966242009-07-28 13:50:43 +0200816
817 amd_decode_err_code(m->status & 0xffff);
Borislav Petkovfb253192009-10-07 13:20:38 +0200818
819 return NOTIFY_STOP;
Borislav Petkov549d0422009-07-24 13:51:42 +0200820}
Borislav Petkov9cdeb402010-09-02 18:33:24 +0200821EXPORT_SYMBOL_GPL(amd_decode_mce);
Ingo Molnarf436f8b2009-10-01 16:14:32 +0200822
Borislav Petkovfb253192009-10-07 13:20:38 +0200823static struct notifier_block amd_mce_dec_nb = {
824 .notifier_call = amd_decode_mce,
825};
826
Ingo Molnarf436f8b2009-10-01 16:14:32 +0200827static int __init mce_amd_init(void)
828{
Borislav Petkovbad11e02010-09-22 17:44:51 +0200829 struct cpuinfo_x86 *c = &boot_cpu_data;
830
831 if (c->x86_vendor != X86_VENDOR_AMD)
Borislav Petkove045c292010-08-06 18:55:45 +0200832 return 0;
833
Borislav Petkovbad11e02010-09-22 17:44:51 +0200834 if ((c->x86 < 0xf || c->x86 > 0x12) &&
835 (c->x86 != 0x14 || c->x86_model > 0xf) &&
836 (c->x86 != 0x15 || c->x86_model > 0xf))
Borislav Petkove045c292010-08-06 18:55:45 +0200837 return 0;
838
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200839 fam_ops = kzalloc(sizeof(struct amd_decoder_ops), GFP_KERNEL);
840 if (!fam_ops)
841 return -ENOMEM;
842
Borislav Petkovbad11e02010-09-22 17:44:51 +0200843 switch (c->x86) {
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200844 case 0xf:
845 fam_ops->dc_mce = k8_dc_mce;
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200846 fam_ops->ic_mce = k8_ic_mce;
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200847 fam_ops->nb_mce = k8_nb_mce;
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200848 break;
849
850 case 0x10:
851 fam_ops->dc_mce = f10h_dc_mce;
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200852 fam_ops->ic_mce = k8_ic_mce;
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200853 fam_ops->nb_mce = f10h_nb_mce;
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200854 break;
855
Borislav Petkovf0157b32010-10-05 19:07:16 +0200856 case 0x11:
857 fam_ops->dc_mce = k8_dc_mce;
858 fam_ops->ic_mce = k8_ic_mce;
859 fam_ops->nb_mce = f10h_nb_mce;
860 break;
861
Borislav Petkov9be0bb12010-09-16 15:08:14 +0200862 case 0x12:
863 fam_ops->dc_mce = f12h_dc_mce;
Borislav Petkove7281eb32010-09-16 16:45:22 +0200864 fam_ops->ic_mce = k8_ic_mce;
Borislav Petkovcb9d5ec2010-09-16 17:36:12 +0200865 fam_ops->nb_mce = nb_noop_mce;
Borislav Petkov9be0bb12010-09-16 15:08:14 +0200866 break;
867
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200868 case 0x14:
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200869 nb_err_cpumask = 0x3;
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200870 fam_ops->dc_mce = f14h_dc_mce;
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200871 fam_ops->ic_mce = f14h_ic_mce;
Borislav Petkovcb9d5ec2010-09-16 17:36:12 +0200872 fam_ops->nb_mce = nb_noop_mce;
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200873 break;
874
Borislav Petkov2be64bf2010-09-17 19:11:47 +0200875 case 0x15:
876 xec_mask = 0x1f;
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200877 fam_ops->dc_mce = f15h_dc_mce;
Borislav Petkov86039cd2010-11-08 15:03:35 +0100878 fam_ops->ic_mce = f15h_ic_mce;
Borislav Petkov05cd6672010-09-22 15:06:24 +0200879 fam_ops->nb_mce = f10h_nb_mce;
Borislav Petkov2be64bf2010-09-17 19:11:47 +0200880 break;
881
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200882 default:
Borislav Petkovbad11e02010-09-22 17:44:51 +0200883 printk(KERN_WARNING "Huh? What family is that: %d?!\n", c->x86);
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200884 kfree(fam_ops);
885 return -EINVAL;
886 }
887
Borislav Petkov9530d602010-09-06 15:05:45 +0200888 pr_info("MCE: In-kernel MCE decoding enabled.\n");
889
Borislav Petkov3653ada2011-12-04 15:12:09 +0100890 mce_register_decode_chain(&amd_mce_dec_nb);
Ingo Molnarf436f8b2009-10-01 16:14:32 +0200891
892 return 0;
893}
894early_initcall(mce_amd_init);
Borislav Petkov0d18b2e2009-10-02 15:31:48 +0200895
896#ifdef MODULE
897static void __exit mce_amd_exit(void)
898{
Borislav Petkov3653ada2011-12-04 15:12:09 +0100899 mce_unregister_decode_chain(&amd_mce_dec_nb);
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200900 kfree(fam_ops);
Borislav Petkov0d18b2e2009-10-02 15:31:48 +0200901}
902
903MODULE_DESCRIPTION("AMD MCE decoder");
904MODULE_ALIAS("edac-mce-amd");
905MODULE_LICENSE("GPL");
906module_exit(mce_amd_exit);
907#endif