Blame view

drivers/edac/mce_amd.c 17.1 KB
b70ef0101   Borislav Petkov   EDAC: move MCE er...
1
  #include <linux/module.h>
888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
2
  #include <linux/slab.h>
47ca08a40   Borislav Petkov   EDAC, MCE: Rename...
3
  #include "mce_amd.h"
b52401cec   Doug Thompson   amd64_edac: add M...
4

888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
5
  static struct amd_decoder_ops *fam_ops;
2be64bfac   Borislav Petkov   EDAC, MCE: Select...
6
  static u8 xec_mask	 = 0xf;
5ce88f6ea   Borislav Petkov   EDAC, MCE: Comple...
7
  static u8 nb_err_cpumask = 0xf;
549d042df   Borislav Petkov   x86, mce: pass mc...
8
  static bool report_gart_errors;
b0b07a2bd   Borislav Petkov   EDAC, MCE, AMD: S...
9
  static void (*nb_bus_decoder)(int node_id, struct mce *m);
549d042df   Borislav Petkov   x86, mce: pass mc...
10
11
12
13
14
15
  
  void amd_report_gart_errors(bool v)
  {
  	report_gart_errors = v;
  }
  EXPORT_SYMBOL_GPL(amd_report_gart_errors);
b0b07a2bd   Borislav Petkov   EDAC, MCE, AMD: S...
16
  void amd_register_ecc_decoder(void (*f)(int, struct mce *))
549d042df   Borislav Petkov   x86, mce: pass mc...
17
18
19
20
  {
  	nb_bus_decoder = f;
  }
  EXPORT_SYMBOL_GPL(amd_register_ecc_decoder);
b0b07a2bd   Borislav Petkov   EDAC, MCE, AMD: S...
21
  void amd_unregister_ecc_decoder(void (*f)(int, struct mce *))
549d042df   Borislav Petkov   x86, mce: pass mc...
22
23
24
25
26
27
28
29
  {
  	if (nb_bus_decoder) {
  		WARN_ON(nb_bus_decoder != f);
  
  		nb_bus_decoder = NULL;
  	}
  }
  EXPORT_SYMBOL_GPL(amd_unregister_ecc_decoder);
b52401cec   Doug Thompson   amd64_edac: add M...
30
31
32
33
  /*
   * string representation for the different MCA reported error types, see F3x48
   * or MSR0000_0411.
   */
6337583d7   Borislav Petkov   EDAC, MCE: Saniti...
34
35
36
  
  /* transaction type */
  const char *tt_msgs[] = { "INSN", "DATA", "GEN", "RESV" };
b70ef0101   Borislav Petkov   EDAC: move MCE er...
37
  EXPORT_SYMBOL_GPL(tt_msgs);
b52401cec   Doug Thompson   amd64_edac: add M...
38

6337583d7   Borislav Petkov   EDAC, MCE: Saniti...
39
40
  /* cache level */
  const char *ll_msgs[] = { "RESV", "L1", "L2", "L3/GEN" };
b70ef0101   Borislav Petkov   EDAC: move MCE er...
41
  EXPORT_SYMBOL_GPL(ll_msgs);
b52401cec   Doug Thompson   amd64_edac: add M...
42

6337583d7   Borislav Petkov   EDAC, MCE: Saniti...
43
  /* memory transaction type */
b52401cec   Doug Thompson   amd64_edac: add M...
44
  const char *rrrr_msgs[] = {
6337583d7   Borislav Petkov   EDAC, MCE: Saniti...
45
         "GEN", "RD", "WR", "DRD", "DWR", "IRD", "PRF", "EV", "SNP"
b52401cec   Doug Thompson   amd64_edac: add M...
46
  };
b70ef0101   Borislav Petkov   EDAC: move MCE er...
47
  EXPORT_SYMBOL_GPL(rrrr_msgs);
b52401cec   Doug Thompson   amd64_edac: add M...
48

6337583d7   Borislav Petkov   EDAC, MCE: Saniti...
49
50
  /* participating processor */
  const char *pp_msgs[] = { "SRC", "RES", "OBS", "GEN" };
b70ef0101   Borislav Petkov   EDAC: move MCE er...
51
  EXPORT_SYMBOL_GPL(pp_msgs);
b52401cec   Doug Thompson   amd64_edac: add M...
52

6337583d7   Borislav Petkov   EDAC, MCE: Saniti...
53
54
  /* request timeout */
  const char *to_msgs[] = { "no timeout",	"timed out" };
b70ef0101   Borislav Petkov   EDAC: move MCE er...
55
  EXPORT_SYMBOL_GPL(to_msgs);
b52401cec   Doug Thompson   amd64_edac: add M...
56

6337583d7   Borislav Petkov   EDAC, MCE: Saniti...
57
58
  /* memory or i/o */
  const char *ii_msgs[] = { "MEM", "RESV", "IO", "GEN" };
b70ef0101   Borislav Petkov   EDAC: move MCE er...
59
  EXPORT_SYMBOL_GPL(ii_msgs);
b52401cec   Doug Thompson   amd64_edac: add M...
60

5ce88f6ea   Borislav Petkov   EDAC, MCE: Comple...
61
62
63
64
65
66
67
68
69
  static const char *f10h_nb_mce_desc[] = {
  	"HT link data error",
  	"Protocol error (link, L3, probe filter, etc.)",
  	"Parity error in NB-internal arrays",
  	"Link Retry due to IO link transmission error",
  	"L3 ECC data cache error",
  	"ECC error in L3 cache tag",
  	"L3 LRU parity bits error",
  	"ECC Error in the Probe Filter directory"
b52401cec   Doug Thompson   amd64_edac: add M...
70
  };
549d042df   Borislav Petkov   x86, mce: pass mc...
71

86039cd40   Borislav Petkov   EDAC, MCE: Add F1...
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
  static const char * const f15h_ic_mce_desc[] = {
  	"UC during a demand linefill from L2",
  	"Parity error during data load from IC",
  	"Parity error for IC valid bit",
  	"Main tag parity error",
  	"Parity error in prediction queue",
  	"PFB data/address parity error",
  	"Parity error in the branch status reg",
  	"PFB promotion address error",
  	"Tag error during probe/victimization",
  	"Parity error for IC probe tag valid bit",
  	"PFB non-cacheable bit parity error",
  	"PFB valid bit parity error",			/* xec = 0xd */
  	"patch RAM",					/* xec = 010 */
  	"uop queue",
  	"insn buffer",
  	"predecode buffer",
  	"fetch address FIFO"
  };
70fdb494a   Borislav Petkov   EDAC, MCE: Add F1...
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
  static const char * const f15h_cu_mce_desc[] = {
  	"Fill ECC error on data fills",			/* xec = 0x4 */
  	"Fill parity error on insn fills",
  	"Prefetcher request FIFO parity error",
  	"PRQ address parity error",
  	"PRQ data parity error",
  	"WCC Tag ECC error",
  	"WCC Data ECC error",
  	"WCB Data parity error",
  	"VB Data/ECC error",
  	"L2 Tag ECC error",				/* xec = 0x10 */
  	"Hard L2 Tag ECC error",
  	"Multiple hits on L2 tag",
  	"XAB parity error",
  	"PRB address parity error"
  };
8259a7e57   Borislav Petkov   EDAC, MCE: Add F1...
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
  static const char * const fr_ex_mce_desc[] = {
  	"CPU Watchdog timer expire",
  	"Wakeup array dest tag",
  	"AG payload array",
  	"EX payload array",
  	"IDRF array",
  	"Retire dispatch queue",
  	"Mapper checkpoint array",
  	"Physical register file EX0 port",
  	"Physical register file EX1 port",
  	"Physical register file AG0 port",
  	"Physical register file AG1 port",
  	"Flag register file",
  	"DE correctable error could not be corrected"
  };
25a4f8b05   Borislav Petkov   EDAC, MCE: Add F1...
122
  static bool f12h_dc_mce(u16 ec, u8 xec)
519662413   Borislav Petkov   EDAC, AMD: decode...
123
  {
888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
124
  	bool ret = false;
519662413   Borislav Petkov   EDAC, AMD: decode...
125

888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
126
  	if (MEM_ERROR(ec)) {
624528823   Borislav Petkov   EDAC, MCE: Overha...
127
  		u8 ll = LL(ec);
888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
128
  		ret = true;
519662413   Borislav Petkov   EDAC, AMD: decode...
129

888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
130
131
132
133
  		if (ll == LL_L2)
  			pr_cont("during L1 linefill from L2.
  ");
  		else if (ll == LL_L1)
624528823   Borislav Petkov   EDAC, MCE: Overha...
134
135
  			pr_cont("Data/Tag %s error.
  ", R4_MSG(ec));
888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
136
137
138
139
140
  		else
  			ret = false;
  	}
  	return ret;
  }
519662413   Borislav Petkov   EDAC, AMD: decode...
141

25a4f8b05   Borislav Petkov   EDAC, MCE: Add F1...
142
  static bool f10h_dc_mce(u16 ec, u8 xec)
9be0bb107   Borislav Petkov   EDAC, MCE: Add F1...
143
  {
624528823   Borislav Petkov   EDAC, MCE: Overha...
144
  	if (R4(ec) == R4_GEN && LL(ec) == LL_L1) {
9be0bb107   Borislav Petkov   EDAC, MCE: Add F1...
145
146
147
148
  		pr_cont("during data scrub.
  ");
  		return true;
  	}
25a4f8b05   Borislav Petkov   EDAC, MCE: Add F1...
149
  	return f12h_dc_mce(ec, xec);
9be0bb107   Borislav Petkov   EDAC, MCE: Add F1...
150
  }
25a4f8b05   Borislav Petkov   EDAC, MCE: Add F1...
151
  static bool k8_dc_mce(u16 ec, u8 xec)
888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
152
153
154
155
156
157
  {
  	if (BUS_ERROR(ec)) {
  		pr_cont("during system linefill.
  ");
  		return true;
  	}
519662413   Borislav Petkov   EDAC, AMD: decode...
158

25a4f8b05   Borislav Petkov   EDAC, MCE: Add F1...
159
  	return f10h_dc_mce(ec, xec);
888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
160
  }
25a4f8b05   Borislav Petkov   EDAC, MCE: Add F1...
161
  static bool f14h_dc_mce(u16 ec, u8 xec)
888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
162
  {
624528823   Borislav Petkov   EDAC, MCE: Overha...
163
  	u8 r4	 = R4(ec);
888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
164
165
166
  	bool ret = true;
  
  	if (MEM_ERROR(ec)) {
624528823   Borislav Petkov   EDAC, MCE: Overha...
167
  		if (TT(ec) != TT_DATA || LL(ec) != LL_L1)
888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
  			return false;
  
  		switch (r4) {
  		case R4_DRD:
  		case R4_DWR:
  			pr_cont("Data/Tag parity error due to %s.
  ",
  				(r4 == R4_DRD ? "load/hw prf" : "store"));
  			break;
  		case R4_EVICT:
  			pr_cont("Copyback parity error on a tag miss.
  ");
  			break;
  		case R4_SNOOP:
  			pr_cont("Tag parity error during snoop.
  ");
  			break;
  		default:
  			ret = false;
  		}
  	} else if (BUS_ERROR(ec)) {
624528823   Borislav Petkov   EDAC, MCE: Overha...
189
  		if ((II(ec) != II_MEM && II(ec) != II_IO) || LL(ec) != LL_LG)
888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
  			return false;
  
  		pr_cont("System read data error on a ");
  
  		switch (r4) {
  		case R4_RD:
  			pr_cont("TLB reload.
  ");
  			break;
  		case R4_DWR:
  			pr_cont("store.
  ");
  			break;
  		case R4_DRD:
  			pr_cont("load.
  ");
  			break;
  		default:
  			ret = false;
  		}
  	} else {
  		ret = false;
  	}
  
  	return ret;
  }
25a4f8b05   Borislav Petkov   EDAC, MCE: Add F1...
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
  static bool f15h_dc_mce(u16 ec, u8 xec)
  {
  	bool ret = true;
  
  	if (MEM_ERROR(ec)) {
  
  		switch (xec) {
  		case 0x0:
  			pr_cont("Data Array access error.
  ");
  			break;
  
  		case 0x1:
  			pr_cont("UC error during a linefill from L2/NB.
  ");
  			break;
  
  		case 0x2:
  		case 0x11:
  			pr_cont("STQ access error.
  ");
  			break;
  
  		case 0x3:
  			pr_cont("SCB access error.
  ");
  			break;
  
  		case 0x10:
  			pr_cont("Tag error.
  ");
  			break;
  
  		case 0x12:
  			pr_cont("LDQ access error.
  ");
  			break;
  
  		default:
  			ret = false;
  		}
  	} else if (BUS_ERROR(ec)) {
  
  		if (!xec)
  			pr_cont("during system linefill.
  ");
  		else
  			pr_cont(" Internal %s condition.
  ",
  				((xec == 1) ? "livelock" : "deadlock"));
  	} else
  		ret = false;
  
  	return ret;
  }
888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
271
272
  static void amd_decode_dc_mce(struct mce *m)
  {
624528823   Borislav Petkov   EDAC, MCE: Overha...
273
274
  	u16 ec = EC(m->status);
  	u8 xec = XEC(m->status, xec_mask);
888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
275
276
277
278
279
  
  	pr_emerg(HW_ERR "Data Cache Error: ");
  
  	/* TLB error signatures are the same across families */
  	if (TLB_ERROR(ec)) {
624528823   Borislav Petkov   EDAC, MCE: Overha...
280
  		if (TT(ec) == TT_DATA) {
888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
281
282
  			pr_cont("%s TLB %s.
  ", LL_MSG(ec),
25a4f8b05   Borislav Petkov   EDAC, MCE: Add F1...
283
284
  				((xec == 2) ? "locked miss"
  					    : (xec ? "multimatch" : "parity")));
888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
285
286
  			return;
  		}
25a4f8b05   Borislav Petkov   EDAC, MCE: Add F1...
287
288
289
290
291
  	} else if (fam_ops->dc_mce(ec, xec))
  		;
  	else
  		pr_emerg(HW_ERR "Corrupted DC MCE info?
  ");
519662413   Borislav Petkov   EDAC, AMD: decode...
292
  }
86039cd40   Borislav Petkov   EDAC, MCE: Add F1...
293
  static bool k8_ic_mce(u16 ec, u8 xec)
ab5535e70   Borislav Petkov   EDAC, AMD: decode...
294
  {
624528823   Borislav Petkov   EDAC, MCE: Overha...
295
  	u8 ll	 = LL(ec);
dd53bce4e   Borislav Petkov   EDAC, MCE: Adjust...
296
  	bool ret = true;
ab5535e70   Borislav Petkov   EDAC, AMD: decode...
297

dd53bce4e   Borislav Petkov   EDAC, MCE: Adjust...
298
299
  	if (!MEM_ERROR(ec))
  		return false;
ab5535e70   Borislav Petkov   EDAC, AMD: decode...
300

dd53bce4e   Borislav Petkov   EDAC, MCE: Adjust...
301
302
303
304
  	if (ll == 0x2)
  		pr_cont("during a linefill from L2.
  ");
  	else if (ll == 0x1) {
624528823   Borislav Petkov   EDAC, MCE: Overha...
305
  		switch (R4(ec)) {
dd53bce4e   Borislav Petkov   EDAC, MCE: Adjust...
306
307
308
309
  		case R4_IRD:
  			pr_cont("Parity error during data load.
  ");
  			break;
ab5535e70   Borislav Petkov   EDAC, AMD: decode...
310

dd53bce4e   Borislav Petkov   EDAC, MCE: Adjust...
311
312
313
314
315
316
317
318
319
320
321
322
323
324
  		case R4_EVICT:
  			pr_cont("Copyback Parity/Victim error.
  ");
  			break;
  
  		case R4_SNOOP:
  			pr_cont("Tag Snoop error.
  ");
  			break;
  
  		default:
  			ret = false;
  			break;
  		}
ab5535e70   Borislav Petkov   EDAC, AMD: decode...
325
  	} else
dd53bce4e   Borislav Petkov   EDAC, MCE: Adjust...
326
  		ret = false;
ab5535e70   Borislav Petkov   EDAC, AMD: decode...
327

dd53bce4e   Borislav Petkov   EDAC, MCE: Adjust...
328
329
  	return ret;
  }
86039cd40   Borislav Petkov   EDAC, MCE: Add F1...
330
  static bool f14h_ic_mce(u16 ec, u8 xec)
dd53bce4e   Borislav Petkov   EDAC, MCE: Adjust...
331
  {
624528823   Borislav Petkov   EDAC, MCE: Overha...
332
  	u8 r4    = R4(ec);
dd53bce4e   Borislav Petkov   EDAC, MCE: Adjust...
333
  	bool ret = true;
ab5535e70   Borislav Petkov   EDAC, AMD: decode...
334

dd53bce4e   Borislav Petkov   EDAC, MCE: Adjust...
335
  	if (MEM_ERROR(ec)) {
624528823   Borislav Petkov   EDAC, MCE: Overha...
336
  		if (TT(ec) != 0 || LL(ec) != 1)
dd53bce4e   Borislav Petkov   EDAC, MCE: Adjust...
337
338
339
340
341
342
343
344
345
346
347
348
349
  			ret = false;
  
  		if (r4 == R4_IRD)
  			pr_cont("Data/tag array parity error for a tag hit.
  ");
  		else if (r4 == R4_SNOOP)
  			pr_cont("Tag error during snoop/victimization.
  ");
  		else
  			ret = false;
  	}
  	return ret;
  }
86039cd40   Borislav Petkov   EDAC, MCE: Add F1...
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
  static bool f15h_ic_mce(u16 ec, u8 xec)
  {
  	bool ret = true;
  
  	if (!MEM_ERROR(ec))
  		return false;
  
  	switch (xec) {
  	case 0x0 ... 0xa:
  		pr_cont("%s.
  ", f15h_ic_mce_desc[xec]);
  		break;
  
  	case 0xd:
  		pr_cont("%s.
  ", f15h_ic_mce_desc[xec-2]);
  		break;
  
  	case 0x10 ... 0x14:
  		pr_cont("Decoder %s parity error.
  ", f15h_ic_mce_desc[xec-4]);
  		break;
  
  	default:
  		ret = false;
  	}
  	return ret;
  }
dd53bce4e   Borislav Petkov   EDAC, MCE: Adjust...
378
379
  static void amd_decode_ic_mce(struct mce *m)
  {
624528823   Borislav Petkov   EDAC, MCE: Overha...
380
381
  	u16 ec = EC(m->status);
  	u8 xec = XEC(m->status, xec_mask);
dd53bce4e   Borislav Petkov   EDAC, MCE: Adjust...
382
383
384
385
386
387
388
389
  
  	pr_emerg(HW_ERR "Instruction Cache Error: ");
  
  	if (TLB_ERROR(ec))
  		pr_cont("%s TLB %s.
  ", LL_MSG(ec),
  			(xec ? "multimatch" : "parity error"));
  	else if (BUS_ERROR(ec)) {
525906bc8   Borislav Petkov   EDAC, MCE: Fix sh...
390
  		bool k8 = (boot_cpu_data.x86 == 0xf && (m->status & BIT_64(58)));
dd53bce4e   Borislav Petkov   EDAC, MCE: Adjust...
391
392
393
  
  		pr_cont("during %s.
  ", (k8 ? "system linefill" : "NB data read"));
86039cd40   Borislav Petkov   EDAC, MCE: Add F1...
394
  	} else if (fam_ops->ic_mce(ec, xec))
dd53bce4e   Borislav Petkov   EDAC, MCE: Adjust...
395
396
397
398
  		;
  	else
  		pr_emerg(HW_ERR "Corrupted IC MCE info?
  ");
ab5535e70   Borislav Petkov   EDAC, AMD: decode...
399
  }
7cfd4a874   Borislav Petkov   EDAC, MCE: Pass c...
400
  static void amd_decode_bu_mce(struct mce *m)
56cad2d6f   Borislav Petkov   EDAC, AMD: decode...
401
  {
624528823   Borislav Petkov   EDAC, MCE: Overha...
402
403
  	u16 ec = EC(m->status);
  	u8 xec = XEC(m->status, xec_mask);
56cad2d6f   Borislav Petkov   EDAC, AMD: decode...
404

c9f281fd9   Borislav Petkov   EDAC, MCE: Add HW...
405
  	pr_emerg(HW_ERR "Bus Unit Error");
56cad2d6f   Borislav Petkov   EDAC, AMD: decode...
406
407
408
409
410
411
412
413
  
  	if (xec == 0x1)
  		pr_cont(" in the write data buffers.
  ");
  	else if (xec == 0x3)
  		pr_cont(" in the victim data buffers.
  ");
  	else if (xec == 0x2 && MEM_ERROR(ec))
624528823   Borislav Petkov   EDAC, MCE: Overha...
414
415
  		pr_cont(": %s error in the L2 cache tags.
  ", R4_MSG(ec));
56cad2d6f   Borislav Petkov   EDAC, AMD: decode...
416
417
418
419
420
421
422
423
  	else if (xec == 0x0) {
  		if (TLB_ERROR(ec))
  			pr_cont(": %s error in a Page Descriptor Cache or "
  				"Guest TLB.
  ", TT_MSG(ec));
  		else if (BUS_ERROR(ec))
  			pr_cont(": %s/ECC error in data read from NB: %s.
  ",
624528823   Borislav Petkov   EDAC, MCE: Overha...
424
  				R4_MSG(ec), PP_MSG(ec));
56cad2d6f   Borislav Petkov   EDAC, AMD: decode...
425
  		else if (MEM_ERROR(ec)) {
624528823   Borislav Petkov   EDAC, MCE: Overha...
426
  			u8 r4 = R4(ec);
56cad2d6f   Borislav Petkov   EDAC, AMD: decode...
427

624528823   Borislav Petkov   EDAC, MCE: Overha...
428
  			if (r4 >= 0x7)
56cad2d6f   Borislav Petkov   EDAC, AMD: decode...
429
430
  				pr_cont(": %s error during data copyback.
  ",
624528823   Borislav Petkov   EDAC, MCE: Overha...
431
432
  					R4_MSG(ec));
  			else if (r4 <= 0x1)
56cad2d6f   Borislav Petkov   EDAC, AMD: decode...
433
  				pr_cont(": %s parity/ECC error during data "
624528823   Borislav Petkov   EDAC, MCE: Overha...
434
435
  					"access from L2.
  ", R4_MSG(ec));
56cad2d6f   Borislav Petkov   EDAC, AMD: decode...
436
437
438
439
440
441
442
443
444
445
  			else
  				goto wrong_bu_mce;
  		} else
  			goto wrong_bu_mce;
  	} else
  		goto wrong_bu_mce;
  
  	return;
  
  wrong_bu_mce:
c9f281fd9   Borislav Petkov   EDAC, MCE: Add HW...
446
447
  	pr_emerg(HW_ERR "Corrupted BU MCE info?
  ");
56cad2d6f   Borislav Petkov   EDAC, AMD: decode...
448
  }
70fdb494a   Borislav Petkov   EDAC, MCE: Add F1...
449
450
  static void amd_decode_cu_mce(struct mce *m)
  {
624528823   Borislav Petkov   EDAC, MCE: Overha...
451
452
  	u16 ec = EC(m->status);
  	u8 xec = XEC(m->status, xec_mask);
70fdb494a   Borislav Petkov   EDAC, MCE: Add F1...
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
  
  	pr_emerg(HW_ERR "Combined Unit Error: ");
  
  	if (TLB_ERROR(ec)) {
  		if (xec == 0x0)
  			pr_cont("Data parity TLB read error.
  ");
  		else if (xec == 0x1)
  			pr_cont("Poison data provided for TLB fill.
  ");
  		else
  			goto wrong_cu_mce;
  	} else if (BUS_ERROR(ec)) {
  		if (xec > 2)
  			goto wrong_cu_mce;
  
  		pr_cont("Error during attempted NB data read.
  ");
  	} else if (MEM_ERROR(ec)) {
  		switch (xec) {
  		case 0x4 ... 0xc:
  			pr_cont("%s.
  ", f15h_cu_mce_desc[xec - 0x4]);
  			break;
  
  		case 0x10 ... 0x14:
  			pr_cont("%s.
  ", f15h_cu_mce_desc[xec - 0x7]);
  			break;
  
  		default:
  			goto wrong_cu_mce;
  		}
  	}
  
  	return;
  
  wrong_cu_mce:
  	pr_emerg(HW_ERR "Corrupted CU MCE info?
  ");
  }
7cfd4a874   Borislav Petkov   EDAC, MCE: Pass c...
494
  static void amd_decode_ls_mce(struct mce *m)
f9350efd6   Borislav Petkov   EDAC, AMD: decode...
495
  {
624528823   Borislav Petkov   EDAC, MCE: Overha...
496
497
  	u16 ec = EC(m->status);
  	u8 xec = XEC(m->status, xec_mask);
ded506232   Borislav Petkov   EDAC, MCE: Warn a...
498

b18434cad   Borislav Petkov   EDAC, MCE: No F15...
499
  	if (boot_cpu_data.x86 >= 0x14) {
ded506232   Borislav Petkov   EDAC, MCE: Warn a...
500
501
502
503
504
  		pr_emerg("You shouldn't be seeing an LS MCE on this cpu family,"
  			 " please report on LKML.
  ");
  		return;
  	}
f9350efd6   Borislav Petkov   EDAC, AMD: decode...
505

c9f281fd9   Borislav Petkov   EDAC, MCE: Add HW...
506
  	pr_emerg(HW_ERR "Load Store Error");
f9350efd6   Borislav Petkov   EDAC, AMD: decode...
507
508
  
  	if (xec == 0x0) {
624528823   Borislav Petkov   EDAC, MCE: Overha...
509
  		u8 r4 = R4(ec);
f9350efd6   Borislav Petkov   EDAC, AMD: decode...
510

ded506232   Borislav Petkov   EDAC, MCE: Warn a...
511
  		if (!BUS_ERROR(ec) || (r4 != R4_DRD && r4 != R4_DWR))
f9350efd6   Borislav Petkov   EDAC, AMD: decode...
512
  			goto wrong_ls_mce;
624528823   Borislav Petkov   EDAC, MCE: Overha...
513
514
  		pr_cont(" during %s.
  ", R4_MSG(ec));
ded506232   Borislav Petkov   EDAC, MCE: Warn a...
515
516
  	} else
  		goto wrong_ls_mce;
f9350efd6   Borislav Petkov   EDAC, AMD: decode...
517
518
519
  	return;
  
  wrong_ls_mce:
c9f281fd9   Borislav Petkov   EDAC, MCE: Add HW...
520
521
  	pr_emerg(HW_ERR "Corrupted LS MCE info?
  ");
f9350efd6   Borislav Petkov   EDAC, AMD: decode...
522
  }
5ce88f6ea   Borislav Petkov   EDAC, MCE: Comple...
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
  static bool k8_nb_mce(u16 ec, u8 xec)
  {
  	bool ret = true;
  
  	switch (xec) {
  	case 0x1:
  		pr_cont("CRC error detected on HT link.
  ");
  		break;
  
  	case 0x5:
  		pr_cont("Invalid GART PTE entry during GART table walk.
  ");
  		break;
  
  	case 0x6:
  		pr_cont("Unsupported atomic RMW received from an IO link.
  ");
  		break;
  
  	case 0x0:
  	case 0x8:
f0157b3af   Borislav Petkov   EDAC, MCE: Add su...
545
546
  		if (boot_cpu_data.x86 == 0x11)
  			return false;
5ce88f6ea   Borislav Petkov   EDAC, MCE: Comple...
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
  		pr_cont("DRAM ECC error detected on the NB.
  ");
  		break;
  
  	case 0xd:
  		pr_cont("Parity error on the DRAM addr/ctl signals.
  ");
  		break;
  
  	default:
  		ret = false;
  		break;
  	}
  
  	return ret;
  }
  
  static bool f10h_nb_mce(u16 ec, u8 xec)
  {
  	bool ret = true;
  	u8 offset = 0;
  
  	if (k8_nb_mce(ec, xec))
  		return true;
  
  	switch(xec) {
  	case 0xa ... 0xc:
  		offset = 10;
  		break;
  
  	case 0xe:
  		offset = 11;
  		break;
  
  	case 0xf:
  		if (TLB_ERROR(ec))
  			pr_cont("GART Table Walk data error.
  ");
  		else if (BUS_ERROR(ec))
  			pr_cont("DMA Exclusion Vector Table Walk error.
  ");
  		else
  			ret = false;
  
  		goto out;
  		break;
05cd667d6   Borislav Petkov   EDAC, MCE: Add an...
593
594
595
596
597
598
599
600
601
  	case 0x19:
  		if (boot_cpu_data.x86 == 0x15)
  			pr_cont("Compute Unit Data Error.
  ");
  		else
  			ret = false;
  
  		goto out;
  		break;
5ce88f6ea   Borislav Petkov   EDAC, MCE: Comple...
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
  	case 0x1c ... 0x1f:
  		offset = 24;
  		break;
  
  	default:
  		ret = false;
  
  		goto out;
  		break;
  	}
  
  	pr_cont("%s.
  ", f10h_nb_mce_desc[xec - offset]);
  
  out:
  	return ret;
  }
cb9d5ecdf   Borislav Petkov   EDAC, MCE: Add F1...
619
  static bool nb_noop_mce(u16 ec, u8 xec)
5ce88f6ea   Borislav Petkov   EDAC, MCE: Comple...
620
621
622
  {
  	return false;
  }
b0b07a2bd   Borislav Petkov   EDAC, MCE, AMD: S...
623
  void amd_decode_nb_mce(struct mce *m)
549d042df   Borislav Petkov   x86, mce: pass mc...
624
  {
df71a0532   Borislav Petkov   amd64_edac: Enabl...
625
  	struct cpuinfo_x86 *c = &boot_cpu_data;
b0b07a2bd   Borislav Petkov   EDAC, MCE, AMD: S...
626
627
628
  	int node_id = amd_get_nb_id(m->extcpu);
  	u16 ec = EC(m->status);
  	u8 xec = XEC(m->status, 0x1f);
256f7276a   Borislav Petkov   edac, mce, amd: s...
629

295d8cda2   Borislav Petkov   EDAC, MCE, AMD: D...
630
  	pr_emerg(HW_ERR "Northbridge Error (node %d): ", node_id);
6d5db4668   Borislav Petkov   EDAC, MCE: Fix NB...
631

5ce88f6ea   Borislav Petkov   EDAC, MCE: Comple...
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
  	switch (xec) {
  	case 0x2:
  		pr_cont("Sync error (sync packets on HT link detected).
  ");
  		return;
  
  	case 0x3:
  		pr_cont("HT Master abort.
  ");
  		return;
  
  	case 0x4:
  		pr_cont("HT Target abort.
  ");
  		return;
  
  	case 0x7:
  		pr_cont("NB Watchdog timeout.
  ");
  		return;
  
  	case 0x9:
  		pr_cont("SVM DMA Exclusion Vector error.
  ");
  		return;
  
  	default:
  		break;
549d042df   Borislav Petkov   x86, mce: pass mc...
660
  	}
5ce88f6ea   Borislav Petkov   EDAC, MCE: Comple...
661
662
  	if (!fam_ops->nb_mce(ec, xec))
  		goto wrong_nb_mce;
df71a0532   Borislav Petkov   amd64_edac: Enabl...
663
  	if (c->x86 == 0xf || c->x86 == 0x10 || c->x86 == 0x15)
5ce88f6ea   Borislav Petkov   EDAC, MCE: Comple...
664
  		if ((xec == 0x8 || xec == 0x0) && nb_bus_decoder)
b0b07a2bd   Borislav Petkov   EDAC, MCE, AMD: S...
665
  			nb_bus_decoder(node_id, m);
d93cc222a   Borislav Petkov   EDAC, AMD: carve ...
666

5ce88f6ea   Borislav Petkov   EDAC, MCE: Comple...
667
668
669
670
671
  	return;
  
  wrong_nb_mce:
  	pr_emerg(HW_ERR "Corrupted NB MCE info?
  ");
d93cc222a   Borislav Petkov   EDAC, AMD: carve ...
672
673
  }
  EXPORT_SYMBOL_GPL(amd_decode_nb_mce);
7cfd4a874   Borislav Petkov   EDAC, MCE: Pass c...
674
  static void amd_decode_fr_mce(struct mce *m)
53bd5fedc   Borislav Petkov   EDAC, AMD: decode...
675
  {
8259a7e57   Borislav Petkov   EDAC, MCE: Add F1...
676
  	struct cpuinfo_x86 *c = &boot_cpu_data;
624528823   Borislav Petkov   EDAC, MCE: Overha...
677
  	u8 xec = XEC(m->status, xec_mask);
8259a7e57   Borislav Petkov   EDAC, MCE: Add F1...
678
679
  
  	if (c->x86 == 0xf || c->x86 == 0x11)
fe4ea2623   Borislav Petkov   EDAC, MCE: Fix FR...
680
  		goto wrong_fr_mce;
8259a7e57   Borislav Petkov   EDAC, MCE: Add F1...
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
  	if (c->x86 != 0x15 && xec != 0x0)
  		goto wrong_fr_mce;
  
  	pr_emerg(HW_ERR "%s Error: ",
  		 (c->x86 == 0x15 ? "Execution Unit" : "FIROB"));
  
  	if (xec == 0x0 || xec == 0xc)
  		pr_cont("%s.
  ", fr_ex_mce_desc[xec]);
  	else if (xec < 0xd)
  		pr_cont("%s parity error.
  ", fr_ex_mce_desc[xec]);
  	else
  		goto wrong_fr_mce;
  
  	return;
fe4ea2623   Borislav Petkov   EDAC, MCE: Fix FR...
697
698
699
700
  
  wrong_fr_mce:
  	pr_emerg(HW_ERR "Corrupted FR MCE info?
  ");
53bd5fedc   Borislav Petkov   EDAC, AMD: decode...
701
  }
b8f85c477   Borislav Petkov   EDAC, MCE: Add F1...
702
703
  static void amd_decode_fp_mce(struct mce *m)
  {
624528823   Borislav Petkov   EDAC, MCE: Overha...
704
  	u8 xec = XEC(m->status, xec_mask);
b8f85c477   Borislav Petkov   EDAC, MCE: Add F1...
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
  
  	pr_emerg(HW_ERR "Floating Point Unit Error: ");
  
  	switch (xec) {
  	case 0x1:
  		pr_cont("Free List");
  		break;
  
  	case 0x2:
  		pr_cont("Physical Register File");
  		break;
  
  	case 0x3:
  		pr_cont("Retire Queue");
  		break;
  
  	case 0x4:
  		pr_cont("Scheduler table");
  		break;
  
  	case 0x5:
  		pr_cont("Status Register File");
  		break;
  
  	default:
  		goto wrong_fp_mce;
  		break;
  	}
  
  	pr_cont(" parity error.
  ");
  
  	return;
  
  wrong_fp_mce:
  	pr_emerg(HW_ERR "Corrupted FP MCE info?
  ");
  }
6337583d7   Borislav Petkov   EDAC, MCE: Saniti...
743
  static inline void amd_decode_err_code(u16 ec)
d93cc222a   Borislav Petkov   EDAC, AMD: carve ...
744
  {
fa7ae8cc8   Borislav Petkov   EDAC, MCE: Shorte...
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
  
  	pr_emerg(HW_ERR "cache level: %s", LL_MSG(ec));
  
  	if (BUS_ERROR(ec))
  		pr_cont(", mem/io: %s", II_MSG(ec));
  	else
  		pr_cont(", tx: %s", TT_MSG(ec));
  
  	if (MEM_ERROR(ec) || BUS_ERROR(ec)) {
  		pr_cont(", mem-tx: %s", R4_MSG(ec));
  
  		if (BUS_ERROR(ec))
  			pr_cont(", part-proc: %s (%s)", PP_MSG(ec), TO_MSG(ec));
  	}
  
  	pr_cont("
  ");
549d042df   Borislav Petkov   x86, mce: pass mc...
762
  }
549d042df   Borislav Petkov   x86, mce: pass mc...
763

5ce88f6ea   Borislav Petkov   EDAC, MCE: Comple...
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
  /*
   * Filter out unwanted MCE signatures here.
   */
  static bool amd_filter_mce(struct mce *m)
  {
  	u8 xec = (m->status >> 16) & 0x1f;
  
  	/*
  	 * NB GART TLB error reporting is disabled by default.
  	 */
  	if (m->bank == 4 && xec == 0x5 && !report_gart_errors)
  		return true;
  
  	return false;
  }
9cdeb404a   Borislav Petkov   EDAC, MCE: Rework...
779
  int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
549d042df   Borislav Petkov   x86, mce: pass mc...
780
  {
fb2531953   Borislav Petkov   mce, edac: Use an...
781
  	struct mce *m = (struct mce *)data;
fa7ae8cc8   Borislav Petkov   EDAC, MCE: Shorte...
782
  	struct cpuinfo_x86 *c = &boot_cpu_data;
b0b07a2bd   Borislav Petkov   EDAC, MCE, AMD: S...
783
  	int ecc;
549d042df   Borislav Petkov   x86, mce: pass mc...
784

5ce88f6ea   Borislav Petkov   EDAC, MCE: Comple...
785
786
  	if (amd_filter_mce(m))
  		return NOTIFY_STOP;
086be786c   Borislav Petkov   EDAC, MCE, AMD: P...
787
  	pr_emerg(HW_ERR "CPU:%d\tMC%d_STATUS[%s|%s|%s|%s|%s",
bff7b8124   Borislav Petkov   EDAC, MCE, AMD: P...
788
  		m->extcpu, m->bank,
fa7ae8cc8   Borislav Petkov   EDAC, MCE: Shorte...
789
790
791
792
793
  		((m->status & MCI_STATUS_OVER)	? "Over"  : "-"),
  		((m->status & MCI_STATUS_UC)	? "UE"	  : "CE"),
  		((m->status & MCI_STATUS_MISCV)	? "MiscV" : "-"),
  		((m->status & MCI_STATUS_PCC)	? "PCC"	  : "-"),
  		((m->status & MCI_STATUS_ADDRV)	? "AddrV" : "-"));
549d042df   Borislav Petkov   x86, mce: pass mc...
794

fa7ae8cc8   Borislav Petkov   EDAC, MCE: Shorte...
795
796
  	if (c->x86 == 0x15)
  		pr_cont("|%s|%s",
50adbbd8a   Randy Dunlap   EDAC, MCE: Use BI...
797
798
  			((m->status & BIT_64(44)) ? "Deferred" : "-"),
  			((m->status & BIT_64(43)) ? "Poison"   : "-"));
549d042df   Borislav Petkov   x86, mce: pass mc...
799

b69b29de6   Borislav Petkov   EDAC, AMD: carve ...
800
  	/* do the two bits[14:13] together */
35d824b28   Borislav Petkov   edac, mce: Fix wr...
801
  	ecc = (m->status >> 45) & 0x3;
b69b29de6   Borislav Petkov   EDAC, AMD: carve ...
802
  	if (ecc)
fa7ae8cc8   Borislav Petkov   EDAC, MCE: Shorte...
803
804
805
806
  		pr_cont("|%sECC", ((ecc == 2) ? "C" : "U"));
  
  	pr_cont("]: 0x%016llx
  ", m->status);
b69b29de6   Borislav Petkov   EDAC, AMD: carve ...
807

086be786c   Borislav Petkov   EDAC, MCE, AMD: P...
808
809
810
  	if (m->status & MCI_STATUS_ADDRV)
  		pr_emerg(HW_ERR "\tMC%d_ADDR: 0x%016llx
  ", m->bank, m->addr);
b69b29de6   Borislav Petkov   EDAC, AMD: carve ...
811

519662413   Borislav Petkov   EDAC, AMD: decode...
812
813
  	switch (m->bank) {
  	case 0:
7cfd4a874   Borislav Petkov   EDAC, MCE: Pass c...
814
  		amd_decode_dc_mce(m);
519662413   Borislav Petkov   EDAC, AMD: decode...
815
  		break;
d93cc222a   Borislav Petkov   EDAC, AMD: carve ...
816

ab5535e70   Borislav Petkov   EDAC, AMD: decode...
817
  	case 1:
7cfd4a874   Borislav Petkov   EDAC, MCE: Pass c...
818
  		amd_decode_ic_mce(m);
ab5535e70   Borislav Petkov   EDAC, AMD: decode...
819
  		break;
56cad2d6f   Borislav Petkov   EDAC, AMD: decode...
820
  	case 2:
fa7ae8cc8   Borislav Petkov   EDAC, MCE: Shorte...
821
  		if (c->x86 == 0x15)
70fdb494a   Borislav Petkov   EDAC, MCE: Add F1...
822
823
824
  			amd_decode_cu_mce(m);
  		else
  			amd_decode_bu_mce(m);
56cad2d6f   Borislav Petkov   EDAC, AMD: decode...
825
  		break;
f9350efd6   Borislav Petkov   EDAC, AMD: decode...
826
  	case 3:
7cfd4a874   Borislav Petkov   EDAC, MCE: Pass c...
827
  		amd_decode_ls_mce(m);
f9350efd6   Borislav Petkov   EDAC, AMD: decode...
828
  		break;
519662413   Borislav Petkov   EDAC, AMD: decode...
829
  	case 4:
b0b07a2bd   Borislav Petkov   EDAC, MCE, AMD: S...
830
  		amd_decode_nb_mce(m);
519662413   Borislav Petkov   EDAC, AMD: decode...
831
  		break;
53bd5fedc   Borislav Petkov   EDAC, AMD: decode...
832
  	case 5:
7cfd4a874   Borislav Petkov   EDAC, MCE: Pass c...
833
  		amd_decode_fr_mce(m);
53bd5fedc   Borislav Petkov   EDAC, AMD: decode...
834
  		break;
b8f85c477   Borislav Petkov   EDAC, MCE: Add F1...
835
836
837
  	case 6:
  		amd_decode_fp_mce(m);
  		break;
519662413   Borislav Petkov   EDAC, AMD: decode...
838
839
  	default:
  		break;
b69b29de6   Borislav Petkov   EDAC, AMD: carve ...
840
  	}
519662413   Borislav Petkov   EDAC, AMD: decode...
841
842
  
  	amd_decode_err_code(m->status & 0xffff);
fb2531953   Borislav Petkov   mce, edac: Use an...
843
844
  
  	return NOTIFY_STOP;
549d042df   Borislav Petkov   x86, mce: pass mc...
845
  }
9cdeb404a   Borislav Petkov   EDAC, MCE: Rework...
846
  EXPORT_SYMBOL_GPL(amd_decode_mce);
f436f8bb7   Ingo Molnar   x86: EDAC: MCE: F...
847

fb2531953   Borislav Petkov   mce, edac: Use an...
848
849
850
  static struct notifier_block amd_mce_dec_nb = {
  	.notifier_call	= amd_decode_mce,
  };
f436f8bb7   Ingo Molnar   x86: EDAC: MCE: F...
851
852
  static int __init mce_amd_init(void)
  {
bad11e031   Borislav Petkov   EDAC, MCE: Enable...
853
854
855
  	struct cpuinfo_x86 *c = &boot_cpu_data;
  
  	if (c->x86_vendor != X86_VENDOR_AMD)
e045c2912   Borislav Petkov   MCE, AMD: Limit M...
856
  		return 0;
bad11e031   Borislav Petkov   EDAC, MCE: Enable...
857
858
859
  	if ((c->x86 < 0xf || c->x86 > 0x12) &&
  	    (c->x86 != 0x14 || c->x86_model > 0xf) &&
  	    (c->x86 != 0x15 || c->x86_model > 0xf))
e045c2912   Borislav Petkov   MCE, AMD: Limit M...
860
  		return 0;
888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
861
862
863
  	fam_ops = kzalloc(sizeof(struct amd_decoder_ops), GFP_KERNEL);
  	if (!fam_ops)
  		return -ENOMEM;
bad11e031   Borislav Petkov   EDAC, MCE: Enable...
864
  	switch (c->x86) {
888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
865
866
  	case 0xf:
  		fam_ops->dc_mce = k8_dc_mce;
dd53bce4e   Borislav Petkov   EDAC, MCE: Adjust...
867
  		fam_ops->ic_mce = k8_ic_mce;
5ce88f6ea   Borislav Petkov   EDAC, MCE: Comple...
868
  		fam_ops->nb_mce = k8_nb_mce;
888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
869
870
871
872
  		break;
  
  	case 0x10:
  		fam_ops->dc_mce = f10h_dc_mce;
dd53bce4e   Borislav Petkov   EDAC, MCE: Adjust...
873
  		fam_ops->ic_mce = k8_ic_mce;
5ce88f6ea   Borislav Petkov   EDAC, MCE: Comple...
874
  		fam_ops->nb_mce = f10h_nb_mce;
888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
875
  		break;
f0157b3af   Borislav Petkov   EDAC, MCE: Add su...
876
877
878
879
880
  	case 0x11:
  		fam_ops->dc_mce = k8_dc_mce;
  		fam_ops->ic_mce = k8_ic_mce;
  		fam_ops->nb_mce = f10h_nb_mce;
  		break;
9be0bb107   Borislav Petkov   EDAC, MCE: Add F1...
881
882
  	case 0x12:
  		fam_ops->dc_mce = f12h_dc_mce;
e7281eb37   Borislav Petkov   EDAC, MCE: Add F1...
883
  		fam_ops->ic_mce = k8_ic_mce;
cb9d5ecdf   Borislav Petkov   EDAC, MCE: Add F1...
884
  		fam_ops->nb_mce = nb_noop_mce;
9be0bb107   Borislav Petkov   EDAC, MCE: Add F1...
885
  		break;
888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
886
  	case 0x14:
5ce88f6ea   Borislav Petkov   EDAC, MCE: Comple...
887
  		nb_err_cpumask  = 0x3;
888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
888
  		fam_ops->dc_mce = f14h_dc_mce;
dd53bce4e   Borislav Petkov   EDAC, MCE: Adjust...
889
  		fam_ops->ic_mce = f14h_ic_mce;
cb9d5ecdf   Borislav Petkov   EDAC, MCE: Add F1...
890
  		fam_ops->nb_mce = nb_noop_mce;
888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
891
  		break;
2be64bfac   Borislav Petkov   EDAC, MCE: Select...
892
893
  	case 0x15:
  		xec_mask = 0x1f;
25a4f8b05   Borislav Petkov   EDAC, MCE: Add F1...
894
  		fam_ops->dc_mce = f15h_dc_mce;
86039cd40   Borislav Petkov   EDAC, MCE: Add F1...
895
  		fam_ops->ic_mce = f15h_ic_mce;
05cd667d6   Borislav Petkov   EDAC, MCE: Add an...
896
  		fam_ops->nb_mce = f10h_nb_mce;
2be64bfac   Borislav Petkov   EDAC, MCE: Select...
897
  		break;
888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
898
  	default:
bad11e031   Borislav Petkov   EDAC, MCE: Enable...
899
900
  		printk(KERN_WARNING "Huh? What family is that: %d?!
  ", c->x86);
888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
901
902
903
  		kfree(fam_ops);
  		return -EINVAL;
  	}
9530d608e   Borislav Petkov   EDAC, MCE: Enable...
904
905
  	pr_info("MCE: In-kernel MCE decoding enabled.
  ");
3653ada5d   Borislav Petkov   x86, mce: Add wra...
906
  	mce_register_decode_chain(&amd_mce_dec_nb);
f436f8bb7   Ingo Molnar   x86: EDAC: MCE: F...
907
908
909
910
  
  	return 0;
  }
  early_initcall(mce_amd_init);
0d18b2e34   Borislav Petkov   x86: EDAC: carve ...
911
912
913
914
  
  #ifdef MODULE
  static void __exit mce_amd_exit(void)
  {
3653ada5d   Borislav Petkov   x86, mce: Add wra...
915
  	mce_unregister_decode_chain(&amd_mce_dec_nb);
888ab8e6e   Borislav Petkov   EDAC, MCE: Adjust...
916
  	kfree(fam_ops);
0d18b2e34   Borislav Petkov   x86: EDAC: carve ...
917
918
919
920
921
922
923
  }
  
  MODULE_DESCRIPTION("AMD MCE decoder");
  MODULE_ALIAS("edac-mce-amd");
  MODULE_LICENSE("GPL");
  module_exit(mce_amd_exit);
  #endif