[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [HVM] Move VMX VMCS initialisation to vcpu-initialisation time.



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID b2668cc03914ebd65d54b6c5a7d0ee6bf102357c
# Parent  29bfe8852dce2e7ff79cf1e907d8317fafd4a60c
[HVM] Move VMX VMCS initialisation to vcpu-initialisation time.
Simplify context initialisation (e.g., no need for selectors to
be given dummy non-zero values).
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 tools/libxc/xc_hvm_build.c        |   55 ++++++++------------------------------
 xen/arch/x86/domain.c             |    2 -
 xen/arch/x86/hvm/svm/svm.c        |   28 ++-----------------
 xen/arch/x86/hvm/svm/vmcb.c       |    6 ----
 xen/arch/x86/hvm/vmx/vmcs.c       |   52 +++++++++--------------------------
 xen/arch/x86/hvm/vmx/vmx.c        |   33 ++++------------------
 xen/include/asm-x86/hvm/support.h |    7 ----
 7 files changed, 39 insertions(+), 144 deletions(-)

diff -r 29bfe8852dce -r b2668cc03914 tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c        Mon Nov 06 11:36:38 2006 +0000
+++ b/tools/libxc/xc_hvm_build.c        Mon Nov 06 13:13:04 2006 +0000
@@ -309,19 +309,13 @@ static int xc_hvm_build_internal(int xc_
                                  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) )
     {
         ERROR("Image required");
         goto error_out;
-    }
-
-    if ( lock_pages(&st_ctxt, sizeof(st_ctxt) ) )
-    {
-        PERROR("%s: ctxt mlock failed", __func__);
-        return 1;
     }
 
     domctl.cmd = XEN_DOMCTL_getdomaininfo;
@@ -333,55 +327,30 @@ static int xc_hvm_build_internal(int xc_
         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++ )
-    {
-        ctxt->trap_ctxt[i].vector = i;
-        ctxt->trap_ctxt[i].cs     = FLAT_KERNEL_CS;
-    }
-
-    /* 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
+    if ( lock_pages(&ctxt, sizeof(ctxt) ) )
+    {
+        PERROR("%s: ctxt mlock failed", __func__);
+        goto error_out;
+    }
 
     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;
 
diff -r 29bfe8852dce -r b2668cc03914 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Mon Nov 06 11:36:38 2006 +0000
+++ b/xen/arch/x86/domain.c     Mon Nov 06 13:13:04 2006 +0000
@@ -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);
     }
diff -r 29bfe8852dce -r b2668cc03914 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Mon Nov 06 11:36:38 2006 +0000
+++ b/xen/arch/x86/hvm/svm/svm.c        Mon Nov 06 13:13:04 2006 +0000
@@ -530,30 +530,10 @@ static void svm_set_tsc_offset(struct vc
 }
 
 
-/* SVM-specific intitialization code for VCPU application processors */
-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;
-
+static void svm_init_ap_context(
+    struct vcpu_guest_context *ctxt, int vcpuid, int trampoline_vector)
+{
     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(struc
     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)
diff -r 29bfe8852dce -r b2668cc03914 xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c       Mon Nov 06 11:36:38 2006 +0000
+++ b/xen/arch/x86/hvm/svm/vmcb.c       Mon Nov 06 13:13:04 2006 +0000
@@ -160,7 +160,6 @@ static int construct_init_vmcb_guest(str
     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(str
     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;
diff -r 29bfe8852dce -r b2668cc03914 xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Mon Nov 06 11:36:38 2006 +0000
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Mon Nov 06 13:13:04 2006 +0000
@@ -233,10 +233,7 @@ void vmx_free_host_vmcs(struct vmcs_stru
     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,11 +350,13 @@ 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);
@@ -404,14 +403,6 @@ static int construct_vmcs(struct vcpu *v
     error |= __vmwrite(CR3_TARGET_COUNT, 0);
 
     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);
@@ -463,14 +454,6 @@ static int construct_vmcs(struct vcpu *v
     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
     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);
 }
diff -r 29bfe8852dce -r b2668cc03914 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Mon Nov 06 11:36:38 2006 +0000
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Mon Nov 06 13:13:04 2006 +0000
@@ -57,6 +57,8 @@ static int vmx_vcpu_initialise(struct vc
 {
     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;
@@ -68,8 +70,6 @@ static int vmx_vcpu_initialise(struct vc
                 v->vcpu_id, rc);
         return rc;
     }
-
-    spin_lock_init(&v->arch.hvm_vmx.vmcs_lock);
 
     return 0;
 }
@@ -534,7 +534,8 @@ static void vmx_load_cpu_guest_regs(stru
 
     __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 vc
     vmx_vmcs_exit(v);
 }
 
-/* SMP VMX guest support */
-static void vmx_init_ap_context(struct vcpu_guest_context *ctxt,
-                         int vcpuid, int trampoline_vector)
-{
-    int i;
-
+static void vmx_init_ap_context(
+    struct vcpu_guest_context *ctxt, int vcpuid, int trampoline_vector)
+{
     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 *);
diff -r 29bfe8852dce -r b2668cc03914 xen/include/asm-x86/hvm/support.h
--- a/xen/include/asm-x86/hvm/support.h Mon Nov 06 11:36:38 2006 +0000
+++ b/xen/include/asm-x86/hvm/support.h Mon Nov 06 13:13:04 2006 +0000
@@ -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)

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.