ia64/xen-unstable
changeset 16096:313ab23f05db
hvm: Fix CR0.TS handling.
Signed-off-by: Keir Fraser <keir@xensource.com>
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