diff options
-rw-r--r-- | drivers/edac/edac_mce_amd.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c index fe8ccebd9672..b30a8306b143 100644 --- a/drivers/edac/edac_mce_amd.c +++ b/drivers/edac/edac_mce_amd.c | |||
@@ -171,6 +171,63 @@ wrong_dc_mce: | |||
171 | pr_warning("Corrupted DC MCE info?\n"); | 171 | pr_warning("Corrupted DC MCE info?\n"); |
172 | } | 172 | } |
173 | 173 | ||
174 | static void amd_decode_ic_mce(u64 mc1_status) | ||
175 | { | ||
176 | u32 ec = mc1_status & 0xffff; | ||
177 | u32 xec = (mc1_status >> 16) & 0xf; | ||
178 | |||
179 | pr_emerg(" Instruction Cache Error"); | ||
180 | |||
181 | if (xec == 1 && TLB_ERROR(ec)) | ||
182 | pr_cont(": %s TLB multimatch.\n", LL_MSG(ec)); | ||
183 | else if (xec == 0) { | ||
184 | if (TLB_ERROR(ec)) | ||
185 | pr_cont(": %s TLB Parity error.\n", LL_MSG(ec)); | ||
186 | else if (BUS_ERROR(ec)) { | ||
187 | if (boot_cpu_data.x86 == 0xf && | ||
188 | (mc1_status & (1ULL << 58))) | ||
189 | pr_cont(" during system linefill.\n"); | ||
190 | else | ||
191 | pr_cont(" during attempted NB data read.\n"); | ||
192 | } else if (MEM_ERROR(ec)) { | ||
193 | u8 ll = ec & 0x3; | ||
194 | u8 rrrr = (ec >> 4) & 0xf; | ||
195 | |||
196 | if (ll == 0x2) | ||
197 | pr_cont(" during a linefill from L2.\n"); | ||
198 | else if (ll == 0x1) { | ||
199 | |||
200 | switch (rrrr) { | ||
201 | case 0x5: | ||
202 | pr_cont(": Parity error during " | ||
203 | "data load.\n"); | ||
204 | break; | ||
205 | |||
206 | case 0x7: | ||
207 | pr_cont(": Copyback Parity/Victim" | ||
208 | " error.\n"); | ||
209 | break; | ||
210 | |||
211 | case 0x8: | ||
212 | pr_cont(": Tag Snoop error.\n"); | ||
213 | break; | ||
214 | |||
215 | default: | ||
216 | goto wrong_ic_mce; | ||
217 | break; | ||
218 | } | ||
219 | } | ||
220 | } else | ||
221 | goto wrong_ic_mce; | ||
222 | } else | ||
223 | goto wrong_ic_mce; | ||
224 | |||
225 | return; | ||
226 | |||
227 | wrong_ic_mce: | ||
228 | pr_warning("Corrupted IC MCE info?\n"); | ||
229 | } | ||
230 | |||
174 | void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors) | 231 | void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors) |
175 | { | 232 | { |
176 | u32 ec = ERROR_CODE(regs->nbsl); | 233 | u32 ec = ERROR_CODE(regs->nbsl); |
@@ -259,6 +316,10 @@ void decode_mce(struct mce *m) | |||
259 | amd_decode_dc_mce(m->status); | 316 | amd_decode_dc_mce(m->status); |
260 | break; | 317 | break; |
261 | 318 | ||
319 | case 1: | ||
320 | amd_decode_ic_mce(m->status); | ||
321 | break; | ||
322 | |||
262 | case 4: | 323 | case 4: |
263 | regs.nbsl = (u32) m->status; | 324 | regs.nbsl = (u32) m->status; |
264 | regs.nbsh = (u32)(m->status >> 32); | 325 | regs.nbsh = (u32)(m->status >> 32); |