aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-04-06 13:46:11 +0100
committerKeir Fraser <keir.fraser@citrix.com>2009-04-06 13:46:11 +0100
commit3e15c37e68862b9d8f3a9f0085fab2d596e19e49 (patch)
treeb06fd3e07fb8c63717607b66378654d1ce6ce70e
parentc806877d1b3992a9a75e4aa7604911d048891410 (diff)
downloadxen-3e15c37e68862b9d8f3a9f0085fab2d596e19e49.tar.gz
xen-3e15c37e68862b9d8f3a9f0085fab2d596e19e49.tar.bz2
xen-3e15c37e68862b9d8f3a9f0085fab2d596e19e49.zip
x86 mce: Small fix for polling/CMCI race conditions.
When CMCI happens very quickly, polling/CMCI processing path might cross. For Intel CPUs which support CMCI, if the error bank has CMCI capability, we'll disable poll on this bank. Signed-off-by: Liping Ke <liping.ke@intel.com> Signed-off-by: Yunhong Jiang<yunhong.jiang@intel.com>
-rw-r--r--xen/arch/x86/cpu/mcheck/mce.c13
-rw-r--r--xen/arch/x86/cpu/mcheck/mce.h4
-rw-r--r--xen/arch/x86/cpu/mcheck/mce_intel.c4
-rw-r--r--xen/arch/x86/cpu/mcheck/non-fatal.c8
4 files changed, 21 insertions, 8 deletions
diff --git a/xen/arch/x86/cpu/mcheck/mce.c b/xen/arch/x86/cpu/mcheck/mce.c
index bc18e3048b..a43f2f131a 100644
--- a/xen/arch/x86/cpu/mcheck/mce.c
+++ b/xen/arch/x86/cpu/mcheck/mce.c
@@ -577,6 +577,7 @@ void mcheck_init(struct cpuinfo_x86 *c)
break;
}
+ set_poll_bankmask(c);
if (!inited)
printk(XENLOG_INFO "CPU%i: No machine check initialization\n",
smp_processor_id());
@@ -1230,7 +1231,19 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u_xen_mc)
return ret;
}
+void set_poll_bankmask(struct cpuinfo_x86 *c)
+{
+ if (cmci_support && !mce_disabled) {
+ memcpy(&(__get_cpu_var(poll_bankmask)),
+ &(__get_cpu_var(no_cmci_banks)), sizeof(cpu_banks_t));
+ }
+ else {
+ memcpy(&(get_cpu_var(poll_bankmask)), &mca_allbanks, sizeof(cpu_banks_t));
+ if (mce_firstbank(c))
+ clear_bit(0, get_cpu_var(poll_bankmask));
+ }
+}
void mc_panic(char *s)
{
console_start_sync();
diff --git a/xen/arch/x86/cpu/mcheck/mce.h b/xen/arch/x86/cpu/mcheck/mce.h
index 2bd6f023d6..6b79e673e2 100644
--- a/xen/arch/x86/cpu/mcheck/mce.h
+++ b/xen/arch/x86/cpu/mcheck/mce.h
@@ -88,6 +88,10 @@ struct mca_summary {
};
extern cpu_banks_t mca_allbanks;
+void set_poll_bankmask(struct cpuinfo_x86 *c);
+DECLARE_PER_CPU(cpu_banks_t, poll_bankmask);
+DECLARE_PER_CPU(cpu_banks_t, no_cmci_banks);
+extern int cmci_support;
extern mctelem_cookie_t mcheck_mca_logout(enum mca_source, cpu_banks_t,
struct mca_summary *);
diff --git a/xen/arch/x86/cpu/mcheck/mce_intel.c b/xen/arch/x86/cpu/mcheck/mce_intel.c
index d8fa0ebb07..67d0342d99 100644
--- a/xen/arch/x86/cpu/mcheck/mce_intel.c
+++ b/xen/arch/x86/cpu/mcheck/mce_intel.c
@@ -12,9 +12,10 @@
#include "x86_mca.h"
DEFINE_PER_CPU(cpu_banks_t, mce_banks_owned);
+DEFINE_PER_CPU(cpu_banks_t, no_cmci_banks);
+int cmci_support = 0;
static int nr_intel_ext_msrs = 0;
-static int cmci_support = 0;
static int firstbank;
#ifdef CONFIG_X86_MCE_THERMAL
@@ -548,7 +549,6 @@ static void intel_machine_check(struct cpu_user_regs * regs, long error_code)
}
static DEFINE_SPINLOCK(cmci_discover_lock);
-static DEFINE_PER_CPU(cpu_banks_t, no_cmci_banks);
/*
* Discover bank sharing using the algorithm recommended in the SDM.
diff --git a/xen/arch/x86/cpu/mcheck/non-fatal.c b/xen/arch/x86/cpu/mcheck/non-fatal.c
index 167b1cea2a..9d66a12b6b 100644
--- a/xen/arch/x86/cpu/mcheck/non-fatal.c
+++ b/xen/arch/x86/cpu/mcheck/non-fatal.c
@@ -22,7 +22,7 @@
#include "mce.h"
-static cpu_banks_t bankmask;
+DEFINE_PER_CPU(cpu_banks_t, poll_bankmask);
static struct timer mce_timer;
#define MCE_PERIOD MILLISECS(8000)
@@ -39,7 +39,7 @@ static void mce_checkregs (void *info)
struct mca_summary bs;
static uint64_t dumpcount = 0;
- mctc = mcheck_mca_logout(MCA_POLLER, bankmask, &bs);
+ mctc = mcheck_mca_logout(MCA_POLLER, __get_cpu_var(poll_bankmask), &bs);
if (bs.errcnt && mctc != NULL) {
adjust++;
@@ -94,10 +94,6 @@ static int __init init_nonfatal_mce_checker(void)
if (!mce_available(c))
return -ENODEV;
- memcpy(&bankmask, &mca_allbanks, sizeof (cpu_banks_t));
- if (mce_firstbank(c) == 1)
- clear_bit(0, bankmask);
-
/*
* Check for non-fatal errors every MCE_RATE s
*/