[HVM] Move VMX VMCS initialisation to vcpu-initialisation time.
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Mon, 6 Nov 2006 13:13:04 +0000 (13:13 +0000)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Mon, 6 Nov 2006 13:13:04 +0000 (13:13 +0000)
Simplify context initialisation (e.g., no need for selectors to
be given dummy non-zero values).
Signed-off-by: Keir Fraser <keir@xensource.com>
tools/libxc/xc_hvm_build.c
xen/arch/x86/domain.c
xen/arch/x86/hvm/svm/svm.c
xen/arch/x86/hvm/svm/vmcb.c
xen/arch/x86/hvm/vmx/vmcs.c
xen/arch/x86/hvm/vmx/vmx.c
xen/include/asm-x86/hvm/support.h

index 8995c6092517d11297d1c95203fcbb611f2cf145..a030cccd52b55dc2751cecb30ce48172031e4266 100644 (file)
@@ -309,8 +309,8 @@ static int xc_hvm_build_internal(int xc_handle,
                                  unsigned long *store_mfn)
 {
     struct xen_domctl launch_domctl, domctl;
-    int rc, i;
-    vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt;
+    vcpu_guest_context_t ctxt;
+    int rc;
 
     if ( (image == NULL) || (image_size == 0) )
     {
@@ -318,12 +318,6 @@ static int xc_hvm_build_internal(int xc_handle,
         goto error_out;
     }
 
-    if ( lock_pages(&st_ctxt, sizeof(st_ctxt) ) )
-    {
-        PERROR("%s: ctxt mlock failed", __func__);
-        return 1;
-    }
-
     domctl.cmd = XEN_DOMCTL_getdomaininfo;
     domctl.domain = (domid_t)domid;
     if ( (xc_domctl(xc_handle, &domctl) < 0) ||
@@ -333,56 +327,31 @@ static int xc_hvm_build_internal(int xc_handle,
         goto error_out;
     }
 
-    memset(ctxt, 0, sizeof(*ctxt));
+    memset(&ctxt, 0, sizeof(ctxt));
 
     if ( setup_guest(xc_handle, domid, memsize, image, image_size,
-                     ctxt, domctl.u.getdomaininfo.shared_info_frame,
+                     &ctxt, domctl.u.getdomaininfo.shared_info_frame,
                      vcpus, pae, acpi, store_evtchn, store_mfn) < 0)
     {
         ERROR("Error constructing guest OS");
         goto error_out;
     }
 
-    /* FPU is set up to default initial state. */
-    memset(&ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt));
-
-    /* Virtual IDT is empty at start-of-day. */
-    for ( i = 0; i < 256; i++ )
+    if ( lock_pages(&ctxt, sizeof(ctxt) ) )
     {
-        ctxt->trap_ctxt[i].vector = i;
-        ctxt->trap_ctxt[i].cs     = FLAT_KERNEL_CS;
+        PERROR("%s: ctxt mlock failed", __func__);
+        goto error_out;
     }
 
-    /* No LDT. */
-    ctxt->ldt_ents = 0;
-
-    /* Use the default Xen-provided GDT. */
-    ctxt->gdt_ents = 0;
-
-    /* No debugging. */
-    memset(ctxt->debugreg, 0, sizeof(ctxt->debugreg));
-
-    /* No callback handlers. */
-#if defined(__i386__)
-    ctxt->event_callback_cs     = FLAT_KERNEL_CS;
-    ctxt->event_callback_eip    = 0;
-    ctxt->failsafe_callback_cs  = FLAT_KERNEL_CS;
-    ctxt->failsafe_callback_eip = 0;
-#elif defined(__x86_64__)
-    ctxt->event_callback_eip    = 0;
-    ctxt->failsafe_callback_eip = 0;
-    ctxt->syscall_callback_eip  = 0;
-#endif
-
     memset(&launch_domctl, 0, sizeof(launch_domctl));
-
     launch_domctl.domain = (domid_t)domid;
     launch_domctl.u.vcpucontext.vcpu   = 0;
-    set_xen_guest_handle(launch_domctl.u.vcpucontext.ctxt, ctxt);
-
+    set_xen_guest_handle(launch_domctl.u.vcpucontext.ctxt, &ctxt);
     launch_domctl.cmd = XEN_DOMCTL_setvcpucontext;
     rc = xc_domctl(xc_handle, &launch_domctl);
 
+    unlock_pages(&ctxt, sizeof(ctxt));
+
     return rc;
 
  error_out:
index a5f89e70ef4b7c979d851a4d212318c28a4e7553..0ee7361825bc7c072e6bc1c11d6faff40684eb2f 100644 (file)
@@ -311,7 +311,7 @@ int arch_set_info_guest(
         /* Ensure real hardware interrupts are enabled. */
         v->arch.guest_context.user_regs.eflags |= EF_IE;
     }
-    else if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
+    else
     {
         hvm_load_cpu_guest_regs(v, &v->arch.guest_context.user_regs);
     }
index ef354abb7e52167b4284d396c76637da78a5bb91..5ff04f79e562630a227fc0b661414e593f82a2d1 100644 (file)
@@ -530,30 +530,10 @@ static void svm_set_tsc_offset(struct vcpu *v, u64 offset)
 }
 
 
-/* SVM-specific intitialization code for VCPU application processors */
-static void svm_init_ap_context(struct vcpu_guest_context *ctxt, 
-                                int vcpuid, int trampoline_vector)
+static void svm_init_ap_context(
+    struct vcpu_guest_context *ctxt, int vcpuid, int trampoline_vector)
 {
-    int i;
-    struct vcpu *v, *bsp = current;
-    struct domain *d = bsp->domain;
-    cpu_user_regs_t *regs;;
-
-  
-    if ((v = d->vcpu[vcpuid]) == NULL)
-    {
-        printk("vcpuid %d is invalid!  good-bye.\n", vcpuid);
-        domain_crash_synchronous();
-    }
-    regs = &v->arch.guest_context.user_regs;
-
     memset(ctxt, 0, sizeof(*ctxt));
-    for (i = 0; i < 256; ++i)
-    {
-        ctxt->trap_ctxt[i].vector = i;
-        ctxt->trap_ctxt[i].cs = FLAT_KERNEL_CS;
-    }
-
 
     /*
      * We execute the trampoline code in real mode. The trampoline vector
@@ -691,7 +671,7 @@ static void svm_load_cpu_user_regs(struct vcpu *v, struct cpu_user_regs *regs)
     vmcb->rax      = regs->eax;
     vmcb->ss.sel   = regs->ss;
     vmcb->rsp      = regs->esp;   
-    vmcb->rflags   = regs->eflags;
+    vmcb->rflags   = regs->eflags | 2UL;
     vmcb->cs.sel   = regs->cs;
     vmcb->rip      = regs->eip;
     if (regs->eflags & EF_TF)
index 6c3dc7c7c1beaf47d69c313ce84ba75a00606742..d2fee7677ce65993c5b58794023f4ba96a165e7c 100644 (file)
@@ -160,7 +160,6 @@ static int construct_init_vmcb_guest(struct arch_svm_struct *arch_svm,
     unsigned long crn;
     segment_attributes_t attrib;
     unsigned long dr7;
-    unsigned long eflags;
     unsigned long shadow_cr;
     struct vmcb_struct *vmcb = arch_svm->vmcb;
 
@@ -254,10 +253,7 @@ static int construct_init_vmcb_guest(struct arch_svm_struct *arch_svm,
     vmcb->rsp = 0;
     vmcb->rip = regs->eip;
 
-    eflags = regs->eflags & ~HVM_EFLAGS_RESERVED_0; /* clear 0s */
-    eflags |= HVM_EFLAGS_RESERVED_1; /* set 1s */
-
-    vmcb->rflags = eflags;
+    vmcb->rflags = regs->eflags | 2UL; /* inc. reserved bit */
 
     __asm__ __volatile__ ("mov %%dr7, %0\n" : "=r" (dr7));
     vmcb->dr7 = dr7;
index 882220926b33925e03be3f8702b9ff3a7e40a250..240e479a272c2154c2c89a842b52c9a8f5ad1792 100644 (file)
@@ -233,10 +233,7 @@ void vmx_free_host_vmcs(struct vmcs_struct *vmcs)
     vmx_free_vmcs(vmcs);
 }
 
-#define GUEST_LAUNCH_DS         0x08
-#define GUEST_LAUNCH_CS         0x10
 #define GUEST_SEGMENT_LIMIT     0xffffffff
-#define HOST_SEGMENT_LIMIT      0xffffffff
 
 struct host_execution_env {
     /* selectors */
@@ -353,12 +350,14 @@ static void vmx_do_launch(struct vcpu *v)
     v->arch.schedule_tail = arch_vmx_do_resume;
 }
 
-static int construct_vmcs(struct vcpu *v, cpu_user_regs_t *regs)
+static int construct_vmcs(struct vcpu *v)
 {
     int error = 0;
-    unsigned long tmp, eflags;
+    unsigned long tmp;
     union vmcs_arbytes arbytes;
 
+    vmx_vmcs_enter(v);
+
     /* VMCS controls. */
     error |= __vmwrite(PIN_BASED_VM_EXEC_CONTROL, vmx_pin_based_exec_control);
     error |= __vmwrite(VM_EXIT_CONTROLS, vmx_vmexit_control);
@@ -405,14 +404,6 @@ static int construct_vmcs(struct vcpu *v, cpu_user_regs_t *regs)
 
     error |= __vmwrite(GUEST_ACTIVITY_STATE, 0);
 
-    /* Guest selectors. */
-    error |= __vmwrite(GUEST_ES_SELECTOR, GUEST_LAUNCH_DS);
-    error |= __vmwrite(GUEST_SS_SELECTOR, GUEST_LAUNCH_DS);
-    error |= __vmwrite(GUEST_DS_SELECTOR, GUEST_LAUNCH_DS);
-    error |= __vmwrite(GUEST_FS_SELECTOR, GUEST_LAUNCH_DS);
-    error |= __vmwrite(GUEST_GS_SELECTOR, GUEST_LAUNCH_DS);
-    error |= __vmwrite(GUEST_CS_SELECTOR, GUEST_LAUNCH_CS);
-
     /* Guest segment bases. */
     error |= __vmwrite(GUEST_ES_BASE, 0);
     error |= __vmwrite(GUEST_SS_BASE, 0);
@@ -463,14 +454,6 @@ static int construct_vmcs(struct vcpu *v, cpu_user_regs_t *regs)
     arbytes.fields.seg_type = 0xb;          /* 32-bit TSS (busy) */
     error |= __vmwrite(GUEST_TR_AR_BYTES, arbytes.bytes);
 
-    error |= __vmwrite(GUEST_RSP, 0);
-    error |= __vmwrite(GUEST_RIP, regs->eip);
-
-    /* Guest EFLAGS. */
-    eflags = regs->eflags & ~HVM_EFLAGS_RESERVED_0; /* clear 0s */
-    eflags |= HVM_EFLAGS_RESERVED_1; /* set 1s */
-    error |= __vmwrite(GUEST_RFLAGS, eflags);
-
     error |= __vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
     __asm__ __volatile__ ("mov %%dr7, %0\n" : "=r" (tmp));
     error |= __vmwrite(GUEST_DR7, tmp);
@@ -482,10 +465,7 @@ static int construct_vmcs(struct vcpu *v, cpu_user_regs_t *regs)
     error |= __vmwrite(EXCEPTION_BITMAP,
                        MONITOR_DEFAULT_EXCEPTION_BITMAP);
 
-    if ( regs->eflags & EF_TF )
-        error |= __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
-    else
-        error |= __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
+    vmx_vmcs_exit(v);
 
     return error;
 }
@@ -494,7 +474,16 @@ int vmx_create_vmcs(struct vcpu *v)
 {
     if ( (v->arch.hvm_vmx.vmcs = vmx_alloc_vmcs()) == NULL )
         return -ENOMEM;
     __vmx_clear_vmcs(v);
+    
+    if ( construct_vmcs(v) != 0 )
+    {
+        vmx_free_vmcs(v->arch.hvm_vmx.vmcs);
+        v->arch.hvm_vmx.vmcs = NULL;
+        return -EINVAL;
+    }
+
     return 0;
 }
 
@@ -547,20 +536,7 @@ void arch_vmx_do_resume(struct vcpu *v)
 
 void arch_vmx_do_launch(struct vcpu *v)
 {
-    cpu_user_regs_t *regs = &current->arch.guest_context.user_regs;
-
     vmx_load_vmcs(v);
-
-    if ( construct_vmcs(v, regs) < 0 )
-    {
-        if ( v->vcpu_id == 0 ) {
-            printk("Failed to construct VMCS for BSP.\n");
-        } else {
-            printk("Failed to construct VMCS for AP %d.\n", v->vcpu_id);
-        }
-        domain_crash_synchronous();
-    }
-
     vmx_do_launch(v);
     reset_stack_and_jump(vmx_asm_do_vmentry);
 }
index a220d30fcca6fba3221fdd5cd659cd9c0ab54fa2..816d50511b0232639ddacb80b3b634b678e52cd1 100644 (file)
@@ -57,6 +57,8 @@ static int vmx_vcpu_initialise(struct vcpu *v)
 {
     int rc;
 
+    spin_lock_init(&v->arch.hvm_vmx.vmcs_lock);
+
     v->arch.schedule_tail    = arch_vmx_do_launch;
     v->arch.ctxt_switch_from = vmx_ctxt_switch_from;
     v->arch.ctxt_switch_to   = vmx_ctxt_switch_to;
@@ -69,8 +71,6 @@ static int vmx_vcpu_initialise(struct vcpu *v)
         return rc;
     }
 
-    spin_lock_init(&v->arch.hvm_vmx.vmcs_lock);
-
     return 0;
 }
 
@@ -534,7 +534,8 @@ static void vmx_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
 
     __vmwrite(GUEST_RSP, regs->esp);
 
-    __vmwrite(GUEST_RFLAGS, regs->eflags);
+    /* NB. Bit 1 of RFLAGS must be set for VMENTRY to succeed. */
+    __vmwrite(GUEST_RFLAGS, regs->eflags | 2UL);
     if (regs->eflags & EF_TF)
         __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
     else
@@ -599,33 +600,13 @@ static void vmx_set_tsc_offset(struct vcpu *v, u64 offset)
     vmx_vmcs_exit(v);
 }
 
-/* SMP VMX guest support */
-static void vmx_init_ap_context(struct vcpu_guest_context *ctxt,
-                         int vcpuid, int trampoline_vector)
+static void vmx_init_ap_context(
+    struct vcpu_guest_context *ctxt, int vcpuid, int trampoline_vector)
 {
-    int i;
-
     memset(ctxt, 0, sizeof(*ctxt));
-
-    /*
-     * Initial register values:
-     */
     ctxt->user_regs.eip = VMXASSIST_BASE;
     ctxt->user_regs.edx = vcpuid;
     ctxt->user_regs.ebx = trampoline_vector;
-
-    /* Virtual IDT is empty at start-of-day. */
-    for ( i = 0; i < 256; i++ )
-    {
-        ctxt->trap_ctxt[i].vector = i;
-        ctxt->trap_ctxt[i].cs     = FLAT_KERNEL_CS;
-    }
-
-    /* No callback handlers. */
-#if defined(__i386__)
-    ctxt->event_callback_cs     = FLAT_KERNEL_CS;
-    ctxt->failsafe_callback_cs  = FLAT_KERNEL_CS;
-#endif
 }
 
 void do_nmi(struct cpu_user_regs *);
index f63b0156e96d5bd9692def55a55786c2aca872ec..440cbfee6926825a85e989d2d8aad372e5e816f1 100644 (file)
@@ -94,13 +94,6 @@ enum hval_bitmaps {
 
 #define VMX_DELIVER_NO_ERROR_CODE  -1
 
-/*
- * This works for both 32bit & 64bit eflags filteration
- * done in construct_init_vmc[sb]_guest()
- */
-#define HVM_EFLAGS_RESERVED_0          0xffc08028 /* bitmap for 0 */
-#define HVM_EFLAGS_RESERVED_1          0x00000002 /* bitmap for 1 */
-
 #if HVM_DEBUG
 #define DBG_LEVEL_0                 (1 << 0)
 #define DBG_LEVEL_1                 (1 << 1)