/src/xen/tools/tests/x86_emulator/x86-emulate.h
Line | Count | Source |
1 | | #ifndef X86_EMULATE_H |
2 | | #define X86_EMULATE_H |
3 | | |
4 | | #include <assert.h> |
5 | | #include <stdbool.h> |
6 | | #include <stddef.h> |
7 | | #include <stdint.h> |
8 | | #include <stdlib.h> |
9 | | /* |
10 | | * Use of sse registers must be disabled prior to the definition of |
11 | | * always_inline functions that would use them (memcpy, memset, etc), |
12 | | * so do this as early as possible, aiming to be before any always_inline |
13 | | * functions that are used are declared. |
14 | | * Unfortunately, this cannot be done prior to inclusion of <stdlib.h> |
15 | | * due to functions such as 'atof' that have SSE register return declared, |
16 | | * so do so here, immediately after that. |
17 | | */ |
18 | | #if __GNUC__ >= 6 |
19 | | # pragma GCC target("no-sse") |
20 | | #endif |
21 | | /* |
22 | | * Attempt detection of unwanted prior inclusion of some headers known to use |
23 | | * always_inline with SSE registers in some library / compiler / optimization |
24 | | * combinations. |
25 | | */ |
26 | | #ifdef _STRING_H |
27 | | # error "Must not include <string.h> before x86-emulate.h" |
28 | | #endif |
29 | | #include <string.h> |
30 | | |
31 | | /* EOF is a standard macro defined in <stdio.h> so use it for detection */ |
32 | | #ifdef EOF |
33 | | # error "Must not include <stdio.h> before x86-emulate.h" |
34 | | #endif |
35 | | #include <stdio.h> |
36 | | |
37 | | #include <xen/xen.h> |
38 | | |
39 | | #include <xen/asm/msr-index.h> |
40 | | #include <xen/asm/x86-defns.h> |
41 | | #include <xen/asm/x86-event.h> |
42 | | #include <xen/asm/x86-types.h> |
43 | | #include <xen/asm/x86-vendors.h> |
44 | | |
45 | | #include <xen-tools/common-macros.h> |
46 | | |
47 | 3.81M | #define ASSERT assert |
48 | 0 | #define ASSERT_UNREACHABLE() assert(!__LINE__) |
49 | | |
50 | | #define DEFINE_PER_CPU(type, var) type per_cpu_##var |
51 | 0 | #define this_cpu(var) per_cpu_##var |
52 | | |
53 | | #define __init |
54 | | #define __maybe_unused __attribute__((__unused__)) |
55 | | |
56 | 93.2k | #define likely(x) __builtin_expect(!!(x), true) |
57 | 4.32M | #define unlikely(x) __builtin_expect(!!(x), false) |
58 | | |
59 | | #define cf_check /* No Control Flow Integriy checking */ |
60 | | |
61 | | /* |
62 | | * Pseudo keyword 'fallthrough' to make explicit the fallthrough intention at |
63 | | * the end of a case statement block. |
64 | | */ |
65 | | #if !defined(__clang__) && (__GNUC__ >= 7) |
66 | | # define fallthrough __attribute__((__fallthrough__)) |
67 | | #else |
68 | 4.68k | # define fallthrough do {} while (0) /* fallthrough */ |
69 | | #endif |
70 | | |
71 | | #ifdef __GCC_ASM_FLAG_OUTPUTS__ |
72 | | # define ASM_FLAG_OUT(yes, no) yes |
73 | | #else |
74 | | # define ASM_FLAG_OUT(yes, no) no |
75 | | #endif |
76 | | |
77 | | #define hweight32 __builtin_popcount |
78 | 0 | #define hweight64 __builtin_popcountll |
79 | | |
80 | 74 | #define is_canonical_address(x) (((int64_t)(x) >> 47) == ((int64_t)(x) >> 63)) |
81 | | |
82 | | static inline void *place_ret(void *ptr) |
83 | 188k | { |
84 | 188k | *(uint8_t *)ptr = 0xc3; |
85 | 188k | return ptr + 1; |
86 | 188k | } Unexecuted instantiation: fuzz-emul.c:place_ret Line | Count | Source | 83 | 118k | { | 84 | 118k | *(uint8_t *)ptr = 0xc3; | 85 | 118k | return ptr + 1; | 86 | 118k | } |
Unexecuted instantiation: 0f01.c:place_ret Unexecuted instantiation: 0fae.c:place_ret Unexecuted instantiation: 0fc7.c:place_ret Unexecuted instantiation: decode.c:place_ret Line | Count | Source | 83 | 70.1k | { | 84 | 70.1k | *(uint8_t *)ptr = 0xc3; | 85 | 70.1k | return ptr + 1; | 86 | 70.1k | } |
Unexecuted instantiation: wrappers.c:place_ret |
87 | | |
88 | | extern uint32_t mxcsr_mask; |
89 | | extern struct cpu_policy cpu_policy; |
90 | | |
91 | 4 | #define MMAP_SZ 16384 |
92 | | bool emul_test_init(void); |
93 | | |
94 | | /* Must save and restore FPU state between any call into libc. */ |
95 | | void emul_save_fpu_state(void); |
96 | | void emul_restore_fpu_state(void); |
97 | | |
98 | | struct x86_fxsr *get_fpu_save_area(void); |
99 | | |
100 | | /* |
101 | | * In order to reasonably use the above, wrap library calls we use and which we |
102 | | * think might access any of the FPU state into wrappers saving/restoring state |
103 | | * around the actual function. |
104 | | */ |
105 | | #ifndef WRAP |
106 | | # define WRAP(x) typeof(x) __wrap_ ## x |
107 | | #endif |
108 | | |
109 | | WRAP(fwrite); |
110 | | WRAP(memcmp); |
111 | | WRAP(memcpy); |
112 | | WRAP(memset); |
113 | | WRAP(printf); |
114 | | WRAP(putchar); |
115 | | WRAP(puts); |
116 | | WRAP(snprintf); |
117 | | WRAP(strstr); |
118 | | WRAP(vprintf); |
119 | | WRAP(vsnprintf); |
120 | | |
121 | | #undef WRAP |
122 | | |
123 | | #include "x86_emulate/x86_emulate.h" |
124 | | |
125 | | void evex_disp8_test(void *instr, struct x86_emulate_ctxt *ctxt, |
126 | | const struct x86_emulate_ops *ops); |
127 | | void predicates_test(void *instr, struct x86_emulate_ctxt *ctxt, |
128 | | int (*fetch)(unsigned long offset, |
129 | | void *p_data, |
130 | | unsigned int bytes, |
131 | | struct x86_emulate_ctxt *ctxt)); |
132 | | |
133 | | static inline uint64_t xgetbv(uint32_t xcr) |
134 | 46.6k | { |
135 | 46.6k | uint32_t lo, hi; |
136 | | |
137 | 46.6k | asm ( ".byte 0x0f, 0x01, 0xd0" : "=a" (lo), "=d" (hi) : "c" (xcr) ); |
138 | | |
139 | 46.6k | return ((uint64_t)hi << 32) | lo; |
140 | 46.6k | } Unexecuted instantiation: fuzz-emul.c:xgetbv Line | Count | Source | 134 | 46.6k | { | 135 | 46.6k | uint32_t lo, hi; | 136 | | | 137 | 46.6k | asm ( ".byte 0x0f, 0x01, 0xd0" : "=a" (lo), "=d" (hi) : "c" (xcr) ); | 138 | | | 139 | 46.6k | return ((uint64_t)hi << 32) | lo; | 140 | 46.6k | } |
Unexecuted instantiation: 0f01.c:xgetbv Unexecuted instantiation: 0fae.c:xgetbv Unexecuted instantiation: 0fc7.c:xgetbv Unexecuted instantiation: decode.c:xgetbv Unexecuted instantiation: fpu.c:xgetbv Unexecuted instantiation: wrappers.c:xgetbv |
141 | | |
142 | | /* Intentionally checking OSXSAVE here. */ |
143 | 93.3k | #define cpu_has_xsave (cpu_policy.basic.raw[1].c & (1u << 27)) |
144 | | |
145 | | static inline bool xcr0_mask(uint64_t mask) |
146 | 46.6k | { |
147 | 46.6k | return cpu_has_xsave && ((xgetbv(0) & mask) == mask); |
148 | 46.6k | } Unexecuted instantiation: fuzz-emul.c:xcr0_mask Line | Count | Source | 146 | 46.6k | { | 147 | 46.6k | return cpu_has_xsave && ((xgetbv(0) & mask) == mask); | 148 | 46.6k | } |
Unexecuted instantiation: 0f01.c:xcr0_mask Unexecuted instantiation: 0fae.c:xcr0_mask Unexecuted instantiation: 0fc7.c:xcr0_mask Unexecuted instantiation: decode.c:xcr0_mask Unexecuted instantiation: fpu.c:xcr0_mask Unexecuted instantiation: wrappers.c:xcr0_mask |
149 | | |
150 | | unsigned int rdpkru(void); |
151 | | void wrpkru(unsigned int val); |
152 | | |
153 | | #define cache_line_size() (cpu_policy.basic.clflush_size * 8) |
154 | | #define cpu_has_fpu cpu_policy.basic.fpu |
155 | 20.1k | #define cpu_has_mmx cpu_policy.basic.mmx |
156 | | #define cpu_has_fxsr cpu_policy.basic.fxsr |
157 | 49.6k | #define cpu_has_sse cpu_policy.basic.sse |
158 | | #define cpu_has_sse2 cpu_policy.basic.sse2 |
159 | | #define cpu_has_sse3 cpu_policy.basic.sse3 |
160 | | #define cpu_has_pclmulqdq cpu_policy.basic.pclmulqdq |
161 | | #define cpu_has_ssse3 cpu_policy.basic.ssse3 |
162 | | #define cpu_has_fma (cpu_policy.basic.fma && xcr0_mask(6)) |
163 | | #define cpu_has_sse4_1 cpu_policy.basic.sse4_1 |
164 | | #define cpu_has_sse4_2 cpu_policy.basic.sse4_2 |
165 | | #define cpu_has_popcnt cpu_policy.basic.popcnt |
166 | | #define cpu_has_aesni cpu_policy.basic.aesni |
167 | 45.7k | #define cpu_has_avx (cpu_policy.basic.avx && xcr0_mask(6)) |
168 | | #define cpu_has_f16c (cpu_policy.basic.f16c && xcr0_mask(6)) |
169 | | |
170 | | #define cpu_has_avx2 (cpu_policy.feat.avx2 && xcr0_mask(6)) |
171 | | #define cpu_has_bmi1 cpu_policy.feat.bmi1 |
172 | | #define cpu_has_bmi2 cpu_policy.feat.bmi2 |
173 | 0 | #define cpu_has_avx512f (cpu_policy.feat.avx512f && \ |
174 | 0 | xcr0_mask(0xe6)) |
175 | | #define cpu_has_avx512dq (cpu_policy.feat.avx512dq && \ |
176 | | xcr0_mask(0xe6)) |
177 | | #define cpu_has_avx512_ifma (cpu_policy.feat.avx512_ifma && \ |
178 | | xcr0_mask(0xe6)) |
179 | | #define cpu_has_avx512cd (cpu_policy.feat.avx512cd && \ |
180 | | xcr0_mask(0xe6)) |
181 | | #define cpu_has_sha cpu_policy.feat.sha |
182 | 0 | #define cpu_has_avx512bw (cpu_policy.feat.avx512bw && \ |
183 | 0 | xcr0_mask(0xe6)) |
184 | | #define cpu_has_avx512vl (cpu_policy.feat.avx512vl && \ |
185 | | xcr0_mask(0xe6)) |
186 | | #define cpu_has_avx512_vbmi (cpu_policy.feat.avx512_vbmi && \ |
187 | | xcr0_mask(0xe6)) |
188 | | #define cpu_has_avx512_vbmi2 (cpu_policy.feat.avx512_vbmi2 && \ |
189 | | xcr0_mask(0xe6)) |
190 | | #define cpu_has_gfni cpu_policy.feat.gfni |
191 | | #define cpu_has_vaes (cpu_policy.feat.vaes && xcr0_mask(6)) |
192 | | #define cpu_has_vpclmulqdq (cpu_policy.feat.vpclmulqdq && xcr0_mask(6)) |
193 | | #define cpu_has_avx512_vnni (cpu_policy.feat.avx512_vnni && \ |
194 | | xcr0_mask(0xe6)) |
195 | | #define cpu_has_avx512_bitalg (cpu_policy.feat.avx512_bitalg && \ |
196 | | xcr0_mask(0xe6)) |
197 | | #define cpu_has_avx512_vpopcntdq (cpu_policy.feat.avx512_vpopcntdq && \ |
198 | | xcr0_mask(0xe6)) |
199 | | #define cpu_has_movdiri cpu_policy.feat.movdiri |
200 | | #define cpu_has_movdir64b cpu_policy.feat.movdir64b |
201 | | #define cpu_has_avx512_vp2intersect (cpu_policy.feat.avx512_vp2intersect && \ |
202 | | xcr0_mask(0xe6)) |
203 | | #define cpu_has_serialize cpu_policy.feat.serialize |
204 | | #define cpu_has_avx512_fp16 (cpu_policy.feat.avx512_fp16 && \ |
205 | | xcr0_mask(0xe6)) |
206 | | #define cpu_has_sha512 (cpu_policy.feat.sha512 && xcr0_mask(6)) |
207 | | #define cpu_has_sm3 (cpu_policy.feat.sm3 && xcr0_mask(6)) |
208 | | #define cpu_has_sm4 (cpu_policy.feat.sm4 && xcr0_mask(6)) |
209 | | #define cpu_has_avx_vnni (cpu_policy.feat.avx_vnni && xcr0_mask(6)) |
210 | | #define cpu_has_avx512_bf16 (cpu_policy.feat.avx512_bf16 && \ |
211 | | xcr0_mask(0xe6)) |
212 | | #define cpu_has_cmpccxadd cpu_policy.feat.cmpccxadd |
213 | | #define cpu_has_avx_ifma (cpu_policy.feat.avx_ifma && xcr0_mask(6)) |
214 | | #define cpu_has_avx_vnni_int8 (cpu_policy.feat.avx_vnni_int8 && \ |
215 | | xcr0_mask(6)) |
216 | | #define cpu_has_avx_ne_convert (cpu_policy.feat.avx_ne_convert && \ |
217 | | xcr0_mask(6)) |
218 | | #define cpu_has_avx_vnni_int16 (cpu_policy.feat.avx_vnni_int16 && \ |
219 | | xcr0_mask(6)) |
220 | | |
221 | 1 | #define cpu_has_xgetbv1 (cpu_has_xsave && cpu_policy.xstate.xgetbv1) |
222 | | |
223 | | #define cpu_has_3dnow_ext cpu_policy.extd._3dnowext |
224 | | #define cpu_has_sse4a cpu_policy.extd.sse4a |
225 | | #define cpu_has_xop (cpu_policy.extd.xop && xcr0_mask(6)) |
226 | | #define cpu_has_fma4 (cpu_policy.extd.fma4 && xcr0_mask(6)) |
227 | | #define cpu_has_tbm cpu_policy.extd.tbm |
228 | | #define cpu_has_avx512_bmm (cpu_policy.extd.avx512_bmm && \ |
229 | | xcr0_mask(0xe6)) |
230 | | |
231 | | int emul_test_cpuid( |
232 | | uint32_t leaf, |
233 | | uint32_t subleaf, |
234 | | struct cpuid_leaf *res, |
235 | | struct x86_emulate_ctxt *ctxt); |
236 | | |
237 | | int emul_test_read_cr( |
238 | | unsigned int reg, |
239 | | unsigned long *val, |
240 | | struct x86_emulate_ctxt *ctxt); |
241 | | |
242 | | int emul_test_read_xcr( |
243 | | unsigned int reg, |
244 | | uint64_t *val, |
245 | | struct x86_emulate_ctxt *ctxt); |
246 | | |
247 | | int emul_test_get_fpu( |
248 | | enum x86_emulate_fpu_type type, |
249 | | struct x86_emulate_ctxt *ctxt); |
250 | | |
251 | | void emul_test_put_fpu( |
252 | | struct x86_emulate_ctxt *ctxt, |
253 | | enum x86_emulate_fpu_type backout, |
254 | | const struct x86_emul_fpu_aux *aux); |
255 | | |
256 | | #endif /* X86_EMULATE_H */ |