ia64/xen-unstable

changeset 16972:aecbf98aa709

vmx realmode: HOST_CR0.TS must be cleared when restoring guest FPU
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>
author Keir Fraser <keir.fraser@citrix.com>
date Sun Feb 03 09:30:59 2008 +0000 (2008-02-03)
parents 39ddd51318e9
children e4edc310e949
files xen/arch/x86/hvm/vmx/vmcs.c xen/arch/x86/hvm/vmx/vmx.c xen/include/asm-x86/hvm/vmx/cpu.h xen/include/asm-x86/hvm/vmx/vmcs.h
line diff
     1.1 --- a/xen/arch/x86/hvm/vmx/vmcs.c	Sun Feb 03 09:09:21 2008 +0000
     1.2 +++ b/xen/arch/x86/hvm/vmx/vmcs.c	Sun Feb 03 09:30:59 2008 +0000
     1.3 @@ -489,7 +489,8 @@ static int construct_vmcs(struct vcpu *v
     1.4      __vmwrite(HOST_GS_BASE, 0);
     1.5  
     1.6      /* Host control registers. */
     1.7 -    __vmwrite(HOST_CR0, read_cr0() | X86_CR0_TS);
     1.8 +    v->arch.hvm_vmx.host_cr0 = read_cr0() | X86_CR0_TS;
     1.9 +    __vmwrite(HOST_CR0, v->arch.hvm_vmx.host_cr0);
    1.10      __vmwrite(HOST_CR4, mmu_cr4_features);
    1.11  
    1.12      /* Host CS:RIP. */
     2.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Sun Feb 03 09:09:21 2008 +0000
     2.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Sun Feb 03 09:30:59 2008 +0000
     2.3 @@ -742,6 +742,13 @@ static int vmx_load_vmcs_ctxt(struct vcp
     2.4  
     2.5  static void vmx_ctxt_switch_from(struct vcpu *v)
     2.6  {
     2.7 +    ASSERT(read_cr0() & X86_CR0_TS);
     2.8 +    if ( !(v->arch.hvm_vmx.host_cr0 & X86_CR0_TS) )
     2.9 +    {
    2.10 +        v->arch.hvm_vmx.host_cr0 |= X86_CR0_TS;
    2.11 +        __vmwrite(HOST_CR0, v->arch.hvm_vmx.host_cr0);
    2.12 +    }
    2.13 +
    2.14      vmx_save_guest_msrs(v);
    2.15      vmx_restore_host_msrs();
    2.16      vmx_save_dr(v);
    2.17 @@ -1232,6 +1239,10 @@ void vmx_do_no_device_fault(void)
    2.18      setup_fpu(current);
    2.19      __vm_clear_bit(EXCEPTION_BITMAP, TRAP_no_device);
    2.20  
    2.21 +    ASSERT(v->arch.hvm_vmx.host_cr0 & X86_CR0_TS);
    2.22 +    v->arch.hvm_vmx.host_cr0 &= ~X86_CR0_TS;
    2.23 +    __vmwrite(HOST_CR0, v->arch.hvm_vmx.host_cr0);
    2.24 +
    2.25      /* Disable TS in guest CR0 unless the guest wants the exception too. */
    2.26      if ( !(v->arch.hvm_vcpu.guest_cr[0] & X86_CR0_TS) )
    2.27      {
     3.1 --- a/xen/include/asm-x86/hvm/vmx/cpu.h	Sun Feb 03 09:09:21 2008 +0000
     3.2 +++ b/xen/include/asm-x86/hvm/vmx/cpu.h	Sun Feb 03 09:30:59 2008 +0000
     3.3 @@ -19,19 +19,6 @@
     3.4  #ifndef __ASM_X86_HVM_VMX_CPU_H__
     3.5  #define __ASM_X86_HVM_VMX_CPU_H__
     3.6  
     3.7 -/*
     3.8 - * Virtual CPU
     3.9 - */
    3.10 -struct arch_state_struct {
    3.11 -    unsigned long       mode_flags; /* vm86, 32-bit, 64-bit, etc. */
    3.12 -    /* debug registers */
    3.13 -    /* MSRs */
    3.14 -};
    3.15 -
    3.16 -#define VMX_MF_VM86     0
    3.17 -#define VMX_MF_32       1
    3.18 -#define VMX_MF_64       2
    3.19 -
    3.20  #define NUM_CORES_RESET_MASK                 0x00003FFF
    3.21  #define NUM_THREADS_RESET_MASK               0xFF00FFFF
    3.22  
     4.1 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h	Sun Feb 03 09:09:21 2008 +0000
     4.2 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h	Sun Feb 03 09:30:59 2008 +0000
     4.3 @@ -92,6 +92,8 @@ struct arch_vmx_struct {
     4.4      unsigned int         host_msr_count;
     4.5      struct vmx_msr_entry *host_msr_area;
     4.6  
     4.7 +    unsigned long        host_cr0;
     4.8 +
     4.9  #ifdef VMXASSIST
    4.10      unsigned long        vmxassist_enabled:1;
    4.11      unsigned long        irqbase_mode:1;