]> xenbits.xensource.com Git - xen.git/commitdiff
vmx: Restore correct host SYSENTER parameters on vmexit.
authorKeir Fraser <keir@xensource.com>
Tue, 13 Nov 2007 19:05:27 +0000 (19:05 +0000)
committerKeir Fraser <keir@xensource.com>
Tue, 13 Nov 2007 19:05:27 +0000 (19:05 +0000)
Also simplify vmx_set_host_env().
HOST_GDT_BASE does not have to change when we shift CPU.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/arch/x86/hvm/vmx/vmcs.c
xen/include/asm-x86/hvm/vmx/vmcs.h

index 2a84b38a34d2b19e63407c11dc4067743759ad80..14d54496ba850933afe33ed5e3d0d264a1633767 100644 (file)
@@ -399,21 +399,15 @@ struct xgt_desc {
 
 static void vmx_set_host_env(struct vcpu *v)
 {
-    unsigned int tr, cpu;
-    struct xgt_desc desc;
+    unsigned int cpu = smp_processor_id();
 
-    cpu = smp_processor_id();
+    __vmwrite(HOST_IDTR_BASE, (unsigned long)idt_tables[cpu]);
 
-    __asm__ __volatile__ ( "sidt (%0) \n" : : "a" (&desc) : "memory" );
-    __vmwrite(HOST_IDTR_BASE, desc.address);
-
-    __asm__ __volatile__ ( "sgdt (%0) \n" : : "a" (&desc) : "memory" );
-    __vmwrite(HOST_GDTR_BASE, desc.address);
-
-    __asm__ __volatile__ ( "str (%0) \n" : : "a" (&tr) : "memory" );
-    __vmwrite(HOST_TR_SELECTOR, tr);
+    __vmwrite(HOST_TR_SELECTOR, __TSS(cpu) << 3);
     __vmwrite(HOST_TR_BASE, (unsigned long)&init_tss[cpu]);
 
+    __vmwrite(HOST_SYSENTER_ESP, get_stack_bottom());
+
     /*
      * Skip end of cpu_user_regs when entering the hypervisor because the
      * CPU does not save context onto the stack. SS,RSP,CS,RIP,RFLAGS,etc
@@ -454,6 +448,8 @@ void vmx_disable_intercept_for_msr(struct vcpu *v, u32 msr)
 static int construct_vmcs(struct vcpu *v)
 {
     union vmcs_arbytes arbytes;
+    uint16_t sysenter_cs;
+    unsigned long sysenter_eip;
 
     vmx_vmcs_enter(v);
 
@@ -489,6 +485,9 @@ static int construct_vmcs(struct vcpu *v)
     __vmwrite(IO_BITMAP_A, virt_to_maddr(hvm_io_bitmap));
     __vmwrite(IO_BITMAP_B, virt_to_maddr(hvm_io_bitmap + PAGE_SIZE));
 
+    /* Host GDTR base. */
+    __vmwrite(HOST_GDTR_BASE, GDT_VIRT_START(v));
+
     /* Host data selectors. */
     __vmwrite(HOST_SS_SELECTOR, __HYPERVISOR_DS);
     __vmwrite(HOST_DS_SELECTOR, __HYPERVISOR_DS);
@@ -506,6 +505,12 @@ static int construct_vmcs(struct vcpu *v)
     __vmwrite(HOST_CS_SELECTOR, __HYPERVISOR_CS);
     __vmwrite(HOST_RIP, (unsigned long)vmx_asm_vmexit_handler);
 
+    /* Host SYSENTER CS:RIP. */
+    rdmsrl(MSR_IA32_SYSENTER_CS, sysenter_cs);
+    __vmwrite(HOST_SYSENTER_CS, sysenter_cs);
+    rdmsrl(MSR_IA32_SYSENTER_EIP, sysenter_eip);
+    __vmwrite(HOST_SYSENTER_EIP, sysenter_eip);
+
     /* MSR intercepts. */
     __vmwrite(VM_EXIT_MSR_LOAD_COUNT, 0);
     __vmwrite(VM_EXIT_MSR_STORE_COUNT, 0);
@@ -903,9 +908,9 @@ void vmcs_dump_vcpu(void)
            (unsigned long long)vmr(HOST_CR3),
            (unsigned long long)vmr(HOST_CR4));
     printk("Sysenter RSP=%016llx CS:RIP=%04x:%016llx\n",
-           (unsigned long long)vmr(HOST_IA32_SYSENTER_ESP),
-           (int)vmr(HOST_IA32_SYSENTER_CS),
-           (unsigned long long)vmr(HOST_IA32_SYSENTER_EIP));
+           (unsigned long long)vmr(HOST_SYSENTER_ESP),
+           (int)vmr(HOST_SYSENTER_CS),
+           (unsigned long long)vmr(HOST_SYSENTER_EIP));
 
     printk("*** Control State ***\n");
     printk("PinBased=%08x CPUBased=%08x SecondaryExec=%08x\n",
index 132aa1d529240f81df727489bc775108ea08d60d..d3da4e3549ba2a0b1870b1d55204a346dd318ec0 100644 (file)
@@ -235,7 +235,7 @@ enum vmcs_field {
     GUEST_INTERRUPTIBILITY_INFO     = 0x00004824,
     GUEST_ACTIVITY_STATE            = 0x00004826,
     GUEST_SYSENTER_CS               = 0x0000482A,
-    HOST_IA32_SYSENTER_CS           = 0x00004c00,
+    HOST_SYSENTER_CS                = 0x00004c00,
     CR0_GUEST_HOST_MASK             = 0x00006000,
     CR4_GUEST_HOST_MASK             = 0x00006002,
     CR0_READ_SHADOW                 = 0x00006004,
@@ -274,8 +274,8 @@ enum vmcs_field {
     HOST_TR_BASE                    = 0x00006c0a,
     HOST_GDTR_BASE                  = 0x00006c0c,
     HOST_IDTR_BASE                  = 0x00006c0e,
-    HOST_IA32_SYSENTER_ESP          = 0x00006c10,
-    HOST_IA32_SYSENTER_EIP          = 0x00006c12,
+    HOST_SYSENTER_ESP               = 0x00006c10,
+    HOST_SYSENTER_EIP               = 0x00006c12,
     HOST_RSP                        = 0x00006c14,
     HOST_RIP                        = 0x00006c16,
 };