]> xenbits.xensource.com Git - people/vhanquez/xen.git/commitdiff
vmx realmode: HOST_CR0.TS must be cleared when restoring guest FPU
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 17 Jun 2008 10:11:21 +0000 (11:11 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 17 Jun 2008 10:11:21 +0000 (11:11 +0100)
state, otherwise in-Xen CR0.TS value becomes set again on next
vmexit. Then we crash the next time we try to emulate an FPU
instruction.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen-unstable changeset:   16970:aecbf98aa7099458fe6895bbd8f15d506e0901b3
xen-unstable date:        Sun Feb 03 09:30:59 2008 +0000

xen/arch/x86/hvm/vmx/vmcs.c
xen/arch/x86/hvm/vmx/vmx.c
xen/include/asm-x86/hvm/vmx/vmcs.h

index 594e2525e0fdfeffcef8be97c679789c81806e00..19bf3f4d54980c58a2e1a4138cfafb6ee3eda38d 100644 (file)
@@ -510,7 +510,8 @@ static int construct_vmcs(struct vcpu *v)
     __vmwrite(HOST_GS_BASE, 0);
 
     /* Host control registers. */
-    __vmwrite(HOST_CR0, read_cr0() | X86_CR0_TS);
+    v->arch.hvm_vmx.host_cr0 = read_cr0() | X86_CR0_TS;
+    __vmwrite(HOST_CR0, v->arch.hvm_vmx.host_cr0);
     __vmwrite(HOST_CR4, mmu_cr4_features);
 
     /* Host CS:RIP. */
index 475efff47ad88cd9ce245edd0388b4d2a70f7305..a4a35ebe46739ac28be9020cb3261111ce9163b4 100644 (file)
@@ -738,6 +738,13 @@ static int vmx_load_vmcs_ctxt(struct vcpu *v, struct hvm_hw_cpu *ctxt)
 
 static void vmx_ctxt_switch_from(struct vcpu *v)
 {
+    ASSERT(read_cr0() & X86_CR0_TS);
+    if ( !(v->arch.hvm_vmx.host_cr0 & X86_CR0_TS) )
+    {
+        v->arch.hvm_vmx.host_cr0 |= X86_CR0_TS;
+        __vmwrite(HOST_CR0, v->arch.hvm_vmx.host_cr0);
+    }
+
     vmx_save_guest_msrs(v);
     vmx_restore_host_msrs();
     vmx_save_dr(v);
@@ -1231,6 +1238,10 @@ void vmx_do_no_device_fault(void)
     setup_fpu(current);
     __vm_clear_bit(EXCEPTION_BITMAP, TRAP_no_device);
 
+    ASSERT(v->arch.hvm_vmx.host_cr0 & X86_CR0_TS);
+    v->arch.hvm_vmx.host_cr0 &= ~X86_CR0_TS;
+    __vmwrite(HOST_CR0, v->arch.hvm_vmx.host_cr0);
+
     /* Disable TS in guest CR0 unless the guest wants the exception too. */
     if ( !(v->arch.hvm_vcpu.guest_cr[0] & X86_CR0_TS) )
     {
index cb3c70a69142c7ecf48ab8362bc8844fc663eccf..94e2c056f00f38df556068add731177ab9c39f0d 100644 (file)
@@ -87,6 +87,8 @@ struct arch_vmx_struct {
     unsigned int         host_msr_count;
     struct vmx_msr_entry *host_msr_area;
 
+    unsigned long        host_cr0;
+
 #ifdef VMXASSIST
 
     unsigned long        vmxassist_enabled:1;