# 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
|