1 #include "x86-emulate.h"
2
3 #include <sys/mman.h>
4
5 #define cpu_has_amd_erratum(nr) 0
6 #define mark_regs_dirty(r) ((void)(r))
7 #define cpu_has_mpx false
8 #define read_bndcfgu() 0
9 #define xstate_set_init(what)
10
11 /* For generic assembly code: use macros to define operation/operand sizes. */
12 #ifdef __i386__
13 # define r(name) e ## name
14 # define __OS "l" /* Operation Suffix */
15 # define __OP "e" /* Operand Prefix */
16 #else
17 # define r(name) r ## name
18 # define __OS "q" /* Operation Suffix */
19 # define __OP "r" /* Operand Prefix */
20 #endif
21
22 #define get_stub(stb) ({ \
23 assert(!(stb).addr); \
24 (void *)((stb).addr = (uintptr_t)(stb).buf); \
25 })
26 #define put_stub(stb) ((stb).addr = 0)
27
28 uint32_t mxcsr_mask = 0x0000ffbf;
29
emul_test_init(void)30 bool emul_test_init(void)
31 {
32 unsigned long sp;
33
34 if ( cpu_has_fxsr )
35 {
36 static union __attribute__((__aligned__(16))) {
37 char x[464];
38 struct {
39 uint32_t other[6];
40 uint32_t mxcsr;
41 uint32_t mxcsr_mask;
42 /* ... */
43 };
44 } fxs;
45
46 asm ( "fxsave %0" : "=m" (fxs) );
47 if ( fxs.mxcsr_mask )
48 mxcsr_mask = fxs.mxcsr_mask;
49 }
50
51 /*
52 * Mark the entire stack executable so that the stub executions
53 * don't fault
54 */
55 #ifdef __x86_64__
56 asm ("movq %%rsp, %0" : "=g" (sp));
57 #else
58 asm ("movl %%esp, %0" : "=g" (sp));
59 #endif
60
61 return mprotect((void *)(sp & -0x1000L) - (MMAP_SZ - 0x1000),
62 MMAP_SZ, PROT_READ|PROT_WRITE|PROT_EXEC) == 0;
63 }
64
emul_test_cpuid(uint32_t leaf,uint32_t subleaf,struct cpuid_leaf * res,struct x86_emulate_ctxt * ctxt)65 int emul_test_cpuid(
66 uint32_t leaf,
67 uint32_t subleaf,
68 struct cpuid_leaf *res,
69 struct x86_emulate_ctxt *ctxt)
70 {
71 asm ("cpuid"
72 : "=a" (res->a), "=b" (res->b), "=c" (res->c), "=d" (res->d)
73 : "a" (leaf), "c" (subleaf));
74
75 /*
76 * The emulator doesn't itself use MOVBE, so we can always run the
77 * respective tests.
78 */
79 if ( leaf == 1 )
80 res->c |= 1U << 22;
81
82 /*
83 * The emulator doesn't itself use ADCX/ADOX/RDPID, so we can always run
84 * the respective tests.
85 */
86 if ( leaf == 7 && subleaf == 0 )
87 {
88 res->b |= 1U << 19;
89 res->c |= 1U << 22;
90 }
91
92 /*
93 * The emulator doesn't itself use CLZERO, so we can always run the
94 * respective test(s).
95 */
96 if ( leaf == 0x80000008 )
97 res->b |= 1U << 0;
98
99 return X86EMUL_OKAY;
100 }
101
emul_test_read_cr(unsigned int reg,unsigned long * val,struct x86_emulate_ctxt * ctxt)102 int emul_test_read_cr(
103 unsigned int reg,
104 unsigned long *val,
105 struct x86_emulate_ctxt *ctxt)
106 {
107 /* Fake just enough state for the emulator's _get_fpu() to be happy. */
108 switch ( reg )
109 {
110 case 0:
111 *val = 0x00000001; /* PE */
112 return X86EMUL_OKAY;
113
114 case 4:
115 /* OSFXSR, OSXMMEXCPT, and maybe OSXSAVE */
116 *val = 0x00000600 | (cpu_has_xsave ? 0x00040000 : 0);
117 return X86EMUL_OKAY;
118 }
119
120 return X86EMUL_UNHANDLEABLE;
121 }
122
emul_test_get_fpu(void (* exception_callback)(void *,struct cpu_user_regs *),void * exception_callback_arg,enum x86_emulate_fpu_type type,struct x86_emulate_ctxt * ctxt)123 int emul_test_get_fpu(
124 void (*exception_callback)(void *, struct cpu_user_regs *),
125 void *exception_callback_arg,
126 enum x86_emulate_fpu_type type,
127 struct x86_emulate_ctxt *ctxt)
128 {
129 switch ( type )
130 {
131 case X86EMUL_FPU_fpu:
132 break;
133 case X86EMUL_FPU_mmx:
134 if ( cpu_has_mmx )
135 break;
136 case X86EMUL_FPU_xmm:
137 if ( cpu_has_sse )
138 break;
139 case X86EMUL_FPU_ymm:
140 if ( cpu_has_avx )
141 break;
142 default:
143 return X86EMUL_UNHANDLEABLE;
144 }
145 return X86EMUL_OKAY;
146 }
147
emul_test_put_fpu(struct x86_emulate_ctxt * ctxt,enum x86_emulate_fpu_type backout,const struct x86_emul_fpu_aux * aux)148 void emul_test_put_fpu(
149 struct x86_emulate_ctxt *ctxt,
150 enum x86_emulate_fpu_type backout,
151 const struct x86_emul_fpu_aux *aux)
152 {
153 /* TBD */
154 }
155
156 #include "x86_emulate/x86_emulate.c"
157