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-api

[Xen-API] [PATCH 1 of 9] XCP.PQ: Add a new hypercall and libxc wrapper t

To: xen-api@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-API] [PATCH 1 of 9] XCP.PQ: Add a new hypercall and libxc wrapper to get the CPUID feature leaves
From: Ian Campbell <ian.campbell@xxxxxxxxxx>
Date: Tue, 11 Jan 2011 10:55:49 +0000
Cc: gianni.tedesco@xxxxxxxxxx, zheng.li@xxxxxxxxxxxxx
Delivery-date: Tue, 11 Jan 2011 03:44:17 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <patchbomb.1294743348@xxxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-api-request@lists.xensource.com?subject=help>
List-id: Discussion of API issues surrounding Xen <xen-api.lists.xensource.com>
List-post: <mailto:xen-api@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-api>, <mailto:xen-api-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-api>, <mailto:xen-api-request@lists.xensource.com?subject=unsubscribe>
References: <patchbomb.1294743348@xxxxxxxxxxxxxxxxxxxxxx>
Sender: xen-api-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mercurial-patchbomb/1.5.2
# 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

<Prev in Thread] Current Thread [Next in Thread>