diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2009-04-06 13:46:11 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2009-04-06 13:46:11 +0100 |
commit | 3e15c37e68862b9d8f3a9f0085fab2d596e19e49 (patch) | |
tree | b06fd3e07fb8c63717607b66378654d1ce6ce70e | |
parent | c806877d1b3992a9a75e4aa7604911d048891410 (diff) | |
download | xen-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.c | 13 | ||||
-rw-r--r-- | xen/arch/x86/cpu/mcheck/mce.h | 4 | ||||
-rw-r--r-- | xen/arch/x86/cpu/mcheck/mce_intel.c | 4 | ||||
-rw-r--r-- | xen/arch/x86/cpu/mcheck/non-fatal.c | 8 |
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 */ |