aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorAndi Kleen <andi@firstfloor.org>2009-02-12 07:49:34 -0500
committerH. Peter Anvin <hpa@zytor.com>2009-02-24 16:26:05 -0500
commitee031c31d6381d004bfd386c2e45821211507499 (patch)
tree91f5dd04b594bccae8e89eb52dff4ba0eea5041e /arch/x86
parent8457c84d68678cbfd4167a9073b89da58e48c037 (diff)
x86, mce, cmci: use polled banks bitmap in machine check poller
Define a per cpu bitmap that contains the banks polled by the machine check poller. This is needed for the CMCI code in the next patches to be able to disable polling on specific banks. The bank by default contains all banks, so there is no behaviour change. Only future code will remove some banks from the polling set. Signed-off-by: Andi Kleen <ak@linux.intel.com> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/include/asm/mce.h5
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_64.c16
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_amd_64.c3
3 files changed, 18 insertions, 6 deletions
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index 125cd8714622..9b9523699dbc 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -119,11 +119,14 @@ extern atomic_t mce_entry;
119 119
120extern void do_machine_check(struct pt_regs *, long); 120extern void do_machine_check(struct pt_regs *, long);
121 121
122typedef DECLARE_BITMAP(mce_banks_t, MAX_NR_BANKS);
123DECLARE_PER_CPU(mce_banks_t, mce_poll_banks);
124
122enum mcp_flags { 125enum mcp_flags {
123 MCP_TIMESTAMP = (1 << 0), /* log time stamp */ 126 MCP_TIMESTAMP = (1 << 0), /* log time stamp */
124 MCP_UC = (1 << 1), /* log uncorrected errors */ 127 MCP_UC = (1 << 1), /* log uncorrected errors */
125}; 128};
126extern void machine_check_poll(enum mcp_flags flags); 129extern void machine_check_poll(enum mcp_flags flags, mce_banks_t *b);
127 130
128extern int mce_notify_user(void); 131extern int mce_notify_user(void);
129 132
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);