vmm: Allow the user to set GUEST_FS/GS_BASE (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 8 Sep 2017 20:31:09 +0000 (16:31 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 14 Sep 2017 20:37:58 +0000 (16:37 -0400)
We'll need this for TLS for vthreads.  It's not particularly useful for
regular VMs.

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/arch/x86/process64.c
kern/arch/x86/ros/vmm.h
kern/arch/x86/trap64.h
kern/arch/x86/vmm/intel/vmx.c
tests/vmm/vmrunkernel.c
user/vmm/vthread.c

index 8cbe2e4..fa80cbf 100644 (file)
@@ -236,14 +236,6 @@ void proc_pop_ctx(struct user_context *ctx)
        }
 }
 
-/* Helper: if *addr isn't a canonical user address, poison it.  Use this when
- * you need a canonical address (like MSR_FS_BASE) */
-static void enforce_user_canon(uintptr_t *addr)
-{
-       if (*addr >> 47 != 0)
-               *addr = 0x5a5a5a5a;
-}
-
 void proc_init_ctx(struct user_context *ctx, uint32_t vcoreid, uintptr_t entryp,
                    uintptr_t stack_top, uintptr_t tls_desc)
 {
index 3fa7cf2..9812f89 100644 (file)
@@ -15,6 +15,8 @@ struct vmm_gpcore_init {
        void                                    *vapic_addr;
        void                                    *apic_addr;
        void                                    *user_data;
+       uintptr_t                               fsbase;
+       uintptr_t                               gsbase;
 };
 
 /* Intel VM Trap Injection Fields */
index b3165d5..8e86c41 100644 (file)
 
 #include <arch/fsgsbase.h>
 
+/* Helper: if *addr isn't a canonical user address, poison it.  Use this when
+ * you need a canonical address (like MSR_FS_BASE) */
+static inline void enforce_user_canon(uintptr_t *addr)
+{
+       if (*addr >> 47 != 0)
+               *addr = 0x5a5a5a5a;
+}
+
 static inline bool in_kernel(struct hw_trapframe *hw_tf)
 {
        return (hw_tf->tf_cs & ~3) == GD_KT;
index e3e4747..c065f60 100644 (file)
@@ -835,7 +835,6 @@ static void vmcs_set_pgaddr(struct proc *p, void *u_addr,
 static void vmx_setup_initial_guest_state(struct proc *p,
                                           struct vmm_gpcore_init *gpci)
 {
-       unsigned long tmpl;
        unsigned long cr4 = X86_CR4_PAE | X86_CR4_VMXE | X86_CR4_OSXMMEXCPT |
                X86_CR4_PGE | X86_CR4_OSFXSR;
        uint32_t protected_mode = X86_CR0_PG | X86_CR0_PE;
@@ -875,10 +874,11 @@ static void vmx_setup_initial_guest_state(struct proc *p,
        vmcs_writel(GUEST_CS_BASE, 0);
        vmcs_writel(GUEST_DS_BASE, 0);
        vmcs_writel(GUEST_ES_BASE, 0);
-       vmcs_writel(GUEST_GS_BASE, 0);
+       enforce_user_canon(&gpci->fsbase);
+       vmcs_writel(GUEST_FS_BASE, gpci->fsbase);
+       enforce_user_canon(&gpci->gsbase);
+       vmcs_writel(GUEST_GS_BASE, gpci->gsbase);
        vmcs_writel(GUEST_SS_BASE, 0);
-       tmpl = read_fsbase();
-       vmcs_writel(GUEST_FS_BASE, tmpl);
 
        /* guest segment access rights */
        vmcs_writel(GUEST_CS_AR_BYTES, 0xA09B);
index d379645..8e374b8 100644 (file)
@@ -278,6 +278,8 @@ void alloc_intr_pages(void)
                gpcis[i].posted_irq_desc = pir + (PGSIZE * i);
                gpcis[i].vapic_addr = pages + (PGSIZE * i);
                gpcis[i].apic_addr = a_page;
+               gpcis[i].fsbase = 0;
+               gpcis[i].gsbase = 0;
 
                /* Set APIC ID. */
                ((uint32_t *)gpcis[i].vapic_addr)[0x20/4] = i;
index d6c33dc..8111679 100644 (file)
@@ -50,6 +50,10 @@ static int vmsetup(struct virtual_machine *vm, int flags)
                vm->gpcis[i].posted_irq_desc = &p[0];
                vm->gpcis[i].vapic_addr = &p[4096];
                vm->gpcis[i].apic_addr = &p[8192];
+               /* TODO: once we are making these GPCs at the same time as vthreads, we
+                * should set fsbase == the TLS desc of the vthread (if any). */
+               vm->gpcis[i].fsbase = 0;
+               vm->gpcis[i].gsbase = 0;
        }
 
        /* Set up default page mappings. */