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