aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndi Kleen <ak@linux.intel.com>2010-11-22 11:18:06 +0100
committerAndi Kleen <ak@linux.intel.com>2010-11-22 11:55:33 +0100
commitfb93f0941875ffc17fdeb7af699a188dba501646 (patch)
tree7f12a391ae6a8a0a7d0fa026011feeb9f7135ab2
parentb7c2e1b7dd10b23e8f68deed638fbfc13fc1b4ee (diff)
downloadlinux-mce-2.6-mce/injector.tar.gz
x86: mce: clear injection state after eventmce/injector
Currently when an event is ever injected the machine check code will never read the hardware registers again, but always only look at the fake software injection registers. Clear the injection state after an event has been processed. This way normal hardware events will be processed again after injection. Signed-off-by: Andi Kleen <ak@linux.intel.com>
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index 2cd0a5182bfe0..9a70b10c28304 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -379,6 +379,18 @@ static void mce_wrmsrl(u32 msr, u64 v)
wrmsrl(msr, v);
}
+/*
+ * Switch back to processing hardware events after finishing
+ * an injected event.
+ */
+static void mce_end_injection(unsigned long *b)
+{
+ struct mce *m = &__get_cpu_var(injectm);
+
+ if (m->finished && test_bit(m->bank, b))
+ m->finished = 0;
+}
+
/*
* Simple lockless ring to communicate PFNs from the exception handler with the
* process context work function. This is vastly simplified because there's
@@ -598,6 +610,8 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
mce_wrmsrl(MSR_IA32_MCx_STATUS(i), 0);
}
+ mce_end_injection(*b);
+
/*
* Don't clear MCG_STATUS here because it's only defined for
* exceptions.
@@ -1081,6 +1095,7 @@ void do_machine_check(struct pt_regs *regs, long error_code)
if (worst > 0)
mce_report_event(regs);
mce_wrmsrl(MSR_IA32_MCG_STATUS, 0);
+ mce_end_injection(toclear);
out:
atomic_dec(&mce_entry);
sync_core();