diff options
author | Chen Yucong <slaoub@gmail.com> | 2014-10-02 08:48:19 -0400 |
---|---|---|
committer | Borislav Petkov <bp@suse.de> | 2014-10-21 16:12:22 -0400 |
commit | 44612a3ac671d7b9a9b987ab73dcc776204ac4d5 (patch) | |
tree | 7189899574cdc8ef4ac3b4808e52861076bd58dd | |
parent | 4b737d78a8081cb2def7ced262a212c31363539a (diff) |
x86, MCE, AMD: Correct thresholding error logging
mce_setup() does not gather the content of IA32_MCG_STATUS, so it
should be read explicitly. Moreover, we need to clear IA32_MCx_STATUS
to avoid that mce_log() logs the processed threshold event again
at next time.
But we do the logging ourselves and machine_check_poll() is completely
useless there. So kill it.
Signed-off-by: Chen Yucong <slaoub@gmail.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce_amd.c | 30 |
1 files changed, 15 insertions, 15 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index f8c56bd7b74d..9ce64955559d 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c | |||
@@ -270,14 +270,13 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c) | |||
270 | static void amd_threshold_interrupt(void) | 270 | static void amd_threshold_interrupt(void) |
271 | { | 271 | { |
272 | u32 low = 0, high = 0, address = 0; | 272 | u32 low = 0, high = 0, address = 0; |
273 | int cpu = smp_processor_id(); | ||
273 | unsigned int bank, block; | 274 | unsigned int bank, block; |
274 | struct mce m; | 275 | struct mce m; |
275 | 276 | ||
276 | mce_setup(&m); | ||
277 | |||
278 | /* assume first bank caused it */ | 277 | /* assume first bank caused it */ |
279 | for (bank = 0; bank < mca_cfg.banks; ++bank) { | 278 | for (bank = 0; bank < mca_cfg.banks; ++bank) { |
280 | if (!(per_cpu(bank_map, m.cpu) & (1 << bank))) | 279 | if (!(per_cpu(bank_map, cpu) & (1 << bank))) |
281 | continue; | 280 | continue; |
282 | for (block = 0; block < NR_BLOCKS; ++block) { | 281 | for (block = 0; block < NR_BLOCKS; ++block) { |
283 | if (block == 0) { | 282 | if (block == 0) { |
@@ -309,20 +308,21 @@ static void amd_threshold_interrupt(void) | |||
309 | * Log the machine check that caused the threshold | 308 | * Log the machine check that caused the threshold |
310 | * event. | 309 | * event. |
311 | */ | 310 | */ |
312 | machine_check_poll(MCP_TIMESTAMP, | 311 | if (high & MASK_OVERFLOW_HI) |
313 | this_cpu_ptr(&mce_poll_banks)); | 312 | goto log; |
314 | |||
315 | if (high & MASK_OVERFLOW_HI) { | ||
316 | rdmsrl(address, m.misc); | ||
317 | rdmsrl(MSR_IA32_MCx_STATUS(bank), m.status); | ||
318 | m.bank = K8_MCE_THRESHOLD_BASE | ||
319 | + bank * NR_BLOCKS | ||
320 | + block; | ||
321 | mce_log(&m); | ||
322 | return; | ||
323 | } | ||
324 | } | 313 | } |
325 | } | 314 | } |
315 | return; | ||
316 | |||
317 | log: | ||
318 | mce_setup(&m); | ||
319 | rdmsrl(MSR_IA32_MCG_STATUS, m.mcgstatus); | ||
320 | rdmsrl(address, m.misc); | ||
321 | rdmsrl(MSR_IA32_MCx_STATUS(bank), m.status); | ||
322 | m.bank = K8_MCE_THRESHOLD_BASE + bank * NR_BLOCKS + block; | ||
323 | mce_log(&m); | ||
324 | |||
325 | wrmsrl(MSR_IA32_MCx_STATUS(bank), 0); | ||
326 | } | 326 | } |
327 | 327 | ||
328 | /* | 328 | /* |