[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86 mce: Change the method to get the extended MCA information.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1275922008 -3600 # Node ID b704a2e22fd672136817e3ad8b0e5aa6f146bc93 # Parent b9d824ff0bbc9fe12c947ee994b9a8d1a3dbeb65 x86 mce: Change the method to get the extended MCA information. Several changes to get the extended MCA information: a) Use the x86_mcinfo_reserve in mcinfo_extended to reserve buffer from mc_info, instead of using the stack b) For intel's extended MSR, we don't need write them one by one as the MSR are continous c) We don't need enum mca_extinfo, since we can consider the extended MSR as either per bank, or global. Currently we add a hook in global data collection, and didn't call register intel_get_extended_msrs as callback. Later that hook can be replaced by cleaner way Signed-off-by: Jiang, Yunhong <yunhong.jiang@xxxxxxxx> --- xen/arch/x86/cpu/mcheck/amd_f10.c | 42 ++++++++++++---------- xen/arch/x86/cpu/mcheck/mce.c | 15 +++++--- xen/arch/x86/cpu/mcheck/mce.h | 8 ---- xen/arch/x86/cpu/mcheck/mce_intel.c | 67 ++++++++++++++++-------------------- 4 files changed, 67 insertions(+), 65 deletions(-) diff -r b9d824ff0bbc -r b704a2e22fd6 xen/arch/x86/cpu/mcheck/amd_f10.c --- a/xen/arch/x86/cpu/mcheck/amd_f10.c Mon Jun 07 15:45:56 2010 +0100 +++ b/xen/arch/x86/cpu/mcheck/amd_f10.c Mon Jun 07 15:46:48 2010 +0100 @@ -49,37 +49,43 @@ #include "x86_mca.h" -static enum mca_extinfo +static struct mcinfo_extended * amd_f10_handler(struct mc_info *mi, uint16_t bank, uint64_t status) { - struct mcinfo_extended mc_ext; + struct mcinfo_extended *mc_ext; /* Family 0x10 introduced additional MSR that belong to the * northbridge bank (4). */ if (mi == NULL || bank != 4) - return MCA_EXTINFO_IGNORED; + return NULL; if (!(status & MCi_STATUS_VAL)) - return MCA_EXTINFO_IGNORED; + return NULL; if (!(status & MCi_STATUS_MISCV)) - return MCA_EXTINFO_IGNORED; + return NULL; - memset(&mc_ext, 0, sizeof(mc_ext)); - mc_ext.common.type = MC_TYPE_EXTENDED; - mc_ext.common.size = sizeof(mc_ext); - mc_ext.mc_msrs = 3; + mc_ext = x86_mcinfo_reserve(mi, sizeof(struct mcinfo_extended)); + if (!mc_ext) + { + mi->flags |= MCINFO_FLAGS_UNCOMPLETE; + return NULL; + } - mc_ext.mc_msr[0].reg = MSR_F10_MC4_MISC1; - mc_ext.mc_msr[1].reg = MSR_F10_MC4_MISC2; - mc_ext.mc_msr[2].reg = MSR_F10_MC4_MISC3; + memset(mc_ext, 0, sizeof(mc_ext)); + mc_ext->common.type = MC_TYPE_EXTENDED; + mc_ext->common.size = sizeof(mc_ext); + mc_ext->mc_msrs = 3; - mca_rdmsrl(MSR_F10_MC4_MISC1, mc_ext.mc_msr[0].value); - mca_rdmsrl(MSR_F10_MC4_MISC2, mc_ext.mc_msr[1].value); - mca_rdmsrl(MSR_F10_MC4_MISC3, mc_ext.mc_msr[2].value); - - x86_mcinfo_add(mi, &mc_ext); - return MCA_EXTINFO_LOCAL; + mc_ext->mc_msr[0].reg = MSR_F10_MC4_MISC1; + mc_ext->mc_msr[1].reg = MSR_F10_MC4_MISC2; + mc_ext->mc_msr[2].reg = MSR_F10_MC4_MISC3; + + mca_rdmsrl(MSR_F10_MC4_MISC1, mc_ext->mc_msr[0].value); + mca_rdmsrl(MSR_F10_MC4_MISC2, mc_ext->mc_msr[1].value); + mca_rdmsrl(MSR_F10_MC4_MISC3, mc_ext->mc_msr[2].value); + + return mc_ext; } /* AMD Family10 machine check */ diff -r b9d824ff0bbc -r b704a2e22fd6 xen/arch/x86/cpu/mcheck/mce.c --- a/xen/arch/x86/cpu/mcheck/mce.c Mon Jun 07 15:45:56 2010 +0100 +++ b/xen/arch/x86/cpu/mcheck/mce.c Mon Jun 07 15:46:48 2010 +0100 @@ -229,7 +229,6 @@ mctelem_cookie_t mcheck_mca_logout(enum mctelem_class_t which = MC_URGENT; /* XXXgcc */ int errcnt = 0; int i; - enum mca_extinfo cbret = MCA_EXTINFO_IGNORED; mca_rdmsrl(MSR_IA32_MCG_STATUS, gstatus); switch (who) { @@ -291,6 +290,15 @@ mctelem_cookie_t mcheck_mca_logout(enum /* mc_info should at least hold up the global information */ ASSERT(mig); mca_init_global(mc_flags, mig); + /* A hook here to get global extended msrs */ + { + struct mcinfo_extended *intel_get_extended_msrs( + struct mcinfo_global *mig, struct mc_info *mi); + + if (boot_cpu_data.x86_vendor == + X86_VENDOR_INTEL) + intel_get_extended_msrs(mig, mci); + } } } @@ -309,9 +317,8 @@ mctelem_cookie_t mcheck_mca_logout(enum mib = mca_init_bank(who, mci, i); - if (mc_callback_bank_extended && cbret != MCA_EXTINFO_GLOBAL) { - cbret = mc_callback_bank_extended(mci, i, status); - } + if (mc_callback_bank_extended) + mc_callback_bank_extended(mci, i, status); /* By default, need_clear = 1 */ if (who != MCA_MCE_SCAN && need_clear) diff -r b9d824ff0bbc -r b704a2e22fd6 xen/arch/x86/cpu/mcheck/mce.h --- a/xen/arch/x86/cpu/mcheck/mce.h Mon Jun 07 15:45:56 2010 +0100 +++ b/xen/arch/x86/cpu/mcheck/mce.h Mon Jun 07 15:46:48 2010 +0100 @@ -110,12 +110,6 @@ enum mca_source { MCA_MCE_SCAN }; -enum mca_extinfo { - MCA_EXTINFO_LOCAL, - MCA_EXTINFO_GLOBAL, - MCA_EXTINFO_IGNORED -}; - struct mca_summary { uint32_t errcnt; /* number of banks with valid errors */ int ripv; /* meaningful on #MC */ @@ -157,7 +151,7 @@ typedef int (*mce_need_clearbank_t)(enum typedef int (*mce_need_clearbank_t)(enum mca_source who, u64 status); extern void mce_need_clearbank_register(mce_need_clearbank_t); -typedef enum mca_extinfo (*x86_mce_callback_t) +typedef struct mcinfo_extended *(*x86_mce_callback_t) (struct mc_info *, uint16_t, uint64_t); extern void x86_mce_callback_register(x86_mce_callback_t); diff -r b9d824ff0bbc -r b704a2e22fd6 xen/arch/x86/cpu/mcheck/mce_intel.c --- a/xen/arch/x86/cpu/mcheck/mce_intel.c Mon Jun 07 15:45:56 2010 +0100 +++ b/xen/arch/x86/cpu/mcheck/mce_intel.c Mon Jun 07 15:46:48 2010 +0100 @@ -155,52 +155,48 @@ static inline void intel_get_extended_ms if ( ext->mc_msrs < ARRAY_SIZE(ext->mc_msr) && msr < MSR_IA32_MCG_EAX + nr_intel_ext_msrs ) { ext->mc_msr[ext->mc_msrs].reg = msr; - mca_rdmsrl(msr, ext->mc_msr[ext->mc_msrs].value); + rdmsrl(msr, ext->mc_msr[ext->mc_msrs].value); ++ext->mc_msrs; } } -static enum mca_extinfo -intel_get_extended_msrs(struct mc_info *mci, uint16_t bank, uint64_t status) -{ - struct mcinfo_extended mc_ext; - - if (mci == NULL || nr_intel_ext_msrs == 0 || !(status & MCG_STATUS_EIPV)) - return MCA_EXTINFO_IGNORED; + +struct mcinfo_extended * +intel_get_extended_msrs(struct mcinfo_global *mig, struct mc_info *mi) +{ + struct mcinfo_extended *mc_ext; + int i; + + /* + * According to spec, processor _support_ 64 bit will always + * have MSR beyond IA32_MCG_MISC + */ + if (!mi|| !mig || nr_intel_ext_msrs == 0 || + !(mig->mc_gstatus & MCG_STATUS_EIPV)) + return NULL; + + mc_ext = x86_mcinfo_reserve(mi, sizeof(struct mcinfo_extended)); + if (!mc_ext) + { + mi->flags |= MCINFO_FLAGS_UNCOMPLETE; + return NULL; + } /* this function will called when CAP(9).MCG_EXT_P = 1 */ memset(&mc_ext, 0, sizeof(struct mcinfo_extended)); - mc_ext.common.type = MC_TYPE_EXTENDED; - mc_ext.common.size = sizeof(mc_ext); - - intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_EAX); - intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_EBX); - intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_ECX); - intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_EDX); - intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_ESI); - intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_EDI); - intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_EBP); - intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_ESP); - intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_EFLAGS); - intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_EIP); - intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_MISC); + mc_ext->common.type = MC_TYPE_EXTENDED; + mc_ext->common.size = sizeof(struct mcinfo_extended); + + for (i = MSR_IA32_MCG_EAX; i <= MSR_IA32_MCG_MISC; i++) + intel_get_extended_msr(mc_ext, i); #ifdef __x86_64__ - intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_R8); - intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_R9); - intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_R10); - intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_R11); - intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_R12); - intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_R13); - intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_R14); - intel_get_extended_msr(&mc_ext, MSR_IA32_MCG_R15); + for (i = MSR_IA32_MCG_R8; i <= MSR_IA32_MCG_R15; i++) + intel_get_extended_msr(mc_ext, i); #endif - x86_mcinfo_add(mci, &mc_ext); - - return MCA_EXTINFO_GLOBAL; -} - + return mc_ext; +} static void intel_UCR_handler(struct mcinfo_bank *bank, struct mcinfo_global *global, @@ -960,7 +956,6 @@ enum mcheck_type intel_mcheck_init(struc /* machine check is available */ x86_mce_vector_register(intel_machine_check); - x86_mce_callback_register(intel_get_extended_msrs); mce_recoverable_register(intel_recoverable_scan); mce_need_clearbank_register(intel_need_clearbank_scan); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |