|
23 | 23 |
|
24 | 24 | #include <mach-o/dyld.h> |
25 | 25 |
|
| 26 | +static bool |
| 27 | +is_avx(int instlen, uint64_t rip) |
| 28 | +{ |
| 29 | + uint8_t op; |
| 30 | + if (copy_from_user(&op, rip, sizeof op)) |
| 31 | + return false; |
| 32 | + return op == 0xc4 || op == 0xc5; |
| 33 | +} |
| 34 | + |
26 | 35 | static bool |
27 | 36 | is_syscall(int instlen, uint64_t rip) |
28 | 37 | { |
@@ -131,7 +140,18 @@ main_loop(int return_on_sigret) |
131 | 140 | return; |
132 | 141 | } |
133 | 142 | continue; |
134 | | - } |
| 143 | + } else if (is_avx(instlen, rip)) { |
| 144 | + uint64_t xcr0; |
| 145 | + vmm_read_register(HV_X86_XCR0, &xcr0); |
| 146 | + if ((xcr0 & XCR0_AVX_STATE) == 0) { |
| 147 | + uint64_t eax; |
| 148 | + asm ("cpuid" : "=a" (eax) : "a" (0x0d), "c" (0)); |
| 149 | + if (eax & XCR0_AVX_STATE) { |
| 150 | + vmm_write_register(HV_X86_XCR0, xcr0 | XCR0_AVX_STATE); |
| 151 | + continue; |
| 152 | + } |
| 153 | + } |
| 154 | + } |
135 | 155 | /* FIXME */ |
136 | 156 | warnk("invalid opcode! (rip = %p): ", (void *) rip); |
137 | 157 | unsigned char inst[instlen]; |
@@ -310,6 +330,13 @@ init_regs() |
310 | 330 | { |
311 | 331 | /* set up cpu regs */ |
312 | 332 | vmm_write_register(HV_X86_RFLAGS, 0x2); |
| 333 | + uint64_t eax; |
| 334 | + asm ("cpuid" : "=a" (eax) : "a" (0x0d), "c" (0)); |
| 335 | + if (eax & XCR0_SSE_STATE) { |
| 336 | + uint64_t xcr0; |
| 337 | + vmm_read_register(HV_X86_XCR0, &xcr0); |
| 338 | + vmm_write_register(HV_X86_XCR0, xcr0 | XCR0_SSE_STATE); |
| 339 | + } |
313 | 340 | } |
314 | 341 |
|
315 | 342 | void |
|
0 commit comments