[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.