aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/mcheck
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/cpu/mcheck')
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_64.c16
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_amd_64.c3
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
63static DECLARE_WAIT_QUEUE_HEAD(mce_wait); 63static DECLARE_WAIT_QUEUE_HEAD(mce_wait);
64 64
65/* MCA banks polled by the period polling timer for corrected events */
66DEFINE_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 */
66void mce_setup(struct mce *m) 71void 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 */
194void machine_check_poll(enum mcp_flags flags) 199void 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(&current_cpu_data)) 465 if (mce_available(&current_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);