Skip to content
This repository was archived by the owner on Jun 9, 2020. It is now read-only.

Commit 305b046

Browse files
committed
Enable AVX instructions on demand
Enabling AVX instructions increases the context size, so it is enabled when used for the first time.
1 parent 4958daf commit 305b046

3 files changed

Lines changed: 32 additions & 2 deletions

File tree

include/vmm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
struct vcpu_snapshot {
1313
uint64_t vcpu_reg[NR_X86_REG_LIST];
1414
uint64_t vmcs[NR_VMCS_FIELD_MASKED];
15-
char fpu_states[512] __attribute__((aligned(16)));
15+
char fpu_states[2496] __attribute__((aligned(16)));
1616
};
1717

1818
struct vmm_snapshot {

include/x86/specialreg.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,6 @@
1717
#define MSR_TIME_STAMP_COUNTER 0x00000010
1818
#define MSR_KERNEL_GS_BASE 0xc0000102
1919
#define MSR_TSC_AUX 0xc0000103
20+
21+
#define XCR0_SSE_STATE 0x00000002
22+
#define XCR0_AVX_STATE 0x00000004

src/main.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@
2323

2424
#include <mach-o/dyld.h>
2525

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+
2635
static bool
2736
is_syscall(int instlen, uint64_t rip)
2837
{
@@ -131,7 +140,18 @@ main_loop(int return_on_sigret)
131140
return;
132141
}
133142
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+
}
135155
/* FIXME */
136156
warnk("invalid opcode! (rip = %p): ", (void *) rip);
137157
unsigned char inst[instlen];
@@ -310,6 +330,13 @@ init_regs()
310330
{
311331
/* set up cpu regs */
312332
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+
}
313340
}
314341

315342
void

0 commit comments

Comments
 (0)