1 /*
2 * include/asm-i386/xstate.h
3 *
4 * x86 extended state (xsave/xrstor) related definitions
5 *
6 */
7
8 #ifndef __ASM_XSTATE_H
9 #define __ASM_XSTATE_H
10
11 #include <xen/sched.h>
12 #include <asm/cpufeature.h>
13 #include <asm/x86-defns.h>
14
15 #define FCW_DEFAULT 0x037f
16 #define FCW_RESET 0x0040
17 #define MXCSR_DEFAULT 0x1f80
18
19 extern uint32_t mxcsr_mask;
20
21 #define XSTATE_CPUID 0x0000000d
22
23 #define XCR_XFEATURE_ENABLED_MASK 0x00000000 /* index of XCR0 */
24
25 #define XSAVE_HDR_SIZE 64
26 #define XSAVE_SSE_OFFSET 160
27 #define XSTATE_YMM_SIZE 256
28 #define FXSAVE_SIZE 512
29 #define XSAVE_HDR_OFFSET FXSAVE_SIZE
30 #define XSTATE_AREA_MIN_SIZE (FXSAVE_SIZE + XSAVE_HDR_SIZE)
31
32 #define XSTATE_FP_SSE (X86_XCR0_FP | X86_XCR0_SSE)
33 #define XCNTXT_MASK (X86_XCR0_FP | X86_XCR0_SSE | X86_XCR0_YMM | \
34 X86_XCR0_OPMASK | X86_XCR0_ZMM | X86_XCR0_HI_ZMM | \
35 XSTATE_NONLAZY)
36
37 #define XSTATE_ALL (~(1ULL << 63))
38 #define XSTATE_NONLAZY (X86_XCR0_BNDREGS | X86_XCR0_BNDCSR | X86_XCR0_PKRU)
39 #define XSTATE_LAZY (XSTATE_ALL & ~XSTATE_NONLAZY)
40 #define XSTATE_XSAVES_ONLY 0
41 #define XSTATE_COMPACTION_ENABLED (1ULL << 63)
42
43 #define XSTATE_ALIGN64 (1U << 1)
44
45 extern u64 xfeature_mask;
46 extern u64 xstate_align;
47 extern unsigned int *xstate_offsets;
48 extern unsigned int *xstate_sizes;
49
50 /* extended state save area */
51 struct __attribute__((aligned (64))) xsave_struct
52 {
53 union __attribute__((aligned(16))) { /* FPU/MMX, SSE */
54 char x[512];
55 struct {
56 uint16_t fcw;
57 uint16_t fsw;
58 uint8_t ftw;
59 uint8_t rsvd1;
60 uint16_t fop;
61 union {
62 uint64_t addr;
63 struct {
64 uint32_t offs;
65 uint16_t sel;
66 uint16_t rsvd;
67 };
68 } fip, fdp;
69 uint32_t mxcsr;
70 uint32_t mxcsr_mask;
71 /* data registers follow here */
72 };
73 } fpu_sse;
74
75 struct xsave_hdr {
76 u64 xstate_bv;
77 u64 xcomp_bv;
78 u64 reserved[6];
79 } xsave_hdr; /* The 64-byte header */
80
81 char data[]; /* Variable layout states */
82 };
83
84 struct xstate_bndcsr {
85 uint64_t bndcfgu;
86 uint64_t bndstatus;
87 };
88
89 /* extended state operations */
90 bool __must_check set_xcr0(u64 xfeatures);
91 uint64_t get_xcr0(void);
92 void set_msr_xss(u64 xss);
93 uint64_t get_msr_xss(void);
94 uint64_t read_bndcfgu(void);
95 void xsave(struct vcpu *v, uint64_t mask);
96 void xrstor(struct vcpu *v, uint64_t mask);
97 void xstate_set_init(uint64_t mask);
98 bool xsave_enabled(const struct vcpu *v);
99 int __must_check validate_xstate(const struct domain *d,
100 uint64_t xcr0, uint64_t xcr0_accum,
101 const struct xsave_hdr *hdr);
102 int __must_check handle_xsetbv(u32 index, u64 new_bv);
103 void expand_xsave_states(struct vcpu *v, void *dest, unsigned int size);
104 void compress_xsave_states(struct vcpu *v, const void *src, unsigned int size);
105
106 /* extended state init and cleanup functions */
107 void xstate_free_save_area(struct vcpu *v);
108 int xstate_alloc_save_area(struct vcpu *v);
109 void xstate_init(struct cpuinfo_x86 *c);
110 unsigned int xstate_ctxt_size(u64 xcr0);
111
xgetbv(unsigned int index)112 static inline uint64_t xgetbv(unsigned int index)
113 {
114 uint32_t lo, hi;
115
116 ASSERT(index); /* get_xcr0() should be used instead. */
117 asm volatile ( ".byte 0x0f,0x01,0xd0" /* xgetbv */
118 : "=a" (lo), "=d" (hi) : "c" (index) );
119
120 return lo | ((uint64_t)hi << 32);
121 }
122
xstate_all(const struct vcpu * v)123 static inline bool xstate_all(const struct vcpu *v)
124 {
125 /*
126 * XSTATE_FP_SSE may be excluded, because the offsets of XSTATE_FP_SSE
127 * (in the legacy region of xsave area) are fixed, so saving
128 * XSTATE_FP_SSE will not cause overwriting problem with XSAVES/XSAVEC.
129 */
130 return (v->arch.xsave_area->xsave_hdr.xcomp_bv &
131 XSTATE_COMPACTION_ENABLED) &&
132 (v->arch.xcr0_accum & XSTATE_LAZY & ~XSTATE_FP_SSE);
133 }
134
135 static inline bool __nonnull(1)
xsave_area_compressed(const struct xsave_struct * xsave_area)136 xsave_area_compressed(const struct xsave_struct *xsave_area)
137 {
138 return xsave_area->xsave_hdr.xcomp_bv & XSTATE_COMPACTION_ENABLED;
139 }
140
141 #endif /* __ASM_XSTATE_H */
142