]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/xen.git/commitdiff
x86: record xsave features in c->x86_capabilities
authorAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 23 Sep 2015 09:15:05 +0000 (11:15 +0200)
committerJan Beulich <jbeulich@suse.com>
Wed, 23 Sep 2015 09:15:05 +0000 (11:15 +0200)
Convert existing cpu_has_x??? to being functions of boot_cpu_data
(matching the prevailing style), and mask out unsupported features.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/cpu/common.c
xen/arch/x86/traps.c
xen/arch/x86/xstate.c
xen/include/asm-x86/cpufeature.h
xen/include/asm-x86/xstate.h

index 35ef21b701453ac07f517462152930338e316ffd..0be06568edab676e8953b2e2e439c6d467249f7b 100644 (file)
@@ -311,7 +311,7 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
                clear_bit(X86_FEATURE_XSAVE, boot_cpu_data.x86_capability);
 
        if ( cpu_has_xsave )
-               xstate_init(c == &boot_cpu_data);
+               xstate_init(c);
 
        /*
         * The vendor-specific functions might have changed features.  Now
index 9f5a6c6f681eac42d7e1270eabde4e23e5f39e4b..07feb6d708b08b6e5229536ac711eff4fae99ead 100644 (file)
@@ -935,10 +935,7 @@ void pv_cpuid(struct cpu_user_regs *regs)
             goto unsupported;
         if ( regs->_ecx == 1 )
         {
-            a &= XSTATE_FEATURE_XSAVEOPT |
-                 XSTATE_FEATURE_XSAVEC |
-                 (cpu_has_xgetbv1 ? XSTATE_FEATURE_XGETBV1 : 0) |
-                 (cpu_has_xsaves ? XSTATE_FEATURE_XSAVES : 0);
+            a &= boot_cpu_data.x86_capability[X86_FEATURE_XSAVEOPT / 32];
             if ( !cpu_has_xsaves )
                 b = c = d = 0;
         }
index d5f5e3b566081128e79e6d44c5dc81277f63a2df..9ddff90433a77fdc93ff1782ee6165f456d6b3f5 100644 (file)
 #include <asm/xstate.h>
 #include <asm/asm_defns.h>
 
-static bool_t __read_mostly cpu_has_xsaveopt;
-static bool_t __read_mostly cpu_has_xsavec;
-bool_t __read_mostly cpu_has_xgetbv1;
-bool_t __read_mostly cpu_has_xsaves;
-
 /*
  * Maximum size (in byte) of the XSAVE/XRSTOR save area required by all
  * the supported and enabled features on the processor, including the
@@ -281,8 +276,9 @@ unsigned int xstate_ctxt_size(u64 xcr0)
 }
 
 /* Collect the information of processor's extended state */
-void xstate_init(bool_t bsp)
+void xstate_init(struct cpuinfo_x86 *c)
 {
+    bool_t bsp = c == &boot_cpu_data;
     u32 eax, ebx, ecx, edx;
     u64 feature_mask;
 
@@ -325,20 +321,14 @@ void xstate_init(bool_t bsp)
 
     /* Check extended XSAVE features. */
     cpuid_count(XSTATE_CPUID, 1, &eax, &ebx, &ecx, &edx);
-    if ( bsp )
-    {
-        cpu_has_xsaveopt = !!(eax & XSTATE_FEATURE_XSAVEOPT);
-        cpu_has_xsavec = !!(eax & XSTATE_FEATURE_XSAVEC);
-        /* XXX cpu_has_xgetbv1 = !!(eax & XSTATE_FEATURE_XGETBV1); */
-        /* XXX cpu_has_xsaves = !!(eax & XSTATE_FEATURE_XSAVES); */
-    }
-    else
-    {
-        BUG_ON(!cpu_has_xsaveopt != !(eax & XSTATE_FEATURE_XSAVEOPT));
-        BUG_ON(!cpu_has_xsavec != !(eax & XSTATE_FEATURE_XSAVEC));
-        /* XXX BUG_ON(!cpu_has_xgetbv1 != !(eax & XSTATE_FEATURE_XGETBV1)); */
-        /* XXX BUG_ON(!cpu_has_xsaves != !(eax & XSTATE_FEATURE_XSAVES)); */
-    }
+
+    /* Mask out features not currently understood by Xen. */
+    eax &= (cpufeat_mask(X86_FEATURE_XSAVEOPT) |
+            cpufeat_mask(X86_FEATURE_XSAVEC));
+
+    c->x86_capability[X86_FEATURE_XSAVEOPT / 32] = eax;
+
+    BUG_ON(eax != boot_cpu_data.x86_capability[X86_FEATURE_XSAVEOPT / 32]);
 }
 
 static bool_t valid_xcr0(u64 xcr0)
index 9a01563152c5e2a103ae1250babe62f55b13536e..6a94724bca2f41de66f9380c65d36bf39cdc977a 100644 (file)
 #define X86_FEATURE_3DNOWEXT   (1*32+30) /* AMD 3DNow! extensions */
 #define X86_FEATURE_3DNOW      (1*32+31) /* 3DNow! */
 
-/* *** Available for re-use ***, word 2 */
+/* Intel-defined CPU features, CPUID level 0x0000000D:1 (eax), word 2 */
+#define X86_FEATURE_XSAVEOPT   (2*32+ 0) /* XSAVEOPT instruction. */
+#define X86_FEATURE_XSAVEC     (2*32+ 1) /* XSAVEC/XRSTORC instructions. */
+#define X86_FEATURE_XGETBV1    (2*32+ 2) /* XGETBV with %ecx=1. */
+#define X86_FEATURE_XSAVES     (2*32+ 3) /* XSAVES/XRSTORS instructions. */
 
 /* Other features, Linux-defined mapping, word 3 */
 /* This range is used for feature bits which conflict or are synthesized */
 
 #define cpu_has_cx16            boot_cpu_has(X86_FEATURE_CX16)
 
+#define cpu_has_xsaveopt       boot_cpu_has(X86_FEATURE_XSAVEOPT)
+#define cpu_has_xsavec         boot_cpu_has(X86_FEATURE_XSAVEC)
+#define cpu_has_xgetbv1                boot_cpu_has(X86_FEATURE_XGETBV1)
+#define cpu_has_xsaves         boot_cpu_has(X86_FEATURE_XSAVES)
+
 enum _cache_type {
     CACHE_TYPE_NULL = 0,
     CACHE_TYPE_DATA = 1,
index 4c690db29ee73d242292b561f2cb7fe4e4f44302..f0d8f0bc58be2f59c364a702da842c21cfeb334a 100644 (file)
@@ -9,16 +9,13 @@
 #define __ASM_XSTATE_H
 
 #include <xen/types.h>
+#include <asm/cpufeature.h>
 
 #define FCW_DEFAULT               0x037f
 #define FCW_RESET                 0x0040
 #define MXCSR_DEFAULT             0x1f80
 
 #define XSTATE_CPUID              0x0000000d
-#define XSTATE_FEATURE_XSAVEOPT   (1 << 0)    /* sub-leaf 1, eax[bit 0] */
-#define XSTATE_FEATURE_XSAVEC     (1 << 1)    /* sub-leaf 1, eax[bit 1] */
-#define XSTATE_FEATURE_XGETBV1    (1 << 2)    /* sub-leaf 1, eax[bit 2] */
-#define XSTATE_FEATURE_XSAVES     (1 << 3)    /* sub-leaf 1, eax[bit 3] */
 
 #define XCR_XFEATURE_ENABLED_MASK 0x00000000  /* index of XCR0 */
 
@@ -43,7 +40,6 @@
 #define XSTATE_LAZY    (XSTATE_ALL & ~XSTATE_NONLAZY)
 
 extern u64 xfeature_mask;
-extern bool_t cpu_has_xsaves, cpu_has_xgetbv1;
 
 /* extended state save area */
 struct __packed __attribute__((aligned (64))) xsave_struct
@@ -91,7 +87,7 @@ int __must_check handle_xsetbv(u32 index, u64 new_bv);
 /* extended state init and cleanup functions */
 void xstate_free_save_area(struct vcpu *v);
 int xstate_alloc_save_area(struct vcpu *v);
-void xstate_init(bool_t bsp);
+void xstate_init(struct cpuinfo_x86 *c);
 unsigned int xstate_ctxt_size(u64 xcr0);
 
 #endif /* __ASM_XSTATE_H */