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
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;
}
#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
}
/* 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;
/* 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)
#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,
#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 */
#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
/* 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 */