diff options
Diffstat (limited to 'arch/x86/kernel/cpu/mcheck')
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce_64.c | 16 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce_amd_64.c | 3 |
2 files changed, 14 insertions, 5 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index 9017609cadd9..a8ff38bfa6ed 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c | |||
@@ -62,6 +62,11 @@ static char *trigger_argv[2] = { trigger, NULL }; | |||
62 | 62 | ||
63 | static DECLARE_WAIT_QUEUE_HEAD(mce_wait); | 63 | static DECLARE_WAIT_QUEUE_HEAD(mce_wait); |
64 | 64 | ||
65 | /* MCA banks polled by the period polling timer for corrected events */ | ||
66 | DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = { | ||
67 | [0 ... BITS_TO_LONGS(MAX_NR_BANKS)-1] = ~0UL | ||
68 | }; | ||
69 | |||
65 | /* Do initial initialization of a struct mce */ | 70 | /* Do initial initialization of a struct mce */ |
66 | void mce_setup(struct mce *m) | 71 | void mce_setup(struct mce *m) |
67 | { | 72 | { |
@@ -191,7 +196,7 @@ static inline void mce_get_rip(struct mce *m, struct pt_regs *regs) | |||
191 | * | 196 | * |
192 | * This is executed in standard interrupt context. | 197 | * This is executed in standard interrupt context. |
193 | */ | 198 | */ |
194 | void machine_check_poll(enum mcp_flags flags) | 199 | void machine_check_poll(enum mcp_flags flags, mce_banks_t *b) |
195 | { | 200 | { |
196 | struct mce m; | 201 | struct mce m; |
197 | int i; | 202 | int i; |
@@ -200,7 +205,7 @@ void machine_check_poll(enum mcp_flags flags) | |||
200 | 205 | ||
201 | rdmsrl(MSR_IA32_MCG_STATUS, m.mcgstatus); | 206 | rdmsrl(MSR_IA32_MCG_STATUS, m.mcgstatus); |
202 | for (i = 0; i < banks; i++) { | 207 | for (i = 0; i < banks; i++) { |
203 | if (!bank[i]) | 208 | if (!bank[i] || !test_bit(i, *b)) |
204 | continue; | 209 | continue; |
205 | 210 | ||
206 | m.misc = 0; | 211 | m.misc = 0; |
@@ -458,7 +463,8 @@ static void mcheck_timer(unsigned long data) | |||
458 | WARN_ON(smp_processor_id() != data); | 463 | WARN_ON(smp_processor_id() != data); |
459 | 464 | ||
460 | if (mce_available(¤t_cpu_data)) | 465 | if (mce_available(¤t_cpu_data)) |
461 | machine_check_poll(MCP_TIMESTAMP); | 466 | machine_check_poll(MCP_TIMESTAMP, |
467 | &__get_cpu_var(mce_poll_banks)); | ||
462 | 468 | ||
463 | /* | 469 | /* |
464 | * Alert userspace if needed. If we logged an MCE, reduce the | 470 | * Alert userspace if needed. If we logged an MCE, reduce the |
@@ -572,11 +578,13 @@ static void mce_init(void *dummy) | |||
572 | { | 578 | { |
573 | u64 cap; | 579 | u64 cap; |
574 | int i; | 580 | int i; |
581 | mce_banks_t all_banks; | ||
575 | 582 | ||
576 | /* | 583 | /* |
577 | * Log the machine checks left over from the previous reset. | 584 | * Log the machine checks left over from the previous reset. |
578 | */ | 585 | */ |
579 | machine_check_poll(MCP_UC); | 586 | bitmap_fill(all_banks, MAX_NR_BANKS); |
587 | machine_check_poll(MCP_UC, &all_banks); | ||
580 | 588 | ||
581 | set_in_cr4(X86_CR4_MCE); | 589 | set_in_cr4(X86_CR4_MCE); |
582 | 590 | ||
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c index 49705be98209..ee8bfcd3aa32 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c | |||
@@ -231,7 +231,8 @@ static void amd_threshold_interrupt(void) | |||
231 | 231 | ||
232 | /* Log the machine check that caused the threshold | 232 | /* Log the machine check that caused the threshold |
233 | event. */ | 233 | event. */ |
234 | machine_check_poll(MCP_TIMESTAMP); | 234 | machine_check_poll(MCP_TIMESTAMP, |
235 | &__get_cpu_var(mce_poll_banks)); | ||
235 | 236 | ||
236 | if (high & MASK_OVERFLOW_HI) { | 237 | if (high & MASK_OVERFLOW_HI) { |
237 | rdmsrl(address, m.misc); | 238 | rdmsrl(address, m.misc); |