1 #include <assert.h>
2 #include <stdbool.h>
3 #include <stddef.h>
4 #include <stdint.h>
5 #include <stdlib.h>
6 #include <string.h>
7
8 #if __GNUC__ >= 6
9 #pragma GCC target("no-sse")
10 #endif
11
12 #include <xen/xen.h>
13
14 #include <asm/msr-index.h>
15 #include <asm/x86-defns.h>
16 #include <asm/x86-vendors.h>
17
18 #define BUG() abort()
19 #define ASSERT assert
20 #define ASSERT_UNREACHABLE() assert(!__LINE__)
21
22 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
23
24 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
25 /* Force a compilation error if condition is true */
26 #define BUILD_BUG_ON(cond) ({ _Static_assert(!(cond), "!(" #cond ")"); })
27 #define BUILD_BUG_ON_ZERO(cond) \
28 sizeof(struct { _Static_assert(!(cond), "!(" #cond ")"); })
29 #else
30 #define BUILD_BUG_ON_ZERO(cond) sizeof(struct { int:-!!(cond); })
31 #define BUILD_BUG_ON(cond) ((void)BUILD_BUG_ON_ZERO(cond))
32 #endif
33
34 #define MASK_EXTR(v, m) (((v) & (m)) / ((m) & -(m)))
35 #define MASK_INSR(v, m) (((v) * ((m) & -(m))) & (m))
36
37 #define __init
38 #define __maybe_unused __attribute__((__unused__))
39
40 #define likely(x) __builtin_expect(!!(x), true)
41 #define unlikely(x) __builtin_expect(!!(x), false)
42
43 #define container_of(ptr, type, member) ({ \
44 typeof(((type *)0)->member) *mptr__ = (ptr); \
45 (type *)((char *)mptr__ - offsetof(type, member)); \
46 })
47
48 #define is_canonical_address(x) (((int64_t)(x) >> 47) == ((int64_t)(x) >> 63))
49
50 extern uint32_t mxcsr_mask;
51
52 #define MMAP_SZ 16384
53 bool emul_test_init(void);
54
55 #include "x86_emulate/x86_emulate.h"
56
xgetbv(uint32_t xcr)57 static inline uint64_t xgetbv(uint32_t xcr)
58 {
59 uint32_t lo, hi;
60
61 asm ( ".byte 0x0f, 0x01, 0xd0" : "=a" (lo), "=d" (hi) : "c" (xcr) );
62
63 return ((uint64_t)hi << 32) | lo;
64 }
65
66 #define cache_line_size() ({ \
67 struct cpuid_leaf res; \
68 emul_test_cpuid(1, 0, &res, NULL); \
69 res.d & (1U << 19) ? (res.b >> 5) & 0x7f8 : 0; \
70 })
71
72 #define cpu_has_mmx ({ \
73 struct cpuid_leaf res; \
74 emul_test_cpuid(1, 0, &res, NULL); \
75 (res.d & (1U << 23)) != 0; \
76 })
77
78 #define cpu_has_fxsr ({ \
79 struct cpuid_leaf res; \
80 emul_test_cpuid(1, 0, &res, NULL); \
81 (res.d & (1U << 24)) != 0; \
82 })
83
84 #define cpu_has_sse ({ \
85 struct cpuid_leaf res; \
86 emul_test_cpuid(1, 0, &res, NULL); \
87 (res.d & (1U << 25)) != 0; \
88 })
89
90 #define cpu_has_sse2 ({ \
91 struct cpuid_leaf res; \
92 emul_test_cpuid(1, 0, &res, NULL); \
93 (res.d & (1U << 26)) != 0; \
94 })
95
96 #define cpu_has_sse3 ({ \
97 struct cpuid_leaf res; \
98 emul_test_cpuid(1, 0, &res, NULL); \
99 (res.c & (1U << 0)) != 0; \
100 })
101
102 #define cpu_has_sse4_1 ({ \
103 struct cpuid_leaf res; \
104 emul_test_cpuid(1, 0, &res, NULL); \
105 (res.c & (1U << 19)) != 0; \
106 })
107
108 #define cpu_has_sse4_2 ({ \
109 struct cpuid_leaf res; \
110 emul_test_cpuid(1, 0, &res, NULL); \
111 (res.c & (1U << 20)) != 0; \
112 })
113
114 #define cpu_has_popcnt ({ \
115 struct cpuid_leaf res; \
116 emul_test_cpuid(1, 0, &res, NULL); \
117 (res.c & (1U << 23)) != 0; \
118 })
119
120 #define cpu_has_xsave ({ \
121 struct cpuid_leaf res; \
122 emul_test_cpuid(1, 0, &res, NULL); \
123 /* Intentionally checking OSXSAVE here. */ \
124 (res.c & (1U << 27)) != 0; \
125 })
126
127 #define cpu_has_avx ({ \
128 struct cpuid_leaf res; \
129 emul_test_cpuid(1, 0, &res, NULL); \
130 if ( !(res.c & (1U << 27)) || ((xgetbv(0) & 6) != 6) ) \
131 res.c = 0; \
132 (res.c & (1U << 28)) != 0; \
133 })
134
135 #define cpu_has_avx2 ({ \
136 struct cpuid_leaf res; \
137 emul_test_cpuid(1, 0, &res, NULL); \
138 if ( !(res.c & (1U << 27)) || ((xgetbv(0) & 6) != 6) ) \
139 res.b = 0; \
140 else { \
141 emul_test_cpuid(7, 0, &res, NULL); \
142 } \
143 (res.b & (1U << 5)) != 0; \
144 })
145
146 #define cpu_has_bmi1 ({ \
147 struct cpuid_leaf res; \
148 emul_test_cpuid(7, 0, &res, NULL); \
149 (res.b & (1U << 3)) != 0; \
150 })
151
152 #define cpu_has_bmi2 ({ \
153 struct cpuid_leaf res; \
154 emul_test_cpuid(7, 0, &res, NULL); \
155 (res.b & (1U << 8)) != 0; \
156 })
157
158 #define cpu_has_sse4a ({ \
159 struct cpuid_leaf res; \
160 emul_test_cpuid(0x80000001, 0, &res, NULL); \
161 (res.c & (1U << 6)) != 0; \
162 })
163
164 #define cpu_has_tbm ({ \
165 struct cpuid_leaf res; \
166 emul_test_cpuid(0x80000001, 0, &res, NULL); \
167 (res.c & (1U << 21)) != 0; \
168 })
169
170 int emul_test_cpuid(
171 uint32_t leaf,
172 uint32_t subleaf,
173 struct cpuid_leaf *res,
174 struct x86_emulate_ctxt *ctxt);
175
176 int emul_test_read_cr(
177 unsigned int reg,
178 unsigned long *val,
179 struct x86_emulate_ctxt *ctxt);
180
181 int emul_test_get_fpu(
182 void (*exception_callback)(void *, struct cpu_user_regs *),
183 void *exception_callback_arg,
184 enum x86_emulate_fpu_type type,
185 struct x86_emulate_ctxt *ctxt);
186
187 void emul_test_put_fpu(
188 struct x86_emulate_ctxt *ctxt,
189 enum x86_emulate_fpu_type backout,
190 const struct x86_emul_fpu_aux *aux);
191