ia64/xen-unstable

changeset 16096:313ab23f05db

hvm: Fix CR0.TS handling.
Signed-off-by: Keir Fraser <keir@xensource.com>
author Keir Fraser <keir@xensource.com>
date Thu Oct 11 13:53:50 2007 +0100 (2007-10-11)
parents 034df2dca608
children d5531095d06b
files xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/vmx/vmx.c
line diff
     1.1 --- a/xen/arch/x86/hvm/svm/svm.c	Thu Oct 11 13:32:41 2007 +0100
     1.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Thu Oct 11 13:53:50 2007 +0100
     1.3 @@ -474,6 +474,14 @@ static void svm_update_guest_cr(struct v
     1.4      switch ( cr )
     1.5      {
     1.6      case 0:
     1.7 +        /* TS cleared? Then initialise FPU now. */
     1.8 +        if ( (v == current) && !(v->arch.hvm_vcpu.guest_cr[0] & X86_CR0_TS) &&
     1.9 +             (vmcb->cr0 & X86_CR0_TS) )
    1.10 +        {
    1.11 +            setup_fpu(v);
    1.12 +            vmcb->exception_intercepts &= ~(1U << TRAP_no_device);
    1.13 +        }
    1.14 +
    1.15          vmcb->cr0 = v->arch.hvm_vcpu.guest_cr[0];
    1.16          if ( !paging_mode_hap(v->domain) )
    1.17              vmcb->cr0 |= X86_CR0_PG | X86_CR0_WP;
    1.18 @@ -1538,25 +1546,6 @@ static void svm_io_instruction(struct vc
    1.19      }
    1.20  }
    1.21  
    1.22 -static int svm_set_cr0(unsigned long value)
    1.23 -{
    1.24 -    struct vcpu *v = current;
    1.25 -    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
    1.26 -    int rc = hvm_set_cr0(value);
    1.27 -
    1.28 -    if ( rc == 0 )
    1.29 -        return 0;
    1.30 -
    1.31 -    /* TS cleared? Then initialise FPU now. */
    1.32 -    if ( !(value & X86_CR0_TS) )
    1.33 -    {
    1.34 -        setup_fpu(v);
    1.35 -        vmcb->exception_intercepts &= ~(1U << TRAP_no_device);
    1.36 -    }
    1.37 -
    1.38 -    return 1;
    1.39 -}
    1.40 -
    1.41  static void mov_from_cr(int cr, int gp, struct cpu_user_regs *regs)
    1.42  {
    1.43      unsigned long value = 0;
    1.44 @@ -1603,7 +1592,7 @@ static int mov_to_cr(int gpreg, int cr, 
    1.45      switch ( cr )
    1.46      {
    1.47      case 0: 
    1.48 -        return svm_set_cr0(value);
    1.49 +        return hvm_set_cr0(value);
    1.50      case 3:
    1.51          return hvm_set_cr3(value);
    1.52      case 4:
    1.53 @@ -1688,7 +1677,7 @@ static void svm_cr_access(
    1.54          gpreg = decode_src_reg(prefix, buffer[index+2]);
    1.55          value = get_reg(gpreg, regs, vmcb) & 0xF;
    1.56          value = (v->arch.hvm_vcpu.guest_cr[0] & ~0xF) | value;
    1.57 -        result = svm_set_cr0(value);
    1.58 +        result = hvm_set_cr0(value);
    1.59          HVMTRACE_1D(LMSW, current, value);
    1.60          break;
    1.61  
     2.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Thu Oct 11 13:32:41 2007 +0100
     2.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Thu Oct 11 13:53:50 2007 +0100
     2.3 @@ -1022,6 +1022,14 @@ static void vmx_update_guest_cr(struct v
     2.4      switch ( cr )
     2.5      {
     2.6      case 0:
     2.7 +        /* TS cleared? Then initialise FPU now. */
     2.8 +        if ( (v == current) && !(v->arch.hvm_vcpu.guest_cr[0] & X86_CR0_TS) &&
     2.9 +             (v->arch.hvm_vcpu.hw_cr[0] & X86_CR0_TS) )
    2.10 +        {
    2.11 +            setup_fpu(v);
    2.12 +            __vm_clear_bit(EXCEPTION_BITMAP, TRAP_no_device);
    2.13 +        }
    2.14 +
    2.15          v->arch.hvm_vcpu.hw_cr[0] =
    2.16              v->arch.hvm_vcpu.guest_cr[0] |
    2.17              X86_CR0_PE | X86_CR0_NE | X86_CR0_PG | X86_CR0_WP;
    2.18 @@ -2046,13 +2054,6 @@ static int vmx_set_cr0(unsigned long val
    2.19      if ( rc == 0 )
    2.20          return 0;
    2.21  
    2.22 -    /* TS cleared? Then initialise FPU now. */
    2.23 -    if ( !(value & X86_CR0_TS) )
    2.24 -    {
    2.25 -        setup_fpu(v);
    2.26 -        __vm_clear_bit(EXCEPTION_BITMAP, TRAP_no_device);
    2.27 -    }
    2.28 -
    2.29      /*
    2.30       * VMX does not implement real-mode virtualization. We emulate
    2.31       * real-mode by performing a world switch to VMXAssist whenever