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