blob: f6ebe5e9a57f4f27e88b6bf613590c3f31843a36 [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 Petkov86039cd2010-11-08 15:03:35 +010067static const char * const f15h_ic_mce_desc[] = {
68 "UC during a demand linefill from L2",
69 "Parity error during data load from IC",
70 "Parity error for IC valid bit",
71 "Main tag parity error",
72 "Parity error in prediction queue",
73 "PFB data/address parity error",
74 "Parity error in the branch status reg",
75 "PFB promotion address error",
76 "Tag error during probe/victimization",
77 "Parity error for IC probe tag valid bit",
78 "PFB non-cacheable bit parity error",
79 "PFB valid bit parity error", /* xec = 0xd */
Borislav Petkov6c1173a2011-11-21 19:45:34 +010080 "Microcode Patch Buffer", /* xec = 010 */
Borislav Petkov86039cd2010-11-08 15:03:35 +010081 "uop queue",
82 "insn buffer",
83 "predecode buffer",
84 "fetch address FIFO"
85};
86
Borislav Petkov70fdb492010-09-21 20:45:10 +020087static const char * const f15h_cu_mce_desc[] = {
88 "Fill ECC error on data fills", /* xec = 0x4 */
89 "Fill parity error on insn fills",
90 "Prefetcher request FIFO parity error",
91 "PRQ address parity error",
92 "PRQ data parity error",
93 "WCC Tag ECC error",
94 "WCC Data ECC error",
95 "WCB Data parity error",
Borislav Petkovb64a99c2011-11-23 14:50:44 +010096 "VB Data ECC or parity error",
Borislav Petkov70fdb492010-09-21 20:45:10 +020097 "L2 Tag ECC error", /* xec = 0x10 */
98 "Hard L2 Tag ECC error",
99 "Multiple hits on L2 tag",
100 "XAB parity error",
101 "PRB address parity error"
102};
103
Borislav Petkov68782672011-11-24 21:29:57 +0100104static const char *nb_mce_desc[] = {
105 "DRAM ECC error detected on the NB",
106 "CRC error detected on HT link",
107 "Link-defined sync error packets detected on HT link",
108 "HT Master abort",
109 "HT Target abort",
110 "Invalid GART PTE entry during GART table walk",
111 "Unsupported atomic RMW received from an IO link",
112 "Watchdog timeout due to lack of progress",
113 "DRAM ECC error detected on the NB",
114 "SVM DMA Exclusion Vector error",
115 "HT data error detected on link",
116 "Protocol error (link, L3, probe filter)",
117 "NB internal arrays parity error",
118 "DRAM addr/ctl signals parity error",
119 "IO link transmission error",
120 "L3 data cache ECC error", /* xec = 0x1c */
121 "L3 cache tag error",
122 "L3 LRU parity bits error",
123 "ECC Error in the Probe Filter directory"
124};
125
Borislav Petkov8259a7e2010-09-22 15:28:59 +0200126static const char * const fr_ex_mce_desc[] = {
127 "CPU Watchdog timer expire",
128 "Wakeup array dest tag",
129 "AG payload array",
130 "EX payload array",
131 "IDRF array",
132 "Retire dispatch queue",
133 "Mapper checkpoint array",
134 "Physical register file EX0 port",
135 "Physical register file EX1 port",
136 "Physical register file AG0 port",
137 "Physical register file AG1 port",
138 "Flag register file",
139 "DE correctable error could not be corrected"
140};
141
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200142static bool f12h_dc_mce(u16 ec, u8 xec)
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200143{
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200144 bool ret = false;
145
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200146 if (MEM_ERROR(ec)) {
Borislav Petkov62452882010-09-22 16:08:37 +0200147 u8 ll = LL(ec);
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200148 ret = true;
149
150 if (ll == LL_L2)
151 pr_cont("during L1 linefill from L2.\n");
152 else if (ll == LL_L1)
Borislav Petkov62452882010-09-22 16:08:37 +0200153 pr_cont("Data/Tag %s error.\n", R4_MSG(ec));
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200154 else
155 ret = false;
156 }
157 return ret;
158}
159
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200160static bool f10h_dc_mce(u16 ec, u8 xec)
Borislav Petkov9be0bb12010-09-16 15:08:14 +0200161{
Borislav Petkov62452882010-09-22 16:08:37 +0200162 if (R4(ec) == R4_GEN && LL(ec) == LL_L1) {
Borislav Petkov9be0bb12010-09-16 15:08:14 +0200163 pr_cont("during data scrub.\n");
164 return true;
165 }
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200166 return f12h_dc_mce(ec, xec);
Borislav Petkov9be0bb12010-09-16 15:08:14 +0200167}
168
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200169static bool k8_dc_mce(u16 ec, u8 xec)
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200170{
171 if (BUS_ERROR(ec)) {
172 pr_cont("during system linefill.\n");
173 return true;
174 }
175
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200176 return f10h_dc_mce(ec, xec);
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200177}
178
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200179static bool f14h_dc_mce(u16 ec, u8 xec)
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200180{
Borislav Petkov62452882010-09-22 16:08:37 +0200181 u8 r4 = R4(ec);
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200182 bool ret = true;
183
184 if (MEM_ERROR(ec)) {
185
Borislav Petkov62452882010-09-22 16:08:37 +0200186 if (TT(ec) != TT_DATA || LL(ec) != LL_L1)
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200187 return false;
188
189 switch (r4) {
190 case R4_DRD:
191 case R4_DWR:
192 pr_cont("Data/Tag parity error due to %s.\n",
193 (r4 == R4_DRD ? "load/hw prf" : "store"));
194 break;
195 case R4_EVICT:
196 pr_cont("Copyback parity error on a tag miss.\n");
197 break;
198 case R4_SNOOP:
199 pr_cont("Tag parity error during snoop.\n");
200 break;
201 default:
202 ret = false;
203 }
204 } else if (BUS_ERROR(ec)) {
205
Borislav Petkov62452882010-09-22 16:08:37 +0200206 if ((II(ec) != II_MEM && II(ec) != II_IO) || LL(ec) != LL_LG)
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200207 return false;
208
209 pr_cont("System read data error on a ");
210
211 switch (r4) {
212 case R4_RD:
213 pr_cont("TLB reload.\n");
214 break;
215 case R4_DWR:
216 pr_cont("store.\n");
217 break;
218 case R4_DRD:
219 pr_cont("load.\n");
220 break;
221 default:
222 ret = false;
223 }
224 } else {
225 ret = false;
226 }
227
228 return ret;
229}
230
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200231static bool f15h_dc_mce(u16 ec, u8 xec)
232{
233 bool ret = true;
234
235 if (MEM_ERROR(ec)) {
236
237 switch (xec) {
238 case 0x0:
239 pr_cont("Data Array access error.\n");
240 break;
241
242 case 0x1:
243 pr_cont("UC error during a linefill from L2/NB.\n");
244 break;
245
246 case 0x2:
247 case 0x11:
248 pr_cont("STQ access error.\n");
249 break;
250
251 case 0x3:
252 pr_cont("SCB access error.\n");
253 break;
254
255 case 0x10:
256 pr_cont("Tag error.\n");
257 break;
258
259 case 0x12:
260 pr_cont("LDQ access error.\n");
261 break;
262
263 default:
264 ret = false;
265 }
266 } else if (BUS_ERROR(ec)) {
267
268 if (!xec)
Borislav Petkov344f0a02011-11-15 17:10:58 +0100269 pr_cont("System Read Data Error.\n");
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200270 else
Borislav Petkov344f0a02011-11-15 17:10:58 +0100271 pr_cont(" Internal error condition type %d.\n", xec);
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200272 } else
273 ret = false;
274
275 return ret;
276}
277
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200278static void amd_decode_dc_mce(struct mce *m)
Borislav Petkov51966242009-07-28 13:50:43 +0200279{
Borislav Petkov62452882010-09-22 16:08:37 +0200280 u16 ec = EC(m->status);
281 u8 xec = XEC(m->status, xec_mask);
Borislav Petkov51966242009-07-28 13:50:43 +0200282
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200283 pr_emerg(HW_ERR "Data Cache Error: ");
Borislav Petkov51966242009-07-28 13:50:43 +0200284
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200285 /* TLB error signatures are the same across families */
286 if (TLB_ERROR(ec)) {
Borislav Petkov62452882010-09-22 16:08:37 +0200287 if (TT(ec) == TT_DATA) {
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200288 pr_cont("%s TLB %s.\n", LL_MSG(ec),
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200289 ((xec == 2) ? "locked miss"
290 : (xec ? "multimatch" : "parity")));
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200291 return;
292 }
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200293 } else if (fam_ops->dc_mce(ec, xec))
294 ;
295 else
296 pr_emerg(HW_ERR "Corrupted DC MCE info?\n");
Borislav Petkov51966242009-07-28 13:50:43 +0200297}
298
Borislav Petkov86039cd2010-11-08 15:03:35 +0100299static bool k8_ic_mce(u16 ec, u8 xec)
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200300{
Borislav Petkov62452882010-09-22 16:08:37 +0200301 u8 ll = LL(ec);
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200302 bool ret = true;
303
304 if (!MEM_ERROR(ec))
305 return false;
306
307 if (ll == 0x2)
308 pr_cont("during a linefill from L2.\n");
309 else if (ll == 0x1) {
Borislav Petkov62452882010-09-22 16:08:37 +0200310 switch (R4(ec)) {
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200311 case R4_IRD:
312 pr_cont("Parity error during data load.\n");
313 break;
314
315 case R4_EVICT:
316 pr_cont("Copyback Parity/Victim error.\n");
317 break;
318
319 case R4_SNOOP:
320 pr_cont("Tag Snoop error.\n");
321 break;
322
323 default:
324 ret = false;
325 break;
326 }
327 } else
328 ret = false;
329
330 return ret;
331}
332
Borislav Petkov86039cd2010-11-08 15:03:35 +0100333static bool f14h_ic_mce(u16 ec, u8 xec)
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200334{
Borislav Petkov62452882010-09-22 16:08:37 +0200335 u8 r4 = R4(ec);
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200336 bool ret = true;
337
338 if (MEM_ERROR(ec)) {
Borislav Petkov62452882010-09-22 16:08:37 +0200339 if (TT(ec) != 0 || LL(ec) != 1)
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200340 ret = false;
341
342 if (r4 == R4_IRD)
343 pr_cont("Data/tag array parity error for a tag hit.\n");
344 else if (r4 == R4_SNOOP)
345 pr_cont("Tag error during snoop/victimization.\n");
346 else
347 ret = false;
348 }
349 return ret;
350}
351
Borislav Petkov86039cd2010-11-08 15:03:35 +0100352static bool f15h_ic_mce(u16 ec, u8 xec)
353{
354 bool ret = true;
355
356 if (!MEM_ERROR(ec))
357 return false;
358
359 switch (xec) {
360 case 0x0 ... 0xa:
361 pr_cont("%s.\n", f15h_ic_mce_desc[xec]);
362 break;
363
364 case 0xd:
365 pr_cont("%s.\n", f15h_ic_mce_desc[xec-2]);
366 break;
367
Borislav Petkov6c1173a2011-11-21 19:45:34 +0100368 case 0x10:
369 pr_cont("%s.\n", f15h_ic_mce_desc[xec-4]);
370 break;
371
372 case 0x11 ... 0x14:
Borislav Petkov86039cd2010-11-08 15:03:35 +0100373 pr_cont("Decoder %s parity error.\n", f15h_ic_mce_desc[xec-4]);
374 break;
375
376 default:
377 ret = false;
378 }
379 return ret;
380}
381
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200382static void amd_decode_ic_mce(struct mce *m)
Borislav Petkovab5535e2009-07-28 14:06:26 +0200383{
Borislav Petkov62452882010-09-22 16:08:37 +0200384 u16 ec = EC(m->status);
385 u8 xec = XEC(m->status, xec_mask);
Borislav Petkovab5535e2009-07-28 14:06:26 +0200386
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200387 pr_emerg(HW_ERR "Instruction Cache Error: ");
Borislav Petkovab5535e2009-07-28 14:06:26 +0200388
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200389 if (TLB_ERROR(ec))
390 pr_cont("%s TLB %s.\n", LL_MSG(ec),
391 (xec ? "multimatch" : "parity error"));
392 else if (BUS_ERROR(ec)) {
Borislav Petkov525906b2010-10-15 15:27:02 +0200393 bool k8 = (boot_cpu_data.x86 == 0xf && (m->status & BIT_64(58)));
Borislav Petkovab5535e2009-07-28 14:06:26 +0200394
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200395 pr_cont("during %s.\n", (k8 ? "system linefill" : "NB data read"));
Borislav Petkov86039cd2010-11-08 15:03:35 +0100396 } else if (fam_ops->ic_mce(ec, xec))
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200397 ;
398 else
399 pr_emerg(HW_ERR "Corrupted IC MCE info?\n");
Borislav Petkovab5535e2009-07-28 14:06:26 +0200400}
401
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200402static void amd_decode_bu_mce(struct mce *m)
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200403{
Borislav Petkov62452882010-09-22 16:08:37 +0200404 u16 ec = EC(m->status);
405 u8 xec = XEC(m->status, xec_mask);
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200406
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200407 pr_emerg(HW_ERR "Bus Unit Error");
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200408
409 if (xec == 0x1)
410 pr_cont(" in the write data buffers.\n");
411 else if (xec == 0x3)
412 pr_cont(" in the victim data buffers.\n");
413 else if (xec == 0x2 && MEM_ERROR(ec))
Borislav Petkov62452882010-09-22 16:08:37 +0200414 pr_cont(": %s error in the L2 cache tags.\n", R4_MSG(ec));
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200415 else if (xec == 0x0) {
416 if (TLB_ERROR(ec))
417 pr_cont(": %s error in a Page Descriptor Cache or "
418 "Guest TLB.\n", TT_MSG(ec));
419 else if (BUS_ERROR(ec))
420 pr_cont(": %s/ECC error in data read from NB: %s.\n",
Borislav Petkov62452882010-09-22 16:08:37 +0200421 R4_MSG(ec), PP_MSG(ec));
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200422 else if (MEM_ERROR(ec)) {
Borislav Petkov62452882010-09-22 16:08:37 +0200423 u8 r4 = R4(ec);
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200424
Borislav Petkov62452882010-09-22 16:08:37 +0200425 if (r4 >= 0x7)
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200426 pr_cont(": %s error during data copyback.\n",
Borislav Petkov62452882010-09-22 16:08:37 +0200427 R4_MSG(ec));
428 else if (r4 <= 0x1)
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200429 pr_cont(": %s parity/ECC error during data "
Borislav Petkov62452882010-09-22 16:08:37 +0200430 "access from L2.\n", R4_MSG(ec));
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200431 else
432 goto wrong_bu_mce;
433 } else
434 goto wrong_bu_mce;
435 } else
436 goto wrong_bu_mce;
437
438 return;
439
440wrong_bu_mce:
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200441 pr_emerg(HW_ERR "Corrupted BU MCE info?\n");
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200442}
443
Borislav Petkov70fdb492010-09-21 20:45:10 +0200444static void amd_decode_cu_mce(struct mce *m)
445{
Borislav Petkov62452882010-09-22 16:08:37 +0200446 u16 ec = EC(m->status);
447 u8 xec = XEC(m->status, xec_mask);
Borislav Petkov70fdb492010-09-21 20:45:10 +0200448
449 pr_emerg(HW_ERR "Combined Unit Error: ");
450
451 if (TLB_ERROR(ec)) {
452 if (xec == 0x0)
453 pr_cont("Data parity TLB read error.\n");
454 else if (xec == 0x1)
455 pr_cont("Poison data provided for TLB fill.\n");
456 else
457 goto wrong_cu_mce;
458 } else if (BUS_ERROR(ec)) {
459 if (xec > 2)
460 goto wrong_cu_mce;
461
462 pr_cont("Error during attempted NB data read.\n");
463 } else if (MEM_ERROR(ec)) {
464 switch (xec) {
465 case 0x4 ... 0xc:
466 pr_cont("%s.\n", f15h_cu_mce_desc[xec - 0x4]);
467 break;
468
469 case 0x10 ... 0x14:
470 pr_cont("%s.\n", f15h_cu_mce_desc[xec - 0x7]);
471 break;
472
473 default:
474 goto wrong_cu_mce;
475 }
476 }
477
478 return;
479
480wrong_cu_mce:
481 pr_emerg(HW_ERR "Corrupted CU MCE info?\n");
482}
483
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200484static void amd_decode_ls_mce(struct mce *m)
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200485{
Borislav Petkov62452882010-09-22 16:08:37 +0200486 u16 ec = EC(m->status);
487 u8 xec = XEC(m->status, xec_mask);
Borislav Petkovded50622010-08-27 17:03:34 +0200488
Borislav Petkovb18434c2010-09-22 11:53:32 +0200489 if (boot_cpu_data.x86 >= 0x14) {
Borislav Petkovded50622010-08-27 17:03:34 +0200490 pr_emerg("You shouldn't be seeing an LS MCE on this cpu family,"
491 " please report on LKML.\n");
492 return;
493 }
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200494
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200495 pr_emerg(HW_ERR "Load Store Error");
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200496
497 if (xec == 0x0) {
Borislav Petkov62452882010-09-22 16:08:37 +0200498 u8 r4 = R4(ec);
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200499
Borislav Petkovded50622010-08-27 17:03:34 +0200500 if (!BUS_ERROR(ec) || (r4 != R4_DRD && r4 != R4_DWR))
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200501 goto wrong_ls_mce;
502
Borislav Petkov62452882010-09-22 16:08:37 +0200503 pr_cont(" during %s.\n", R4_MSG(ec));
Borislav Petkovded50622010-08-27 17:03:34 +0200504 } else
505 goto wrong_ls_mce;
506
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200507 return;
508
509wrong_ls_mce:
Borislav Petkovc9f281f2010-08-18 18:21:42 +0200510 pr_emerg(HW_ERR "Corrupted LS MCE info?\n");
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200511}
512
Borislav Petkov68782672011-11-24 21:29:57 +0100513void amd_decode_nb_mce(struct mce *m)
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200514{
Borislav Petkov68782672011-11-24 21:29:57 +0100515 struct cpuinfo_x86 *c = &boot_cpu_data;
516 int node_id = amd_get_nb_id(m->extcpu);
517 u16 ec = EC(m->status);
518 u8 xec = XEC(m->status, 0x1f);
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200519 u8 offset = 0;
520
Borislav Petkov68782672011-11-24 21:29:57 +0100521 pr_emerg(HW_ERR "Northbridge Error (node %d): ", node_id);
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200522
Borislav Petkov68782672011-11-24 21:29:57 +0100523 switch (xec) {
524 case 0x0 ... 0xe:
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200525
Borislav Petkov68782672011-11-24 21:29:57 +0100526 /* special handling for DRAM ECCs */
527 if (xec == 0x0 || xec == 0x8) {
528 /* no ECCs on F11h */
529 if (c->x86 == 0x11)
530 goto wrong_nb_mce;
531
532 pr_cont("%s.\n", nb_mce_desc[xec]);
533
534 if (nb_bus_decoder)
535 nb_bus_decoder(node_id, m);
536 return;
537 }
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200538 break;
539
540 case 0xf:
541 if (TLB_ERROR(ec))
542 pr_cont("GART Table Walk data error.\n");
543 else if (BUS_ERROR(ec))
544 pr_cont("DMA Exclusion Vector Table Walk error.\n");
545 else
Borislav Petkov68782672011-11-24 21:29:57 +0100546 goto wrong_nb_mce;
547 return;
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200548
Borislav Petkov05cd6672010-09-22 15:06:24 +0200549 case 0x19:
550 if (boot_cpu_data.x86 == 0x15)
551 pr_cont("Compute Unit Data Error.\n");
552 else
Borislav Petkov68782672011-11-24 21:29:57 +0100553 goto wrong_nb_mce;
554 return;
Borislav Petkov05cd6672010-09-22 15:06:24 +0200555
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200556 case 0x1c ... 0x1f:
Borislav Petkov68782672011-11-24 21:29:57 +0100557 offset = 13;
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200558 break;
559
560 default:
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200561 goto wrong_nb_mce;
Borislav Petkov68782672011-11-24 21:29:57 +0100562 }
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200563
Borislav Petkov68782672011-11-24 21:29:57 +0100564 pr_cont("%s.\n", nb_mce_desc[xec - offset]);
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200565 return;
566
567wrong_nb_mce:
568 pr_emerg(HW_ERR "Corrupted NB MCE info?\n");
Borislav Petkovd93cc222009-07-28 10:56:15 +0200569}
570EXPORT_SYMBOL_GPL(amd_decode_nb_mce);
571
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200572static void amd_decode_fr_mce(struct mce *m)
Borislav Petkov53bd5fe2009-07-28 14:20:46 +0200573{
Borislav Petkov8259a7e2010-09-22 15:28:59 +0200574 struct cpuinfo_x86 *c = &boot_cpu_data;
Borislav Petkov62452882010-09-22 16:08:37 +0200575 u8 xec = XEC(m->status, xec_mask);
Borislav Petkov8259a7e2010-09-22 15:28:59 +0200576
577 if (c->x86 == 0xf || c->x86 == 0x11)
Borislav Petkovfe4ea262010-08-31 18:38:24 +0200578 goto wrong_fr_mce;
579
Borislav Petkov8259a7e2010-09-22 15:28:59 +0200580 if (c->x86 != 0x15 && xec != 0x0)
581 goto wrong_fr_mce;
582
583 pr_emerg(HW_ERR "%s Error: ",
584 (c->x86 == 0x15 ? "Execution Unit" : "FIROB"));
585
586 if (xec == 0x0 || xec == 0xc)
587 pr_cont("%s.\n", fr_ex_mce_desc[xec]);
588 else if (xec < 0xd)
589 pr_cont("%s parity error.\n", fr_ex_mce_desc[xec]);
590 else
591 goto wrong_fr_mce;
592
593 return;
Borislav Petkovfe4ea262010-08-31 18:38:24 +0200594
595wrong_fr_mce:
596 pr_emerg(HW_ERR "Corrupted FR MCE info?\n");
Borislav Petkov53bd5fe2009-07-28 14:20:46 +0200597}
598
Borislav Petkovb8f85c42010-09-22 15:37:58 +0200599static void amd_decode_fp_mce(struct mce *m)
600{
Borislav Petkov62452882010-09-22 16:08:37 +0200601 u8 xec = XEC(m->status, xec_mask);
Borislav Petkovb8f85c42010-09-22 15:37:58 +0200602
603 pr_emerg(HW_ERR "Floating Point Unit Error: ");
604
605 switch (xec) {
606 case 0x1:
607 pr_cont("Free List");
608 break;
609
610 case 0x2:
611 pr_cont("Physical Register File");
612 break;
613
614 case 0x3:
615 pr_cont("Retire Queue");
616 break;
617
618 case 0x4:
619 pr_cont("Scheduler table");
620 break;
621
622 case 0x5:
623 pr_cont("Status Register File");
624 break;
625
626 default:
627 goto wrong_fp_mce;
628 break;
629 }
630
631 pr_cont(" parity error.\n");
632
633 return;
634
635wrong_fp_mce:
636 pr_emerg(HW_ERR "Corrupted FP MCE info?\n");
637}
638
Borislav Petkov63375832010-09-06 18:13:39 +0200639static inline void amd_decode_err_code(u16 ec)
Borislav Petkovd93cc222009-07-28 10:56:15 +0200640{
Borislav Petkovfa7ae8c2010-09-22 17:42:27 +0200641
642 pr_emerg(HW_ERR "cache level: %s", LL_MSG(ec));
643
644 if (BUS_ERROR(ec))
645 pr_cont(", mem/io: %s", II_MSG(ec));
646 else
647 pr_cont(", tx: %s", TT_MSG(ec));
648
649 if (MEM_ERROR(ec) || BUS_ERROR(ec)) {
650 pr_cont(", mem-tx: %s", R4_MSG(ec));
651
652 if (BUS_ERROR(ec))
653 pr_cont(", part-proc: %s (%s)", PP_MSG(ec), TO_MSG(ec));
654 }
655
656 pr_cont("\n");
Borislav Petkov549d0422009-07-24 13:51:42 +0200657}
Borislav Petkov549d0422009-07-24 13:51:42 +0200658
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200659/*
660 * Filter out unwanted MCE signatures here.
661 */
662static bool amd_filter_mce(struct mce *m)
663{
664 u8 xec = (m->status >> 16) & 0x1f;
665
666 /*
667 * NB GART TLB error reporting is disabled by default.
668 */
669 if (m->bank == 4 && xec == 0x5 && !report_gart_errors)
670 return true;
671
672 return false;
673}
674
Borislav Petkov9cdeb402010-09-02 18:33:24 +0200675int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
Borislav Petkov549d0422009-07-24 13:51:42 +0200676{
Borislav Petkovfb253192009-10-07 13:20:38 +0200677 struct mce *m = (struct mce *)data;
Borislav Petkovfa7ae8c2010-09-22 17:42:27 +0200678 struct cpuinfo_x86 *c = &boot_cpu_data;
Borislav Petkovb0b07a22011-08-24 18:44:22 +0200679 int ecc;
Borislav Petkov549d0422009-07-24 13:51:42 +0200680
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200681 if (amd_filter_mce(m))
682 return NOTIFY_STOP;
683
Borislav Petkov086be782011-09-30 16:34:44 +0200684 pr_emerg(HW_ERR "CPU:%d\tMC%d_STATUS[%s|%s|%s|%s|%s",
Borislav Petkovbff7b812011-08-04 19:25:24 +0200685 m->extcpu, m->bank,
Borislav Petkovfa7ae8c2010-09-22 17:42:27 +0200686 ((m->status & MCI_STATUS_OVER) ? "Over" : "-"),
687 ((m->status & MCI_STATUS_UC) ? "UE" : "CE"),
688 ((m->status & MCI_STATUS_MISCV) ? "MiscV" : "-"),
689 ((m->status & MCI_STATUS_PCC) ? "PCC" : "-"),
690 ((m->status & MCI_STATUS_ADDRV) ? "AddrV" : "-"));
Borislav Petkov549d0422009-07-24 13:51:42 +0200691
Borislav Petkovfa7ae8c2010-09-22 17:42:27 +0200692 if (c->x86 == 0x15)
693 pr_cont("|%s|%s",
Randy Dunlap50adbbd2010-11-13 11:44:26 -0500694 ((m->status & BIT_64(44)) ? "Deferred" : "-"),
695 ((m->status & BIT_64(43)) ? "Poison" : "-"));
Borislav Petkov549d0422009-07-24 13:51:42 +0200696
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200697 /* do the two bits[14:13] together */
Borislav Petkov35d824b2010-04-30 15:19:02 +0200698 ecc = (m->status >> 45) & 0x3;
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200699 if (ecc)
Borislav Petkovfa7ae8c2010-09-22 17:42:27 +0200700 pr_cont("|%sECC", ((ecc == 2) ? "C" : "U"));
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200701
Borislav Petkovfa7ae8c2010-09-22 17:42:27 +0200702 pr_cont("]: 0x%016llx\n", m->status);
703
Borislav Petkov086be782011-09-30 16:34:44 +0200704 if (m->status & MCI_STATUS_ADDRV)
705 pr_emerg(HW_ERR "\tMC%d_ADDR: 0x%016llx\n", m->bank, m->addr);
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200706
Borislav Petkov51966242009-07-28 13:50:43 +0200707 switch (m->bank) {
708 case 0:
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200709 amd_decode_dc_mce(m);
Borislav Petkov51966242009-07-28 13:50:43 +0200710 break;
Borislav Petkovd93cc222009-07-28 10:56:15 +0200711
Borislav Petkovab5535e2009-07-28 14:06:26 +0200712 case 1:
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200713 amd_decode_ic_mce(m);
Borislav Petkovab5535e2009-07-28 14:06:26 +0200714 break;
715
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200716 case 2:
Borislav Petkovfa7ae8c2010-09-22 17:42:27 +0200717 if (c->x86 == 0x15)
Borislav Petkov70fdb492010-09-21 20:45:10 +0200718 amd_decode_cu_mce(m);
719 else
720 amd_decode_bu_mce(m);
Borislav Petkov56cad2d2009-07-28 14:14:24 +0200721 break;
722
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200723 case 3:
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200724 amd_decode_ls_mce(m);
Borislav Petkovf9350ef2009-07-28 14:17:30 +0200725 break;
726
Borislav Petkov51966242009-07-28 13:50:43 +0200727 case 4:
Borislav Petkovb0b07a22011-08-24 18:44:22 +0200728 amd_decode_nb_mce(m);
Borislav Petkov51966242009-07-28 13:50:43 +0200729 break;
730
Borislav Petkov53bd5fe2009-07-28 14:20:46 +0200731 case 5:
Borislav Petkov7cfd4a82010-09-01 14:45:20 +0200732 amd_decode_fr_mce(m);
Borislav Petkov53bd5fe2009-07-28 14:20:46 +0200733 break;
734
Borislav Petkovb8f85c42010-09-22 15:37:58 +0200735 case 6:
736 amd_decode_fp_mce(m);
737 break;
738
Borislav Petkov51966242009-07-28 13:50:43 +0200739 default:
740 break;
Borislav Petkovb69b29d2009-07-27 16:21:14 +0200741 }
Borislav Petkov51966242009-07-28 13:50:43 +0200742
743 amd_decode_err_code(m->status & 0xffff);
Borislav Petkovfb253192009-10-07 13:20:38 +0200744
745 return NOTIFY_STOP;
Borislav Petkov549d0422009-07-24 13:51:42 +0200746}
Borislav Petkov9cdeb402010-09-02 18:33:24 +0200747EXPORT_SYMBOL_GPL(amd_decode_mce);
Ingo Molnarf436f8b2009-10-01 16:14:32 +0200748
Borislav Petkovfb253192009-10-07 13:20:38 +0200749static struct notifier_block amd_mce_dec_nb = {
750 .notifier_call = amd_decode_mce,
751};
752
Ingo Molnarf436f8b2009-10-01 16:14:32 +0200753static int __init mce_amd_init(void)
754{
Borislav Petkovbad11e02010-09-22 17:44:51 +0200755 struct cpuinfo_x86 *c = &boot_cpu_data;
756
757 if (c->x86_vendor != X86_VENDOR_AMD)
Borislav Petkove045c292010-08-06 18:55:45 +0200758 return 0;
759
Borislav Petkovbad11e02010-09-22 17:44:51 +0200760 if ((c->x86 < 0xf || c->x86 > 0x12) &&
761 (c->x86 != 0x14 || c->x86_model > 0xf) &&
762 (c->x86 != 0x15 || c->x86_model > 0xf))
Borislav Petkove045c292010-08-06 18:55:45 +0200763 return 0;
764
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200765 fam_ops = kzalloc(sizeof(struct amd_decoder_ops), GFP_KERNEL);
766 if (!fam_ops)
767 return -ENOMEM;
768
Borislav Petkovbad11e02010-09-22 17:44:51 +0200769 switch (c->x86) {
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200770 case 0xf:
771 fam_ops->dc_mce = k8_dc_mce;
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200772 fam_ops->ic_mce = k8_ic_mce;
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200773 break;
774
775 case 0x10:
776 fam_ops->dc_mce = f10h_dc_mce;
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200777 fam_ops->ic_mce = k8_ic_mce;
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200778 break;
779
Borislav Petkovf0157b32010-10-05 19:07:16 +0200780 case 0x11:
781 fam_ops->dc_mce = k8_dc_mce;
782 fam_ops->ic_mce = k8_ic_mce;
Borislav Petkovf0157b32010-10-05 19:07:16 +0200783 break;
784
Borislav Petkov9be0bb12010-09-16 15:08:14 +0200785 case 0x12:
786 fam_ops->dc_mce = f12h_dc_mce;
Borislav Petkove7281eb2010-09-16 16:45:22 +0200787 fam_ops->ic_mce = k8_ic_mce;
Borislav Petkov9be0bb12010-09-16 15:08:14 +0200788 break;
789
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200790 case 0x14:
Borislav Petkov5ce88f62010-08-31 18:28:08 +0200791 nb_err_cpumask = 0x3;
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200792 fam_ops->dc_mce = f14h_dc_mce;
Borislav Petkovdd53bce2010-08-26 19:05:49 +0200793 fam_ops->ic_mce = f14h_ic_mce;
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200794 break;
795
Borislav Petkov2be64bf2010-09-17 19:11:47 +0200796 case 0x15:
797 xec_mask = 0x1f;
Borislav Petkov25a4f8b2010-09-17 19:22:34 +0200798 fam_ops->dc_mce = f15h_dc_mce;
Borislav Petkov86039cd2010-11-08 15:03:35 +0100799 fam_ops->ic_mce = f15h_ic_mce;
Borislav Petkov2be64bf2010-09-17 19:11:47 +0200800 break;
801
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200802 default:
Borislav Petkovbad11e02010-09-22 17:44:51 +0200803 printk(KERN_WARNING "Huh? What family is that: %d?!\n", c->x86);
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200804 kfree(fam_ops);
805 return -EINVAL;
806 }
807
Borislav Petkov9530d602010-09-06 15:05:45 +0200808 pr_info("MCE: In-kernel MCE decoding enabled.\n");
809
Borislav Petkov3653ada2011-12-04 15:12:09 +0100810 mce_register_decode_chain(&amd_mce_dec_nb);
Ingo Molnarf436f8b2009-10-01 16:14:32 +0200811
812 return 0;
813}
814early_initcall(mce_amd_init);
Borislav Petkov0d18b2e2009-10-02 15:31:48 +0200815
816#ifdef MODULE
817static void __exit mce_amd_exit(void)
818{
Borislav Petkov3653ada2011-12-04 15:12:09 +0100819 mce_unregister_decode_chain(&amd_mce_dec_nb);
Borislav Petkov888ab8e2010-08-18 15:11:35 +0200820 kfree(fam_ops);
Borislav Petkov0d18b2e2009-10-02 15:31:48 +0200821}
822
823MODULE_DESCRIPTION("AMD MCE decoder");
824MODULE_ALIAS("edac-mce-amd");
825MODULE_LICENSE("GPL");
826module_exit(mce_amd_exit);
827#endif