debuggers.hg

changeset 20963:da7ae6d8838a

x86: MCE fixes

- fill_vmsr_data() leaked a domain reference; since the caller already
obtained one, there's no need to obtain another one here
- intel_UCR_handler() could call put_domain() with a NULL pointer
- mcheck_mca_logout() updated a local data structure that wasn't used
after the update

Signed-off-by: Jan Beulich <jbeulich@novell.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Feb 10 09:18:11 2010 +0000 (2010-02-10)
parents 869884b93584
children a3fa6d444b25
files xen/arch/x86/cpu/mcheck/mce.c xen/arch/x86/cpu/mcheck/mce_intel.c
line diff
     1.1 --- a/xen/arch/x86/cpu/mcheck/mce.c	Wed Feb 10 09:09:35 2010 +0000
     1.2 +++ b/xen/arch/x86/cpu/mcheck/mce.c	Wed Feb 10 09:18:11 2010 +0000
     1.3 @@ -300,13 +300,15 @@ mctelem_cookie_t mcheck_mca_logout(enum 
     1.4  
     1.5  	if (mci != NULL && errcnt > 0) {
     1.6  		x86_mcinfo_lookup(mic, mci, MC_TYPE_GLOBAL);
     1.7 -		mig = (struct mcinfo_global *)mic;
     1.8 -		if (pcc)
     1.9 -			mcg.mc_flags |= MC_FLAG_UNCORRECTABLE;
    1.10 +		mig = container_of(mic, struct mcinfo_global, common);
    1.11 +		if (mic == NULL)
    1.12 +			;
    1.13 +		else if (pcc)
    1.14 +			mig->mc_flags |= MC_FLAG_UNCORRECTABLE;
    1.15  		else if (uc)
    1.16 -			mcg.mc_flags |= MC_FLAG_RECOVERABLE;
    1.17 +			mig->mc_flags |= MC_FLAG_RECOVERABLE;
    1.18  		else
    1.19 -			mcg.mc_flags |= MC_FLAG_CORRECTABLE;
    1.20 +			mig->mc_flags |= MC_FLAG_CORRECTABLE;
    1.21  	}
    1.22  
    1.23  
     2.1 --- a/xen/arch/x86/cpu/mcheck/mce_intel.c	Wed Feb 10 09:09:35 2010 +0000
     2.2 +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c	Wed Feb 10 09:18:11 2010 +0000
     2.3 @@ -225,22 +225,13 @@ static struct bank_entry* alloc_bank_ent
     2.4        for vMCE# MSRs virtualization
     2.5  */
     2.6  
     2.7 -static int fill_vmsr_data(struct mcinfo_bank *mc_bank, 
     2.8 +static int fill_vmsr_data(struct mcinfo_bank *mc_bank, struct domain *d,
     2.9          uint64_t gstatus) {
    2.10 -    struct domain *d;
    2.11      struct bank_entry *entry;
    2.12  
    2.13      /* This error bank impacts one domain, we need to fill domain related
    2.14       * data for vMCE MSRs virtualization and vMCE# injection */
    2.15      if (mc_bank->mc_domid != (uint16_t)~0) {
    2.16 -        d = get_domain_by_id(mc_bank->mc_domid);
    2.17 -
    2.18 -        /* Not impact a valid domain, skip this error of the bank */
    2.19 -        if (!d) {
    2.20 -            mce_printk(MCE_QUIET, "MCE: Not found valid impacted DOM\n");
    2.21 -            return 0;
    2.22 -        }
    2.23 -
    2.24          /* For HVM guest, Only when first vMCE is consumed by HVM guest successfully,
    2.25           * will we generete another node and inject another vMCE
    2.26           */
    2.27 @@ -365,15 +356,18 @@ static void intel_UCR_handler(struct mci
    2.28                            if ( mca_ctl_conflict(bank, d) )
    2.29                            {
    2.30                                /* Guest has different MCE ctl with hypervisor */
    2.31 -                              put_domain(d);
    2.32 +                              if ( d )
    2.33 +                                  put_domain(d);
    2.34                                return;
    2.35                            }
    2.36  
    2.37 +                          ASSERT(d);
    2.38                            gfn =
    2.39                                get_gpfn_from_mfn((bank->mc_addr) >> PAGE_SHIFT);
    2.40                            bank->mc_addr =  gfn << PAGE_SHIFT |
    2.41                                          (bank->mc_addr & (PAGE_SIZE -1 ));
    2.42 -                          if (fill_vmsr_data(bank, global->mc_gstatus) == -1)
    2.43 +                          if ( fill_vmsr_data(bank, d,
    2.44 +                                              global->mc_gstatus) == -1 )
    2.45                            {
    2.46                                mce_printk(MCE_QUIET, "Fill vMCE# data for DOM%d "
    2.47                                        "failed\n", result->owner);