x86/c_traps.c: add clobbers in 32-bit VMX restore
The inline assembly blocks for vmlaunch and vmresume in the 32-bit restore_vmx() function manually pop guest state into all general-purpose registers. Previously, these registers were not included in the inline assembly clobber list. If a VM entry fails, execution falls through to the vmlaunch_failed() C function. Because the compiler is unaware that the registers were overwritten, it may generate code for the failure handler that relies on destroyed state. Signed-off-by: Bill Nguyen <bill.nguyen@unsw.edu.au>
This commit is contained in:
parent
84d60b58a1
commit
7eac2ceab8
1 changed files with 9 additions and 10 deletions
|
|
@ -36,11 +36,12 @@ static void NORETURN restore_vmx(tcb_t *cur_thread, vcpu_t *vcpu)
|
|||
/* Do not support breakpoints in VMs, so just disable all breakpoints */
|
||||
loadAllDisabledBreakpointState(cur_thread);
|
||||
#endif
|
||||
word_t *guest_regs_ptr = vcpu->gp_registers;
|
||||
if (vcpu->launched) {
|
||||
/* attempt to do a vmresume */
|
||||
asm volatile(
|
||||
// Set our stack pointer to the top of the tcb so we can efficiently pop
|
||||
"movl %0, %%esp\n"
|
||||
"movl %[guest_regs], %%esp\n"
|
||||
"popl %%eax\n"
|
||||
"popl %%ebx\n"
|
||||
"popl %%ecx\n"
|
||||
|
|
@ -57,18 +58,17 @@ static void NORETURN restore_vmx(tcb_t *cur_thread, vcpu_t *vcpu)
|
|||
"leal kernel_stack_alloc + %c1, %%esp\n"
|
||||
#endif
|
||||
"call vmlaunch_failed\n"
|
||||
:
|
||||
: "r"(&vcpu->gp_registers[VCPU_EAX]),
|
||||
"i"(BIT(CONFIG_KERNEL_STACK_BITS) - sizeof(word_t))
|
||||
: [guest_regs] "+a"(guest_regs_ptr)
|
||||
: "i"(BIT(CONFIG_KERNEL_STACK_BITS) - sizeof(word_t))
|
||||
// Clobber memory so the compiler is forced to complete all stores
|
||||
// before running this assembler
|
||||
: "memory"
|
||||
: "ebx", "ecx", "edx", "esi", "edi", "ebp", "memory"
|
||||
);
|
||||
} else {
|
||||
/* attempt to do a vmlaunch */
|
||||
asm volatile(
|
||||
// Set our stack pointer to the top of the tcb so we can efficiently pop
|
||||
"movl %0, %%esp\n"
|
||||
"movl %[guest_regs], %%esp\n"
|
||||
"popl %%eax\n"
|
||||
"popl %%ebx\n"
|
||||
"popl %%ecx\n"
|
||||
|
|
@ -85,12 +85,11 @@ static void NORETURN restore_vmx(tcb_t *cur_thread, vcpu_t *vcpu)
|
|||
"leal kernel_stack_alloc + %c1, %%esp\n"
|
||||
#endif
|
||||
"call vmlaunch_failed\n"
|
||||
:
|
||||
: "r"(&vcpu->gp_registers[VCPU_EAX]),
|
||||
"i"(BIT(CONFIG_KERNEL_STACK_BITS) - sizeof(word_t))
|
||||
: [guest_regs] "+a"(guest_regs_ptr)
|
||||
: "i"(BIT(CONFIG_KERNEL_STACK_BITS) - sizeof(word_t))
|
||||
// Clobber memory so the compiler is forced to complete all stores
|
||||
// before running this assembler
|
||||
: "memory"
|
||||
: "ebx", "ecx", "edx", "esi", "edi", "ebp", "memory"
|
||||
);
|
||||
}
|
||||
UNREACHABLE();
|
||||
|
|
|
|||
Loading…
Reference in a new issue