VMM: Set the host stacktop on every VMX entry
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 2 Dec 2016 19:18:51 +0000 (14:18 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 14 Dec 2016 00:43:24 +0000 (19:43 -0500)
We had been assuming that if you returned to the VM, that the kernel was
still on the same stack.  That's not true - the kernel could have blocked
the kthread that handled the vmexit.  (Despite my warnings to not block in
vmexit_dispatch(), it might be safe).

This popped up as a problem when implementing lazy VMCS unload.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/arch/x86/process64.c
kern/arch/x86/vmm/intel/vmx.c

index d122748..32b62c9 100644 (file)
@@ -120,6 +120,11 @@ static void __attribute__((noreturn)) proc_pop_vmtf(struct vm_trapframe *tf)
        vmcs_write(GUEST_CR3, tf->tf_cr3);
        vmcs_write(GUEST_RIP, tf->tf_rip);
        vmcs_write(GUEST_RFLAGS, tf->tf_rflags);
+       /* The host stacktop could have changed, even if we are still a partial
+        * context.  Consider a vmcall that blocks.  We'll restart the partial
+        * context, but be on a new stack.  set_stack_top() doesn't really know
+        * about the VMCS. */
+       vmcs_write(HOST_RSP, pcpui->stacktop);
        /* cr2 is not part of the VMCS state; we need to save/restore it manually */
        lcr2(tf->tf_cr2);
        vmcs_write(VM_ENTRY_INTR_INFO_FIELD, tf->tf_trap_inject);
index 17b5b39..90e9c1a 100644 (file)
@@ -767,7 +767,6 @@ static void __vmx_setup_pcpu(struct guest_pcore *gpc)
 
        vmcs_write(HOST_TR_BASE, (uintptr_t)pcpui->tss);
        vmcs_writel(HOST_GDTR_BASE, (uintptr_t)pcpui->gdt);
-       vmcs_write(HOST_RSP, pcpui->stacktop);
        vmcs_write(HOST_GS_BASE, (uintptr_t)pcpui);
        /* TODO: we might need to also set HOST_IA32_PERF_GLOBAL_CTRL.  Need to
         * think about how perf will work with VMs */