[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 = ¤t->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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |