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