WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] x86: mce: Provide extended physical CPU i

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86: mce: Provide extended physical CPU info.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 10 Feb 2009 04:35:10 -0800
Delivery-date: Tue, 10 Feb 2009 04:34:50 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1234245060 0
# Node ID 4ac8bc60c000500f7fa1aeccea708d2191f5f31a
# Parent  09ea7eea81229fc64276b5682778a131f2fd1e1b
x86: mce: Provide extended physical CPU info.

Provide extended physial CPU info for the sake of dom0 MCE handling.
This information includes <cpu,core,thread> info for all logical CPUs,
cpuid information from all of them, and initial MSR values for a few
MSRs that are important to MCE handling.

Signed-off-by: Frank van der Linden <Frank.Vanderlinden@xxxxxxx>
---
 xen/arch/x86/cpu/mcheck/amd_k8.c       |   14 +--
 xen/arch/x86/cpu/mcheck/amd_nonfatal.c |   13 +--
 xen/arch/x86/cpu/mcheck/mce.c          |  130 +++++++++++++++++++++++++++++++++
 xen/arch/x86/cpu/mcheck/mce.h          |    3 
 xen/arch/x86/cpu/mcheck/mce_intel.c    |    8 --
 xen/include/public/arch-x86/xen-mca.h  |   48 +++++++++++-
 6 files changed, 194 insertions(+), 22 deletions(-)

diff -r 09ea7eea8122 -r 4ac8bc60c000 xen/arch/x86/cpu/mcheck/amd_k8.c
--- a/xen/arch/x86/cpu/mcheck/amd_k8.c  Tue Feb 10 05:47:00 2009 +0000
+++ b/xen/arch/x86/cpu/mcheck/amd_k8.c  Tue Feb 10 05:51:00 2009 +0000
@@ -99,6 +99,8 @@ void k8_machine_check(struct cpu_user_re
 
        mc_data = x86_mcinfo_getptr();
        cpu_nr = smp_processor_id();
+       BUG_ON(cpu_nr != vcpu->processor);
+
        curdom = vcpu->domain;
 
        memset(&mc_global, 0, sizeof(mc_global));
@@ -106,14 +108,12 @@ void k8_machine_check(struct cpu_user_re
        mc_global.common.size = sizeof(mc_global);
 
        mc_global.mc_domid = curdom->domain_id; /* impacted domain */
-       mc_global.mc_coreid = vcpu->processor; /* impacted physical cpu */
-       BUG_ON(cpu_nr != vcpu->processor);
-       mc_global.mc_core_threadid = 0;
+
+       x86_mc_get_cpu_info(cpu_nr, &mc_global.mc_socketid,
+           &mc_global.mc_coreid, &mc_global.mc_core_threadid,
+           &mc_global.mc_apicid, NULL, NULL, NULL);
+
        mc_global.mc_vcpuid = vcpu->vcpu_id; /* impacted vcpu */
-#if 0 /* TODO: on which socket is this physical core?
-         It's not clear to me how to figure this out. */
-       mc_global.mc_socketid = ???;
-#endif
        mc_global.mc_flags |= MC_FLAG_UNCORRECTABLE;
        rdmsrl(MSR_IA32_MCG_STATUS, mc_global.mc_gstatus);
 
diff -r 09ea7eea8122 -r 4ac8bc60c000 xen/arch/x86/cpu/mcheck/amd_nonfatal.c
--- a/xen/arch/x86/cpu/mcheck/amd_nonfatal.c    Tue Feb 10 05:47:00 2009 +0000
+++ b/xen/arch/x86/cpu/mcheck/amd_nonfatal.c    Tue Feb 10 05:51:00 2009 +0000
@@ -95,6 +95,7 @@ void mce_amd_checkregs(void *info)
        mc_data = NULL;
 
        cpu_nr = smp_processor_id();
+       BUG_ON(cpu_nr != vcpu->processor);
        event_enabled = guest_enabled_event(dom0->vcpu[0], VIRQ_MCA);
        error_found = 0;
 
@@ -103,14 +104,12 @@ void mce_amd_checkregs(void *info)
        mc_global.common.size = sizeof(mc_global);
 
        mc_global.mc_domid = vcpu->domain->domain_id; /* impacted domain */
-       mc_global.mc_coreid = vcpu->processor; /* impacted physical cpu */
-       BUG_ON(cpu_nr != vcpu->processor);
-       mc_global.mc_core_threadid = 0;
        mc_global.mc_vcpuid = vcpu->vcpu_id; /* impacted vcpu */
-#if 0 /* TODO: on which socket is this physical core?
-         It's not clear to me how to figure this out. */
-       mc_global.mc_socketid = ???;
-#endif
+
+       x86_mc_get_cpu_info(cpu_nr, &mc_global.mc_socketid,
+           &mc_global.mc_coreid, &mc_global.mc_core_threadid,
+           &mc_global.mc_apicid, NULL, NULL, NULL);
+
        mc_global.mc_flags |= MC_FLAG_CORRECTABLE;
        rdmsrl(MSR_IA32_MCG_STATUS, mc_global.mc_gstatus);
 
diff -r 09ea7eea8122 -r 4ac8bc60c000 xen/arch/x86/cpu/mcheck/mce.c
--- a/xen/arch/x86/cpu/mcheck/mce.c     Tue Feb 10 05:47:00 2009 +0000
+++ b/xen/arch/x86/cpu/mcheck/mce.c     Tue Feb 10 05:51:00 2009 +0000
@@ -443,6 +443,96 @@ next:
 
 
 
+static void do_mc_get_cpu_info(void *v)
+{
+       int cpu = smp_processor_id();
+       int cindex, cpn;
+       struct cpuinfo_x86 *c;
+       xen_mc_logical_cpu_t *log_cpus, *xcp;
+       uint32_t junk, ebx;
+
+       log_cpus = v;
+       c = &cpu_data[cpu];
+       cindex = 0;
+       cpn = cpu - 1;
+
+       /*
+        * Deal with sparse masks, condensed into a contig array.
+        */
+       while (cpn >= 0) {
+               if (cpu_isset(cpn, cpu_online_map))
+                       cindex++;
+               cpn--;
+       }
+
+       xcp = &log_cpus[cindex];
+       c = &cpu_data[cpu];
+       xcp->mc_cpunr = cpu;
+       x86_mc_get_cpu_info(cpu, &xcp->mc_chipid,
+           &xcp->mc_coreid, &xcp->mc_threadid,
+           &xcp->mc_apicid, &xcp->mc_ncores,
+           &xcp->mc_ncores_active, &xcp->mc_nthreads);
+       xcp->mc_cpuid_level = c->cpuid_level;
+       xcp->mc_family = c->x86;
+       xcp->mc_vendor = c->x86_vendor;
+       xcp->mc_model = c->x86_model;
+       xcp->mc_step = c->x86_mask;
+       xcp->mc_cache_size = c->x86_cache_size;
+       xcp->mc_cache_alignment = c->x86_cache_alignment;
+       memcpy(xcp->mc_vendorid, c->x86_vendor_id, sizeof xcp->mc_vendorid);
+       memcpy(xcp->mc_brandid, c->x86_model_id, sizeof xcp->mc_brandid);
+       memcpy(xcp->mc_cpu_caps, c->x86_capability, sizeof xcp->mc_cpu_caps);
+
+       /*
+        * This part needs to run on the CPU itself.
+        */
+       xcp->mc_nmsrvals = __MC_NMSRS;
+       xcp->mc_msrvalues[0].reg = MSR_IA32_MCG_CAP;
+       rdmsrl(MSR_IA32_MCG_CAP, xcp->mc_msrvalues[0].value);
+
+       if (c->cpuid_level >= 1) {
+               cpuid(1, &junk, &ebx, &junk, &junk);
+               xcp->mc_clusterid = (ebx >> 24) & 0xff;
+       } else
+               xcp->mc_clusterid = hard_smp_processor_id();
+}
+
+
+void x86_mc_get_cpu_info(unsigned cpu, uint32_t *chipid, uint16_t *coreid,
+                        uint16_t *threadid, uint32_t *apicid,
+                        unsigned *ncores, unsigned *ncores_active,
+                        unsigned *nthreads)
+{
+       struct cpuinfo_x86 *c;
+
+       *apicid = cpu_physical_id(cpu);
+       c = &cpu_data[cpu];
+       if (c->apicid == BAD_APICID) {
+               *chipid = cpu;
+               *coreid = 0;
+               *threadid = 0;
+               if (ncores != NULL)
+                       *ncores = 1;
+               if (ncores_active != NULL)
+                       *ncores_active = 1;
+               if (nthreads != NULL)
+                       *nthreads = 1;
+       } else {
+               *chipid = phys_proc_id[cpu];
+               if (c->x86_max_cores > 1)
+                       *coreid = cpu_core_id[cpu];
+               else
+                       *coreid = 0;
+               *threadid = c->apicid & ((1 << (c->x86_num_siblings - 1)) - 1);
+               if (ncores != NULL)
+                       *ncores = c->x86_max_cores;
+               if (ncores_active != NULL)
+                       *ncores_active = c->booted_cores;
+               if (nthreads != NULL)
+                       *nthreads = c->x86_num_siblings;
+       }
+}
+
 /* Machine Check Architecture Hypercall */
 long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u_xen_mc)
 {
@@ -452,6 +542,7 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u
        struct domain *domU;
        struct xen_mc_fetch *mc_fetch;
        struct xen_mc_notifydomain *mc_notifydomain;
+       struct xen_mc_physcpuinfo *mc_physcpuinfo;
        struct mc_info *mi;
        uint32_t flags;
        uint32_t fetch_idx;
@@ -460,6 +551,8 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u
         * a DomU to fetch mc data while Dom0 notifies another DomU. */
        static DEFINE_SPINLOCK(mc_lock);
        static DEFINE_SPINLOCK(mc_notify_lock);
+       int nlcpu;
+       xen_mc_logical_cpu_t *log_cpus = NULL;
 
        if ( copy_from_guest(op, u_xen_mc, 1) )
                return -EFAULT;
@@ -580,6 +673,43 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u
 
                spin_unlock(&mc_notify_lock);
                break;
+
+       case XEN_MC_physcpuinfo:
+              if ( !IS_PRIV(v->domain) )
+                      return -EPERM;
+ 
+              mc_physcpuinfo = &op->u.mc_physcpuinfo;
+              nlcpu = num_online_cpus();
+ 
+              if (!guest_handle_is_null(mc_physcpuinfo->info)) {
+                      if (mc_physcpuinfo->ncpus <= 0)
+                              return -EINVAL;
+                      nlcpu = min(nlcpu, (int)mc_physcpuinfo->ncpus);
+                      log_cpus = xmalloc_array(xen_mc_logical_cpu_t, nlcpu);
+                      if (log_cpus == NULL)
+                              return -ENOMEM;
+ 
+                      if (on_each_cpu(do_mc_get_cpu_info, log_cpus,
+                          1, 1) != 0) {
+                              xfree(log_cpus);
+                              return -EIO;
+                      }
+              }
+ 
+              mc_physcpuinfo->ncpus = nlcpu;
+ 
+              if (copy_to_guest(u_xen_mc, op, 1)) {
+                      if (log_cpus != NULL)
+                              xfree(log_cpus);
+                      return -EFAULT;
+              }
+ 
+              if (!guest_handle_is_null(mc_physcpuinfo->info)) {
+                      if (copy_to_guest(mc_physcpuinfo->info,
+                          log_cpus, nlcpu))
+                              ret = -EFAULT;
+                      xfree(log_cpus);
+              }
        }
 
        return ret;
diff -r 09ea7eea8122 -r 4ac8bc60c000 xen/arch/x86/cpu/mcheck/mce.h
--- a/xen/arch/x86/cpu/mcheck/mce.h     Tue Feb 10 05:47:00 2009 +0000
+++ b/xen/arch/x86/cpu/mcheck/mce.h     Tue Feb 10 05:51:00 2009 +0000
@@ -34,4 +34,5 @@ int x86_mcinfo_add(struct mc_info *mi, v
 int x86_mcinfo_add(struct mc_info *mi, void *mcinfo);
 void x86_mcinfo_dump(struct mc_info *mi);
 void mc_panic(char *s);
-
+void x86_mc_get_cpu_info(unsigned, uint32_t *, uint16_t *, uint16_t *,
+                        uint32_t *, uint32_t *, uint32_t *, uint32_t *);
diff -r 09ea7eea8122 -r 4ac8bc60c000 xen/arch/x86/cpu/mcheck/mce_intel.c
--- a/xen/arch/x86/cpu/mcheck/mce_intel.c       Tue Feb 10 05:47:00 2009 +0000
+++ b/xen/arch/x86/cpu/mcheck/mce_intel.c       Tue Feb 10 05:51:00 2009 +0000
@@ -182,11 +182,9 @@ static struct mc_info *machine_check_pol
         mcg.mc_flags = MC_FLAG_POLLED;
     else if (calltype == MC_FLAG_CMCI)
         mcg.mc_flags = MC_FLAG_CMCI;
-    mcg.mc_socketid = phys_proc_id[cpu];
-    mcg.mc_coreid = cpu_core_id[cpu];
-    mcg.mc_apicid = cpu_physical_id(cpu);
-    mcg.mc_core_threadid =
-        mcg.mc_apicid & ( 1 << (cpu_data[cpu].x86_num_siblings - 1)); 
+    x86_mc_get_cpu_info(
+        cpu, &mcg.mc_socketid, &mcg.mc_coreid,
+        &mcg.mc_core_threadid, &mcg.mc_apicid, NULL, NULL, NULL);
     rdmsrl(MSR_IA32_MCG_STATUS, mcg.mc_gstatus);
 
     for ( i = 0; i < nr_mce_banks; i++ ) {
diff -r 09ea7eea8122 -r 4ac8bc60c000 xen/include/public/arch-x86/xen-mca.h
--- a/xen/include/public/arch-x86/xen-mca.h     Tue Feb 10 05:47:00 2009 +0000
+++ b/xen/include/public/arch-x86/xen-mca.h     Tue Feb 10 05:51:00 2009 +0000
@@ -56,7 +56,7 @@
 /* Hypercall */
 #define __HYPERVISOR_mca __HYPERVISOR_arch_0
 
-#define XEN_MCA_INTERFACE_VERSION 0x03000001
+#define XEN_MCA_INTERFACE_VERSION 0x03000002
 
 /* IN: Dom0 calls hypercall from MC event handler. */
 #define XEN_MC_CORRECTABLE  0x0
@@ -118,7 +118,7 @@ struct mcinfo_global {
     uint16_t mc_domid;
     uint32_t mc_socketid; /* physical socket of the physical core */
     uint16_t mc_coreid; /* physical impacted core */
-    uint8_t  mc_apicid;
+    uint32_t mc_apicid;
     uint16_t mc_core_threadid; /* core thread of physical core */
     uint16_t mc_vcpuid; /* virtual cpu scheduled for mc_domid */
     uint64_t mc_gstatus; /* global status */
@@ -175,6 +175,41 @@ struct mc_info {
 };
 typedef struct mc_info mc_info_t;
 
+#define __MC_MSR_ARRAYSIZE 8
+#define __MC_NMSRS 1
+#define MC_NCAPS       7       /* 7 CPU feature flag words */
+#define MC_CAPS_STD_EDX        0       /* cpuid level 0x00000001 (%edx) */
+#define MC_CAPS_AMD_EDX        1       /* cpuid level 0x80000001 (%edx) */
+#define MC_CAPS_TM     2       /* cpuid level 0x80860001 (TransMeta) */
+#define MC_CAPS_LINUX  3       /* Linux-defined */
+#define MC_CAPS_STD_ECX        4       /* cpuid level 0x00000001 (%ecx) */
+#define MC_CAPS_VIA    5       /* cpuid level 0xc0000001 */
+#define MC_CAPS_AMD_ECX        6       /* cpuid level 0x80000001 (%ecx) */
+
+typedef struct mcinfo_logical_cpu {
+    uint32_t mc_cpunr;          
+    uint32_t mc_chipid; 
+    uint16_t mc_coreid;
+    uint16_t mc_threadid;
+    uint32_t mc_apicid;
+    uint32_t mc_clusterid;
+    uint32_t mc_ncores;
+    uint32_t mc_ncores_active;
+    uint32_t mc_nthreads;
+    int32_t mc_cpuid_level;
+    uint32_t mc_family;
+    uint32_t mc_vendor;
+    uint32_t mc_model;
+    uint32_t mc_step;
+    char mc_vendorid[16];
+    char mc_brandid[64];
+    uint32_t mc_cpu_caps[MC_NCAPS];
+    uint32_t mc_cache_size;
+    uint32_t mc_cache_alignment;
+    int32_t mc_nmsrvals;
+    struct mcinfo_msr mc_msrvalues[__MC_MSR_ARRAYSIZE];
+} xen_mc_logical_cpu_t;
+DEFINE_XEN_GUEST_HANDLE(xen_mc_logical_cpu_t);
 
 
 /* 
@@ -272,6 +307,14 @@ typedef struct xen_mc_notifydomain xen_m
 typedef struct xen_mc_notifydomain xen_mc_notifydomain_t;
 DEFINE_XEN_GUEST_HANDLE(xen_mc_notifydomain_t);
 
+#define XEN_MC_physcpuinfo 3
+struct xen_mc_physcpuinfo {
+       /* IN/OUT */
+       uint32_t ncpus;
+       uint32_t pad0;
+       /* OUT */
+       XEN_GUEST_HANDLE(xen_mc_logical_cpu_t) info;
+};
 
 struct xen_mc {
     uint32_t cmd;
@@ -279,6 +322,7 @@ struct xen_mc {
     union {
         struct xen_mc_fetch        mc_fetch;
         struct xen_mc_notifydomain mc_notifydomain;
+        struct xen_mc_physcpuinfo  mc_physcpuinfo;
         uint8_t pad[MCINFO_HYPERCALLSIZE];
     } u;
 };

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] x86: mce: Provide extended physical CPU info., Xen patchbot-unstable <=