debuggers.hg

changeset 20911:088f1b01d852

x86 mca: Add MCE broadcast checkiing.

Some platform will broadcast MCE to all logical processor, while some
platform will not. Distinguish these platforms will be helpful for
unified MCA handler.

the "mce_fb" is a option to emulate the broadcast MCA in non-broadcast
platform. This is mainly for MCA software trigger.

Signed-off-by: Jiang, Yunhong <yunhong.jiang@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jan 29 06:49:42 2010 +0000 (2010-01-29)
parents da5faf9f5df8
children ebd2495ec073
files xen/arch/x86/cpu/mcheck/mce.c xen/arch/x86/cpu/mcheck/mce.h xen/arch/x86/cpu/mcheck/mce_intel.c
line diff
     1.1 --- a/xen/arch/x86/cpu/mcheck/mce.c	Fri Jan 29 06:49:13 2010 +0000
     1.2 +++ b/xen/arch/x86/cpu/mcheck/mce.c	Fri Jan 29 06:49:42 2010 +0000
     1.3 @@ -25,10 +25,12 @@
     1.4  
     1.5  int mce_disabled;
     1.6  invbool_param("mce", mce_disabled);
     1.7 -
     1.8 +static int mce_force_broadcast;
     1.9 +boolean_param("mce_fb", mce_force_broadcast);
    1.10  int is_mc_panic;
    1.11  unsigned int nr_mce_banks;
    1.12  
    1.13 +int mce_broadcast = 0;
    1.14  static uint64_t g_mcg_cap;
    1.15  
    1.16  /* Real value in physical CTL MSR */
    1.17 @@ -588,6 +590,21 @@ int mce_available(struct cpuinfo_x86 *c)
    1.18  	return cpu_has(c, X86_FEATURE_MCE) && cpu_has(c, X86_FEATURE_MCA);
    1.19  }
    1.20  
    1.21 +static int mce_is_broadcast(struct cpuinfo_x86 *c)
    1.22 +{
    1.23 +    if (mce_force_broadcast)
    1.24 +        return 1;
    1.25 +
    1.26 +    /* According to Intel SDM Dec, 2009, 15.10.4.1, For processors with
    1.27 +     * DisplayFamily_DisplayModel encoding of 06H_EH and above,
    1.28 +     * a MCA signal is broadcast to all logical processors in the system
    1.29 +     */
    1.30 +    if (c->x86_vendor == X86_VENDOR_INTEL && c->x86 == 6 &&
    1.31 +        c->x86_model >= 0xe)
    1.32 +            return 1;
    1.33 +    return 0;
    1.34 +}
    1.35 +
    1.36  /*
    1.37   * Check if bank 0 is usable for MCE. It isn't for AMD K7,
    1.38   * and Intel P6 family before model 0x1a.
    1.39 @@ -608,13 +625,24 @@ int mce_firstbank(struct cpuinfo_x86 *c)
    1.40  /* This has to be run for each processor */
    1.41  void mcheck_init(struct cpuinfo_x86 *c)
    1.42  {
    1.43 -	int inited = 0, i;
    1.44 +	int inited = 0, i, broadcast;
    1.45 +    static int broadcast_check;
    1.46  
    1.47  	if (mce_disabled == 1) {
    1.48 -		printk(XENLOG_INFO "MCE support disabled by bootparam\n");
    1.49 +		dprintk(XENLOG_INFO, "MCE support disabled by bootparam\n");
    1.50  		return;
    1.51  	}
    1.52  
    1.53 +    broadcast = mce_is_broadcast(c);
    1.54 +    if (broadcast_check && (broadcast != mce_broadcast) )
    1.55 +            dprintk(XENLOG_INFO,
    1.56 +                "CPUs have mixed broadcast support"
    1.57 +                "may cause undetermined result!!!\n");
    1.58 +
    1.59 +    broadcast_check = 1;
    1.60 +    if (broadcast)
    1.61 +        mce_broadcast = broadcast;
    1.62 +
    1.63  	for (i = 0; i < MAX_NR_BANKS; i++)
    1.64  		set_bit(i,mca_allbanks);
    1.65  
    1.66 @@ -1542,14 +1570,17 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u
    1.67  
    1.68  		if (target >= NR_CPUS)
    1.69  			return x86_mcerr("do_mca #MC: bad target", -EINVAL);
    1.70 -		       
    1.71 +
    1.72  		if (!cpu_isset(target, cpu_online_map))
    1.73  			return x86_mcerr("do_mca #MC: target offline", -EINVAL);
    1.74  
    1.75  		add_taint(TAINT_ERROR_INJECT);
    1.76  
    1.77 -		on_selected_cpus(cpumask_of(target), x86_mc_mceinject,
    1.78 -		                 mc_mceinject, 1);
    1.79 +        if ( mce_broadcast )
    1.80 +            on_each_cpu(x86_mc_mceinject, mc_mceinject, 0);
    1.81 +        else
    1.82 +            on_selected_cpus(cpumask_of(target), x86_mc_mceinject,
    1.83 +                  mc_mceinject, 1);
    1.84  		break;
    1.85  
    1.86  	default:
     2.1 --- a/xen/arch/x86/cpu/mcheck/mce.h	Fri Jan 29 06:49:13 2010 +0000
     2.2 +++ b/xen/arch/x86/cpu/mcheck/mce.h	Fri Jan 29 06:49:42 2010 +0000
     2.3 @@ -121,6 +121,7 @@ DECLARE_PER_CPU(cpu_banks_t, no_cmci_ban
     2.4  extern int cmci_support;
     2.5  extern int ser_support;
     2.6  extern int is_mc_panic;
     2.7 +extern int mce_broadcast;
     2.8  extern void mcheck_mca_clearbanks(cpu_banks_t);
     2.9  
    2.10  extern mctelem_cookie_t mcheck_mca_logout(enum mca_source, cpu_banks_t,
     3.1 --- a/xen/arch/x86/cpu/mcheck/mce_intel.c	Fri Jan 29 06:49:13 2010 +0000
     3.2 +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c	Fri Jan 29 06:49:42 2010 +0000
     3.3 @@ -612,6 +612,8 @@ static void mce_barrier_enter(struct mce
     3.4  {
     3.5        int gen;
     3.6  
     3.7 +      if (!mce_broadcast)
     3.8 +          return;
     3.9        atomic_inc(&bar->ingen);
    3.10        gen = atomic_read(&bar->outgen);
    3.11        mb();
    3.12 @@ -627,6 +629,8 @@ static void mce_barrier_exit(struct mce_
    3.13  {
    3.14        int gen;
    3.15  
    3.16 +      if (!mce_broadcast)
    3.17 +          return;
    3.18        atomic_inc(&bar->outgen);
    3.19        gen = atomic_read(&bar->ingen);
    3.20        mb();