extern void do_machine_check(struct pt_regs *, long);
+typedef DECLARE_BITMAP(mce_banks_t, MAX_NR_BANKS);
+DECLARE_PER_CPU(mce_banks_t, mce_poll_banks);
+
enum mcp_flags {
MCP_TIMESTAMP = (1 << 0), /* log time stamp */
MCP_UC = (1 << 1), /* log uncorrected errors */
};
-extern void machine_check_poll(enum mcp_flags flags);
+extern void machine_check_poll(enum mcp_flags flags, mce_banks_t *b);
extern int mce_notify_user(void);
static DECLARE_WAIT_QUEUE_HEAD(mce_wait);
+/* MCA banks polled by the period polling timer for corrected events */
+DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = {
+ [0 ... BITS_TO_LONGS(MAX_NR_BANKS)-1] = ~0UL
+};
+
/* Do initial initialization of a struct mce */
void mce_setup(struct mce *m)
{
*
* This is executed in standard interrupt context.
*/
-void machine_check_poll(enum mcp_flags flags)
+void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
{
struct mce m;
int i;
rdmsrl(MSR_IA32_MCG_STATUS, m.mcgstatus);
for (i = 0; i < banks; i++) {
- if (!bank[i])
+ if (!bank[i] || !test_bit(i, *b))
continue;
m.misc = 0;
WARN_ON(smp_processor_id() != data);
if (mce_available(¤t_cpu_data))
- machine_check_poll(MCP_TIMESTAMP);
+ machine_check_poll(MCP_TIMESTAMP,
+ &__get_cpu_var(mce_poll_banks));
/*
* Alert userspace if needed. If we logged an MCE, reduce the
{
u64 cap;
int i;
+ mce_banks_t all_banks;
/*
* Log the machine checks left over from the previous reset.
*/
- machine_check_poll(MCP_UC);
+ bitmap_fill(all_banks, MAX_NR_BANKS);
+ machine_check_poll(MCP_UC, &all_banks);
set_in_cr4(X86_CR4_MCE);
/* Log the machine check that caused the threshold
event. */
- machine_check_poll(MCP_TIMESTAMP);
+ machine_check_poll(MCP_TIMESTAMP,
+ &__get_cpu_var(mce_poll_banks));
if (high & MASK_OVERFLOW_HI) {
rdmsrl(address, m.misc);