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

[Xen-API] [PATCH 1 of 9] XCP.PQ: Add a new hypercall and libxc wrapper to get the CPUID feature leaves



# HG changeset patch
# User Ian Campbell <ian.campbell@xxxxxxxxxx>
# Date 1294742831 0
# Node ID 1d1ae9c19591075dd50f7fb566247adf7945b3b9
# Parent  9b5d121c8805b40a4338248c346303e1e18d0c4e
XCP.PQ: Add a new hypercall and libxc wrapper to get the CPUID feature leaves
as they were before and after the FlexMigrate/Extended Migration masks.

This is not the ideal way to do it - in particular I think probably
platform_ops is the wrong hypercall, and it definitely needs to
allocate a better cmd number before going upstream.

diff -r 9b5d121c8805 -r 1d1ae9c19591 tools/libxc/xc_misc.c
--- a/tools/libxc/xc_misc.c     Mon Jan 10 08:45:19 2011 +0000
+++ b/tools/libxc/xc_misc.c     Tue Jan 11 10:47:11 2011 +0000
@@ -323,6 +323,31 @@ int xc_getcpuinfo(xc_interface *xch, int
 }
 
 
+int xc_get_boot_cpufeatures(xc_interface *xch,
+                            uint32_t *base_ecx, uint32_t *base_edx,
+                            uint32_t *ext_ecx, uint32_t *ext_edx,
+                            uint32_t *masked_base_ecx, 
+                            uint32_t *masked_base_edx,
+                            uint32_t *masked_ext_ecx, 
+                            uint32_t *masked_ext_edx)
+{
+    xen_platform_op_t pm = {0};
+    int rc;
+
+    pm.cmd = XENPF_get_cpu_features;
+    rc = do_platform(xch, &pm);
+
+    *base_ecx = pm.u.cpu_features.base_ecx;
+    *base_edx = pm.u.cpu_features.base_edx;
+    *ext_ecx = pm.u.cpu_features.ext_ecx;
+    *ext_edx = pm.u.cpu_features.ext_edx;
+    *masked_base_ecx = pm.u.cpu_features.masked_base_ecx;
+    *masked_base_edx = pm.u.cpu_features.masked_base_edx;
+    *masked_ext_ecx = pm.u.cpu_features.masked_ext_ecx;
+    *masked_ext_edx = pm.u.cpu_features.masked_ext_edx;
+    return rc;
+}
+
 int xc_hvm_set_pci_intx_level(
     xc_interface *xch, domid_t dom,
     uint8_t domain, uint8_t bus, uint8_t device, uint8_t intx,
diff -r 9b5d121c8805 -r 1d1ae9c19591 tools/libxc/xc_private.h
--- a/tools/libxc/xc_private.h  Mon Jan 10 08:45:19 2011 +0000
+++ b/tools/libxc/xc_private.h  Tue Jan 11 10:47:11 2011 +0000
@@ -262,6 +262,27 @@ static inline int do_sysctl(xc_interface
 
 int do_memory_op(xc_interface *xch, int cmd, void *arg, size_t len);
 
+static inline int do_platform(xc_interface *xch, struct xen_platform_op *pm)
+{
+    int ret = -1;
+    DECLARE_HYPERCALL;
+    DECLARE_HYPERCALL_BOUNCE(pm, sizeof(*pm), XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
+
+    pm->interface_version = XENPF_INTERFACE_VERSION;
+
+    hypercall.op     = __HYPERVISOR_platform_op;
+    hypercall.arg[0] = HYPERCALL_BUFFER_AS_ARG(pm);
+    if ( (ret = do_xen_hypercall(xch, &hypercall)) < 0 )
+    {
+        if ( errno == EACCES )
+            DPRINTF("platform operation failed -- need to"
+                    " rebuild the user-space tool set?\n");
+    }
+
+    xc_hypercall_bounce_post(xch, pm);
+    return ret;
+}
+
 void *xc_map_foreign_ranges(xc_interface *xch, uint32_t dom,
                             size_t size, int prot, size_t chunksize,
                             privcmd_mmap_entry_t entries[], int nentries);
diff -r 9b5d121c8805 -r 1d1ae9c19591 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h     Mon Jan 10 08:45:19 2011 +0000
+++ b/tools/libxc/xenctrl.h     Tue Jan 11 10:47:11 2011 +0000
@@ -38,6 +38,7 @@
 #include <xen/domctl.h>
 #include <xen/physdev.h>
 #include <xen/sysctl.h>
+#include <xen/platform.h>
 #include <xen/version.h>
 #include <xen/event_channel.h>
 #include <xen/sched.h>
@@ -1801,4 +1802,15 @@ void xc_elf_set_logfile(xc_interface *xc
                         int verbose);
 /* Useful for callers who also use libelf. */
 
+
+/* Get the CPUID feature lists before and after any hardware masks 
+ * were applied.  Returns the ANDed aggregate of all online CPUs. */
+int xc_get_boot_cpufeatures(xc_interface *xc_handle, 
+                            uint32_t *base_ecx, uint32_t *base_edx,
+                            uint32_t *ext_ecx, uint32_t *ext_edx,
+                            uint32_t *masked_base_ecx, 
+                            uint32_t *masked_base_edx,
+                            uint32_t *masked_ext_ecx, 
+                            uint32_t *masked_ext_edx);
+
 #endif /* XENCTRL_H */
diff -r 9b5d121c8805 -r 1d1ae9c19591 xen/arch/x86/cpu/amd.c
--- a/xen/arch/x86/cpu/amd.c    Mon Jan 10 08:45:19 2011 +0000
+++ b/xen/arch/x86/cpu/amd.c    Tue Jan 11 10:47:11 2011 +0000
@@ -89,12 +89,16 @@ static inline int wrmsr_amd_safe(unsigne
  */
 static void __devinit set_cpuidmask(const struct cpuinfo_x86 *c)
 {
+       unsigned int eax, ebx;
        static unsigned int feat_ecx, feat_edx;
        static unsigned int extfeat_ecx, extfeat_edx;
        static enum { not_parsed, no_mask, set_mask } status;
 
+       cpuid(0x1, &eax, &ebx, &c->boot_base_ecx, &c->boot_base_edx);
+       cpuid(0x80000001, &eax, &ebx, &c->boot_ext_ecx, &c->boot_ext_edx);
+
        if (status == no_mask)
-               return;
+               goto out;
 
        if (status == set_mask)
                goto setmask;
@@ -109,7 +113,7 @@ static void __devinit set_cpuidmask(cons
                extfeat_ecx = opt_cpuid_mask_ext_ecx;
                extfeat_edx = opt_cpuid_mask_ext_edx;
        } else if (*opt_famrev == '\0') {
-               return;
+               goto out;
        } else if (!strcmp(opt_famrev, "fam_0f_rev_c")) {
                feat_ecx = AMD_FEATURES_K8_REV_C_ECX;
                feat_edx = AMD_FEATURES_K8_REV_C_EDX;
@@ -153,7 +157,7 @@ static void __devinit set_cpuidmask(cons
        } else {
                printk("Invalid processor string: %s\n", opt_famrev);
                printk("CPUID will not be masked\n");
-               return;
+               goto out;
        }
 
         /* Setting bits in the CPUID mask MSR that are not set in the
@@ -170,7 +174,7 @@ static void __devinit set_cpuidmask(cons
        printk("Writing CPUID extended feature mask ECX:EDX -> %08Xh:%08Xh\n", 
               extfeat_ecx, extfeat_edx);
 
- setmask:
+setmask:
        /* FIXME check if processor supports CPUID masking */
        /* AMD processors prior to family 10h required a 32-bit password */
        if (c->x86 >= 0x10) {
@@ -180,6 +184,10 @@ static void __devinit set_cpuidmask(cons
                wrmsr_amd(MSR_K8_FEATURE_MASK, feat_edx, feat_ecx);
                wrmsr_amd(MSR_K8_EXT_FEATURE_MASK, extfeat_edx, extfeat_ecx);
        }
+
+out:
+       cpuid(0x1, &eax, &ebx, &c->masked_base_ecx, &c->masked_base_edx);
+       cpuid(0x80000001, &eax, &ebx, &c->masked_ext_ecx, &c->masked_ext_edx);
 }
 
 /*
diff -r 9b5d121c8805 -r 1d1ae9c19591 xen/arch/x86/cpu/intel.c
--- a/xen/arch/x86/cpu/intel.c  Mon Jan 10 08:45:19 2011 +0000
+++ b/xen/arch/x86/cpu/intel.c  Tue Jan 11 10:47:11 2011 +0000
@@ -35,11 +35,15 @@ struct movsl_mask movsl_mask __read_most
  */
 static void __devinit set_cpuidmask(const struct cpuinfo_x86 *c)
 {
+    unsigned int eax, ebx;
        const char *extra = "";
 
+       cpuid(0x1, &eax, &ebx, &c->boot_base_ecx, &c->boot_base_edx);
+       cpuid(0x80000001, &eax, &ebx, &c->boot_ext_ecx, &c->boot_ext_edx);
+
        if (!~(opt_cpuid_mask_ecx & opt_cpuid_mask_edx &
               opt_cpuid_mask_ext_ecx & opt_cpuid_mask_ext_edx))
-               return;
+        goto out;
 
        /* Only family 6 supports this feature  */
        switch ((c->x86 == 6) * c->x86_model) {
@@ -78,6 +82,9 @@ static void __devinit set_cpuidmask(cons
 
        printk(XENLOG_ERR "Cannot set CPU feature mask on CPU#%d\n",
               smp_processor_id());
+out:
+    cpuid(0x1, &eax, &ebx, &c->masked_base_ecx, &c->masked_base_edx);
+    cpuid(0x80000001, &eax, &ebx, &c->masked_ext_ecx, &c->masked_ext_edx);
 }
 
 void __devinit early_intel_workaround(struct cpuinfo_x86 *c)
diff -r 9b5d121c8805 -r 1d1ae9c19591 xen/arch/x86/platform_hypercall.c
--- a/xen/arch/x86/platform_hypercall.c Mon Jan 10 08:45:19 2011 +0000
+++ b/xen/arch/x86/platform_hypercall.c Tue Jan 11 10:47:11 2011 +0000
@@ -492,6 +492,35 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
                       op->u.mem_add.epfn,
                       op->u.mem_add.pxm);
         break;
+
+    case XENPF_get_cpu_features:
+    {
+        uint32_t cpu;
+
+        op->u.cpu_features.base_ecx = 0xffffffff;
+        op->u.cpu_features.base_edx = 0xffffffff;
+        op->u.cpu_features.ext_ecx = 0xffffffff;
+        op->u.cpu_features.ext_edx = 0xffffffff;
+        op->u.cpu_features.masked_base_ecx = 0xffffffff;
+        op->u.cpu_features.masked_base_edx = 0xffffffff;
+        op->u.cpu_features.masked_ext_ecx = 0xffffffff;
+        op->u.cpu_features.masked_ext_edx = 0xffffffff;
+        for_each_online_cpu( cpu )
+        {
+            op->u.cpu_features.base_ecx &= cpu_data[cpu].boot_base_ecx;
+            op->u.cpu_features.base_edx &= cpu_data[cpu].boot_base_edx;
+            op->u.cpu_features.ext_ecx  &= cpu_data[cpu].boot_ext_ecx;
+            op->u.cpu_features.ext_edx  &= cpu_data[cpu].boot_ext_edx;
+            op->u.cpu_features.masked_base_ecx &= 
cpu_data[cpu].masked_base_ecx;
+            op->u.cpu_features.masked_base_edx &= 
cpu_data[cpu].masked_base_edx;
+            op->u.cpu_features.masked_ext_ecx  &= cpu_data[cpu].masked_ext_ecx;
+            op->u.cpu_features.masked_ext_edx  &= cpu_data[cpu].masked_ext_edx;
+        }
+
+        ret = copy_to_guest(u_xenpf_op, op, 1) ? -EFAULT : 0;
+    }
+    break;
+
     default:
         ret = -ENOSYS;
         break;
diff -r 9b5d121c8805 -r 1d1ae9c19591 xen/include/asm-x86/processor.h
--- a/xen/include/asm-x86/processor.h   Mon Jan 10 08:45:19 2011 +0000
+++ b/xen/include/asm-x86/processor.h   Tue Jan 11 10:47:11 2011 +0000
@@ -166,6 +166,10 @@ struct cpuinfo_x86 {
     __u8 x86_mask;
     int  cpuid_level;    /* Maximum supported CPUID level, -1=no CPUID */
     unsigned int x86_capability[NCAPINTS];
+    unsigned int boot_base_ecx, boot_base_edx;
+    unsigned int boot_ext_ecx, boot_ext_edx;
+    unsigned int masked_base_ecx, masked_base_edx;
+    unsigned int masked_ext_ecx, masked_ext_edx;
     char x86_vendor_id[16];
     char x86_model_id[64];
     int  x86_cache_size; /* in KB - valid for CPUS which support this call  */
diff -r 9b5d121c8805 -r 1d1ae9c19591 xen/include/public/platform.h
--- a/xen/include/public/platform.h     Mon Jan 10 08:45:19 2011 +0000
+++ b/xen/include/public/platform.h     Tue Jan 11 10:47:11 2011 +0000
@@ -355,6 +355,24 @@ struct xenpf_mem_hotadd
     uint32_t flags;
 };
 
+
+/* Get the CPUID feature lists before and after any hardware masks 
+ * were applied.   Returns the ANDed aggregate of all online CPUs. */
+#define XENPF_get_cpu_features  511
+struct xenpf_cpu_features {
+    uint32_t base_ecx;          /* CPUID leaf 0x00000001:ECX */
+    uint32_t base_edx;          /* CPUID leaf 0x00000001:EDX */
+    uint32_t ext_ecx;           /* CPUID leaf 0x80000001:ECX */
+    uint32_t ext_edx;           /* CPUID leaf 0x80000001:EDX */
+    uint32_t masked_base_ecx;   /* CPUID leaf 0x00000001:ECX */
+    uint32_t masked_base_edx;   /* CPUID leaf 0x00000001:EDX */
+    uint32_t masked_ext_ecx;    /* CPUID leaf 0x80000001:ECX */
+    uint32_t masked_ext_edx;    /* CPUID leaf 0x80000001:EDX */
+};
+typedef struct xenpf_cpu_features xenpf_cpu_features_t;
+DEFINE_XEN_GUEST_HANDLE(xenpf_cpu_features_t);
+
+
 struct xen_platform_op {
     uint32_t cmd;
     uint32_t interface_version; /* XENPF_INTERFACE_VERSION */
@@ -374,6 +392,7 @@ struct xen_platform_op {
         struct xenpf_cpu_ol            cpu_ol;
         struct xenpf_cpu_hotadd        cpu_add;
         struct xenpf_mem_hotadd        mem_add;
+        struct xenpf_cpu_features      cpu_features;
         uint8_t                        pad[128];
     } u;
 };

_______________________________________________
xen-api mailing list
xen-api@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/mailman/listinfo/xen-api


 


Rackspace

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