@@ -594,10 +594,12 @@ int show_mca_info(int inited, struct cpuinfo_x86 *c)
printk("%s%s machine check reporting enabled\n",
prefix, type_str[inited]);
break;
+
case mcheck_amd_famXX:
printk("%s%s Fam%xh machine check reporting enabled\n",
prefix, type_str[inited], c->x86);
break;
+
case mcheck_none:
printk("%sNo machine check initialization\n", prefix);
break;
@@ -703,10 +705,12 @@ static int cpu_callback(
case CPU_UP_PREPARE:
rc = cpu_bank_alloc(cpu);
break;
+
case CPU_UP_CANCELED:
case CPU_DEAD:
cpu_bank_free(cpu);
break;
+
default:
break;
}
@@ -1516,6 +1520,7 @@ long do_mca(XEN_GUEST_HANDLE_PARAM(xen_mc_t) u_xen_mc)
printk("Not trigger MCE on all CPUs, may HANG!\n");
on_selected_cpus(cpumap, x86_mc_mceinject, NULL, 1);
break;
+
case XEN_MC_INJECT_TYPE_CMCI:
if ( !cmci_apic_vector )
ret = x86_mcerr(
@@ -1527,6 +1532,7 @@ long do_mca(XEN_GUEST_HANDLE_PARAM(xen_mc_t) u_xen_mc)
send_IPI_mask(cpumap, cmci_apic_vector);
}
break;
+
default:
ret = x86_mcerr("Wrong mca type\n", -EINVAL);
break;
@@ -1673,16 +1679,19 @@ static int mce_delayed_action(mctelem_cookie_t mctc)
x86_mcinfo_dump(mctelem_dataptr(mctc));
panic("MCE: Software recovery failed for the UCR");
break;
+
case MCER_RECOVERED:
dprintk(XENLOG_INFO, "MCE: Error is successfully recovered\n");
ret = 1;
break;
+
case MCER_CONTINUE:
dprintk(XENLOG_INFO, "MCE: Error can't be recovered, "
"system is tainted\n");
x86_mcinfo_dump(mctelem_dataptr(mctc));
ret = 1;
break;
+
default:
ret = 0;
break;
@@ -158,6 +158,7 @@ static inline int mce_vendor_bank_msr(const struct vcpu *v, uint32_t msr)
msr < MSR_IA32_MCx_CTL2(v->arch.vmce.mcg_cap & MCG_CAP_COUNT) )
return 1;
break;
+
case X86_VENDOR_AMD:
switch (msr) {
case MSR_F10_MC4_MISC1:
@@ -121,9 +121,11 @@ mc_amd_recoverable_scan(uint64_t status)
case MC_EC_BUS_TYPE: /* value in addr MSR is physical */
/* should run cpu offline action */
break;
+
case MC_EC_MEM_TYPE: /* value in addr MSR is physical */
ret = true; /* run memory page offline action */
break;
+
case MC_EC_TLB_TYPE: /* value in addr MSR is virtual */
/* should run tlb flush action and retry */
break;
@@ -146,6 +148,7 @@ mc_amd_addrcheck(uint64_t status, uint64_t misc, int addrtype)
case MC_EC_BUS_TYPE: /* value in addr MSR is physical */
case MC_EC_MEM_TYPE: /* value in addr MSR is physical */
return (addrtype == MC_ADDR_PHYSICAL);
+
case MC_EC_TLB_TYPE: /* value in addr MSR is virtual */
return (addrtype == MC_ADDR_VIRTUAL);
}
@@ -193,6 +196,7 @@ int mcequirk_amd_apply(enum mcequirk_amd_flags flags)
wrmsrl(MSR_IA32_MCx_CTL(4), ~(1ULL << 10));
wrmsrl(MSR_IA32_MCx_STATUS(4), 0ULL);
break;
+
case MCEQUIRK_F10_GART:
if ( rdmsr_safe(MSR_AMD64_MCx_MASK(4), val) == 0 )
wrmsr_safe(MSR_AMD64_MCx_MASK(4), val | (1 << 10));
@@ -302,6 +302,7 @@ static void intel_srar_dhandler(
case INTEL_SRAR_INSTR_FETCH:
intel_memerr_dhandler(binfo, result, regs);
break;
+
default:
break;
}
@@ -330,6 +331,7 @@ static void intel_srao_dhandler(
case INTEL_SRAO_L3_EWB:
intel_memerr_dhandler(binfo, result, regs);
break;
+
default:
break;
}
@@ -378,6 +380,7 @@ static void intel_default_mce_uhandler(
case intel_mce_fatal:
*result = MCER_RESET;
break;
+
default:
*result = MCER_CONTINUE;
break;
@@ -843,14 +846,17 @@ static int cpu_callback(
case CPU_UP_PREPARE:
rc = cpu_mcabank_alloc(cpu);
break;
+
case CPU_DYING:
cpu_mcheck_disable();
break;
+
case CPU_UP_CANCELED:
case CPU_DEAD:
cpu_mcheck_distribute_cmci();
cpu_mcabank_free(cpu);
break;
+
default:
break;
}
@@ -113,6 +113,7 @@ static int bank_mce_rdmsr(const struct vcpu *v, uint32_t msr, uint64_t *val)
mce_printk(MCE_VERBOSE, "MCE: %pv: rd MC%u_CTL %#"PRIx64"\n",
v, bank, *val);
break;
+
case MSR_IA32_MC0_STATUS:
if ( bank < GUEST_MC_BANK_NUM )
{
@@ -122,6 +123,7 @@ static int bank_mce_rdmsr(const struct vcpu *v, uint32_t msr, uint64_t *val)
v, bank, *val);
}
break;
+
case MSR_IA32_MC0_ADDR:
if ( bank < GUEST_MC_BANK_NUM )
{
@@ -131,6 +133,7 @@ static int bank_mce_rdmsr(const struct vcpu *v, uint32_t msr, uint64_t *val)
v, bank, *val);
}
break;
+
case MSR_IA32_MC0_MISC:
if ( bank < GUEST_MC_BANK_NUM )
{
@@ -140,15 +143,18 @@ static int bank_mce_rdmsr(const struct vcpu *v, uint32_t msr, uint64_t *val)
v, bank, *val);
}
break;
+
default:
switch ( boot_cpu_data.x86_vendor )
{
case X86_VENDOR_INTEL:
ret = vmce_intel_rdmsr(v, msr, val);
break;
+
case X86_VENDOR_AMD:
ret = vmce_amd_rdmsr(v, msr, val);
break;
+
default:
ret = 0;
break;
@@ -181,15 +187,18 @@ int vmce_rdmsr(uint32_t msr, uint64_t *val)
mce_printk(MCE_VERBOSE,
"MCE: %pv: rd MCG_STATUS %#"PRIx64"\n", cur, *val);
break;
+
case MSR_IA32_MCG_CAP:
*val = cur->arch.vmce.mcg_cap;
mce_printk(MCE_VERBOSE, "MCE: %pv: rd MCG_CAP %#"PRIx64"\n", cur, *val);
break;
+
case MSR_IA32_MCG_CTL:
if ( cur->arch.vmce.mcg_cap & MCG_CTL_P )
*val = ~0ULL;
mce_printk(MCE_VERBOSE, "MCE: %pv: rd MCG_CTL %#"PRIx64"\n", cur, *val);
break;
+
default:
ret = mce_bank_msr(cur, msr) ? bank_mce_rdmsr(cur, msr, val) : 0;
break;
@@ -217,6 +226,7 @@ static int bank_mce_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val)
* treat it as not implement and ignore write change it.
*/
break;
+
case MSR_IA32_MC0_STATUS:
mce_printk(MCE_VERBOSE, "MCE: %pv: wr MC%u_STATUS %#"PRIx64"\n",
v, bank, val);
@@ -225,6 +235,7 @@ static int bank_mce_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val)
else if ( bank < GUEST_MC_BANK_NUM )
v->arch.vmce.bank[bank].mci_status = val;
break;
+
case MSR_IA32_MC0_ADDR:
mce_printk(MCE_VERBOSE, "MCE: %pv: wr MC%u_ADDR %#"PRIx64"\n",
v, bank, val);
@@ -233,6 +244,7 @@ static int bank_mce_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val)
else if ( bank < GUEST_MC_BANK_NUM )
v->arch.vmce.bank[bank].mci_addr = val;
break;
+
case MSR_IA32_MC0_MISC:
mce_printk(MCE_VERBOSE, "MCE: %pv: wr MC%u_MISC %#"PRIx64"\n",
v, bank, val);
@@ -241,15 +253,18 @@ static int bank_mce_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val)
else if ( bank < GUEST_MC_BANK_NUM )
v->arch.vmce.bank[bank].mci_misc = val;
break;
+
default:
switch ( boot_cpu_data.x86_vendor )
{
case X86_VENDOR_INTEL:
ret = vmce_intel_wrmsr(v, msr, val);
break;
+
case X86_VENDOR_AMD:
ret = vmce_amd_wrmsr(v, msr, val);
break;
+
default:
ret = 0;
break;
@@ -277,11 +292,13 @@ int vmce_wrmsr(uint32_t msr, uint64_t val)
case MSR_IA32_MCG_CTL:
/* If MCG_CTL exists then stick to all 1's, else ignore. */
break;
+
case MSR_IA32_MCG_STATUS:
cur->arch.vmce.mcg_status = val;
mce_printk(MCE_VERBOSE, "MCE: %pv: wr MCG_STATUS %"PRIx64"\n",
cur, val);
break;
+
case MSR_IA32_MCG_CAP:
/*
* According to Intel SDM, IA32_MCG_CAP is a read-only register,
@@ -290,6 +307,7 @@ int vmce_wrmsr(uint32_t msr, uint64_t val)
*/
mce_printk(MCE_VERBOSE, "MCE: %pv: MCG_CAP is r/o\n", cur);
break;
+
default:
ret = mce_bank_msr(cur, msr) ? bank_mce_wrmsr(cur, msr, val) : 0;
break;
Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com> --- Cc: Jan Beulich <jbeulich@suse.com> Cc: Andrew Cooper <andrew.cooper3@citrix.com> --- xen/arch/x86/cpu/mcheck/mce.c | 9 +++++++++ xen/arch/x86/cpu/mcheck/mce.h | 1 + xen/arch/x86/cpu/mcheck/mce_amd.c | 4 ++++ xen/arch/x86/cpu/mcheck/mce_intel.c | 6 ++++++ xen/arch/x86/cpu/mcheck/vmce.c | 18 ++++++++++++++++++ 5 files changed, 38 insertions(+)