[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] x86 mce: Re-arrange mce_intel.c, to make it more clean



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1276154210 -3600
# Node ID 104da3a219fa0e3c22c77abb1db35357d1e2c344
# Parent  65b27a094ec826a5a7db2d53e77988c3d76cef63
x86 mce: Re-arrange mce_intel.c, to make it more clean

Seperate logic for MCE handling, Intel MCA, MCE, CMCI handler, to make
it more clean. No logic changes in this patch.

Signed-off-by: Jiang, Yunhong <yunhong.jiang@xxxxxxxxx>
---
 xen/arch/x86/cpu/mcheck/mce_intel.c |  303 ++++++++++++++++++------------------
 1 files changed, 156 insertions(+), 147 deletions(-)

diff -r 65b27a094ec8 -r 104da3a219fa xen/arch/x86/cpu/mcheck/mce_intel.c
--- a/xen/arch/x86/cpu/mcheck/mce_intel.c       Wed Jun 09 14:38:30 2010 +0100
+++ b/xen/arch/x86/cpu/mcheck/mce_intel.c       Thu Jun 10 08:16:50 2010 +0100
@@ -26,30 +26,7 @@ boolean_param("mce_fb", mce_force_broadc
 
 static int nr_intel_ext_msrs = 0;
 
-/* Below are for MCE handling */
-struct mce_softirq_barrier {
-    atomic_t val;
-    atomic_t ingen;
-    atomic_t outgen;
-};
-
-static struct mce_softirq_barrier mce_inside_bar, mce_severity_bar;
-static struct mce_softirq_barrier mce_trap_bar;
-
-/*
- * mce_logout_lock should only be used in the trap handler,
- * while MCIP has not been cleared yet in the global status
- * register. Other use is not safe, since an MCE trap can
- * happen at any moment, which would cause lock recursion.
- */
-static DEFINE_SPINLOCK(mce_logout_lock);
-
-static atomic_t severity_cpu = ATOMIC_INIT(-1);
-static atomic_t found_error = ATOMIC_INIT(0);
-
-static void mce_barrier_enter(struct mce_softirq_barrier *);
-static void mce_barrier_exit(struct mce_softirq_barrier *);
-
+/* Thermal Hanlding */
 #ifdef CONFIG_X86_MCE_THERMAL
 static void unexpected_thermal_interrupt(struct cpu_user_regs *regs)
 {
@@ -153,133 +130,34 @@ static void intel_init_thermal(struct cp
 }
 #endif /* CONFIG_X86_MCE_THERMAL */
 
-static inline void intel_get_extended_msr(struct mcinfo_extended *ext, u32 msr)
-{
-    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;
-        rdmsrl(msr, ext->mc_msr[ext->mc_msrs].value);
-        ++ext->mc_msrs;
-    }
-}
-
-
-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(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__
-    for (i = MSR_IA32_MCG_R8; i <= MSR_IA32_MCG_R15; i++)
-        intel_get_extended_msr(mc_ext, i);
-#endif
-
-    return mc_ext;
-}
+/* MCE handling */
+struct mce_softirq_barrier {
+       atomic_t val;
+       atomic_t ingen;
+       atomic_t outgen;
+};
+
+static struct mce_softirq_barrier mce_inside_bar, mce_severity_bar;
+static struct mce_softirq_barrier mce_trap_bar;
+
+/*
+ * mce_logout_lock should only be used in the trap handler,
+ * while MCIP has not been cleared yet in the global status
+ * register. Other use is not safe, since an MCE trap can
+ * happen at any moment, which would cause lock recursion.
+ */
+static DEFINE_SPINLOCK(mce_logout_lock);
+
+static atomic_t severity_cpu = ATOMIC_INIT(-1);
+static atomic_t found_error = ATOMIC_INIT(0);
+
+static void mce_barrier_enter(struct mce_softirq_barrier *);
+static void mce_barrier_exit(struct mce_softirq_barrier *);
 
 static void intel_UCR_handler(struct mcinfo_bank *bank,
              struct mcinfo_global *global,
              struct mcinfo_extended *extension,
-             struct mca_handle_result *result)
-{
-    struct domain *d;
-    unsigned long mfn, gfn;
-    uint32_t status;
-
-    mce_printk(MCE_VERBOSE, "MCE: Enter UCR recovery action\n");
-    result->result = MCA_NEED_RESET;
-    if (bank->mc_addr != 0) {
-         mfn = bank->mc_addr >> PAGE_SHIFT;
-         if (!offline_page(mfn, 1, &status)) {
-              /* This is free page */
-              if (status & PG_OFFLINE_OFFLINED)
-                  result->result = MCA_RECOVERED;
-              else if (status & PG_OFFLINE_PENDING) {
-                 /* This page has owner */
-                  if (status & PG_OFFLINE_OWNED) {
-                      result->result |= MCA_OWNER;
-                      result->owner = status >> PG_OFFLINE_OWNER_SHIFT;
-                      mce_printk(MCE_QUIET, "MCE: This error page is ownded"
-                                  " by DOM %d\n", result->owner);
-                      /* Fill vMCE# injection and vMCE# MSR virtualization "
-                       * "related data */
-                      bank->mc_domid = result->owner;
-                      /* XXX: Cannot handle shared pages yet 
-                       * (this should identify all domains and gfn mapping to
-                       *  the mfn in question) */
-                      BUG_ON( result->owner == DOMID_COW );
-                      if ( result->owner != DOMID_XEN ) {
-
-                          d = get_domain_by_id(result->owner);
-                          if ( mca_ctl_conflict(bank, d) )
-                          {
-                              /* Guest has different MCE ctl with hypervisor */
-                              if ( d )
-                                  put_domain(d);
-                              return;
-                          }
-
-                          ASSERT(d);
-                          gfn =
-                              get_gpfn_from_mfn((bank->mc_addr) >> PAGE_SHIFT);
-                          bank->mc_addr =  gfn << PAGE_SHIFT |
-                                        (bank->mc_addr & (PAGE_SIZE -1 ));
-                          if ( fill_vmsr_data(bank, d,
-                                              global->mc_gstatus) == -1 )
-                          {
-                              mce_printk(MCE_QUIET, "Fill vMCE# data for DOM%d 
"
-                                      "failed\n", result->owner);
-                              put_domain(d);
-                              domain_crash(d);
-                              return;
-                          }
-                          /* We will inject vMCE to DOMU*/
-                          if ( inject_vmce(d) < 0 )
-                          {
-                              mce_printk(MCE_QUIET, "inject vMCE to DOM%d"
-                                          " failed\n", d->domain_id);
-                              put_domain(d);
-                              domain_crash(d);
-                              return;
-                          }
-                          /* Impacted domain go on with domain's recovery job
-                           * if the domain has its own MCA handler.
-                           * For xen, it has contained the error and finished
-                           * its own recovery job.
-                           */
-                          result->result = MCA_RECOVERED;
-                          put_domain(d);
-                      }
-                  }
-              }
-         }
-    }
-}
-
+             struct mca_handle_result *result);
 #define INTEL_MAX_RECOVERY 2
 struct mca_error_handler intel_recovery_handler[INTEL_MAX_RECOVERY] =
             {{0x017A, intel_UCR_handler}, {0x00C0, intel_UCR_handler}};
@@ -526,6 +404,134 @@ static void mce_barrier(struct mce_softi
 }
 #endif
 
+/* Intel MCE handler */
+static inline void intel_get_extended_msr(struct mcinfo_extended *ext, u32 msr)
+{
+    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;
+        rdmsrl(msr, ext->mc_msr[ext->mc_msrs].value);
+        ++ext->mc_msrs;
+    }
+}
+
+
+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(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__
+    for (i = MSR_IA32_MCG_R8; i <= MSR_IA32_MCG_R15; i++)
+        intel_get_extended_msr(mc_ext, i);
+#endif
+
+    return mc_ext;
+}
+
+static void intel_UCR_handler(struct mcinfo_bank *bank,
+             struct mcinfo_global *global,
+             struct mcinfo_extended *extension,
+             struct mca_handle_result *result)
+{
+    struct domain *d;
+    unsigned long mfn, gfn;
+    uint32_t status;
+
+    mce_printk(MCE_VERBOSE, "MCE: Enter UCR recovery action\n");
+    result->result = MCA_NEED_RESET;
+    if (bank->mc_addr != 0) {
+         mfn = bank->mc_addr >> PAGE_SHIFT;
+         if (!offline_page(mfn, 1, &status)) {
+              /* This is free page */
+              if (status & PG_OFFLINE_OFFLINED)
+                  result->result = MCA_RECOVERED;
+              else if (status & PG_OFFLINE_PENDING) {
+                 /* This page has owner */
+                  if (status & PG_OFFLINE_OWNED) {
+                      result->result |= MCA_OWNER;
+                      result->owner = status >> PG_OFFLINE_OWNER_SHIFT;
+                      mce_printk(MCE_QUIET, "MCE: This error page is ownded"
+                                  " by DOM %d\n", result->owner);
+                      /* Fill vMCE# injection and vMCE# MSR virtualization "
+                       * "related data */
+                      bank->mc_domid = result->owner;
+                      /* XXX: Cannot handle shared pages yet 
+                       * (this should identify all domains and gfn mapping to
+                       *  the mfn in question) */
+                      BUG_ON( result->owner == DOMID_COW );
+                      if ( result->owner != DOMID_XEN ) {
+
+                          d = get_domain_by_id(result->owner);
+                          if ( mca_ctl_conflict(bank, d) )
+                          {
+                              /* Guest has different MCE ctl with hypervisor */
+                              if ( d )
+                                  put_domain(d);
+                              return;
+                          }
+
+                          ASSERT(d);
+                          gfn =
+                              get_gpfn_from_mfn((bank->mc_addr) >> PAGE_SHIFT);
+                          bank->mc_addr =  gfn << PAGE_SHIFT |
+                                        (bank->mc_addr & (PAGE_SIZE -1 ));
+                          if ( fill_vmsr_data(bank, d,
+                                              global->mc_gstatus) == -1 )
+                          {
+                              mce_printk(MCE_QUIET, "Fill vMCE# data for DOM%d 
"
+                                      "failed\n", result->owner);
+                              put_domain(d);
+                              domain_crash(d);
+                              return;
+                          }
+                          /* We will inject vMCE to DOMU*/
+                          if ( inject_vmce(d) < 0 )
+                          {
+                              mce_printk(MCE_QUIET, "inject vMCE to DOM%d"
+                                          " failed\n", d->domain_id);
+                              put_domain(d);
+                              domain_crash(d);
+                              return;
+                          }
+                          /* Impacted domain go on with domain's recovery job
+                           * if the domain has its own MCA handler.
+                           * For xen, it has contained the error and finished
+                           * its own recovery job.
+                           */
+                          result->result = MCA_RECOVERED;
+                          put_domain(d);
+                      }
+                  }
+              }
+         }
+    }
+}
+
 static void intel_machine_check(struct cpu_user_regs * regs, long error_code)
 {
     uint64_t gstatus;
@@ -691,6 +697,7 @@ static int intel_recoverable_scan(u64 st
     return 0;
 }
 
+/* CMCI */
 static DEFINE_SPINLOCK(cmci_discover_lock);
 
 /*
@@ -881,6 +888,7 @@ fastcall void smp_cmci_interrupt(struct 
     set_irq_regs(old_regs);
 }
 
+/* MCA */
 void mce_intel_feature_init(struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_X86_MCE_THERMAL
@@ -1021,6 +1029,7 @@ enum mcheck_type intel_mcheck_init(struc
     return mcheck_intel;
 }
 
+/* intel specific MCA MSR */
 int intel_mce_wrmsr(uint32_t msr, uint64_t val)
 {
     int ret = 0;

_______________________________________________
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®.