# HG changeset patch
# User Keir Fraser <keir@xxxxxxxxxxxxx>
# Date 1192107230 -3600
# Node ID 313ab23f05dbd7b708653ff4603b62da534efd84
# Parent 034df2dca6081e3b88be549e66c67184b6bbce55
hvm: Fix CR0.TS handling.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
xen/arch/x86/hvm/svm/svm.c | 31 ++++++++++---------------------
xen/arch/x86/hvm/vmx/vmx.c | 15 ++++++++-------
2 files changed, 18 insertions(+), 28 deletions(-)
diff -r 034df2dca608 -r 313ab23f05db xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Thu Oct 11 13:32:41 2007 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c Thu Oct 11 13:53:50 2007 +0100
@@ -474,6 +474,14 @@ static void svm_update_guest_cr(struct v
switch ( cr )
{
case 0:
+ /* TS cleared? Then initialise FPU now. */
+ if ( (v == current) && !(v->arch.hvm_vcpu.guest_cr[0] & X86_CR0_TS) &&
+ (vmcb->cr0 & X86_CR0_TS) )
+ {
+ setup_fpu(v);
+ vmcb->exception_intercepts &= ~(1U << TRAP_no_device);
+ }
+
vmcb->cr0 = v->arch.hvm_vcpu.guest_cr[0];
if ( !paging_mode_hap(v->domain) )
vmcb->cr0 |= X86_CR0_PG | X86_CR0_WP;
@@ -1538,25 +1546,6 @@ static void svm_io_instruction(struct vc
}
}
-static int svm_set_cr0(unsigned long value)
-{
- struct vcpu *v = current;
- struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
- int rc = hvm_set_cr0(value);
-
- if ( rc == 0 )
- return 0;
-
- /* TS cleared? Then initialise FPU now. */
- if ( !(value & X86_CR0_TS) )
- {
- setup_fpu(v);
- vmcb->exception_intercepts &= ~(1U << TRAP_no_device);
- }
-
- return 1;
-}
-
static void mov_from_cr(int cr, int gp, struct cpu_user_regs *regs)
{
unsigned long value = 0;
@@ -1603,7 +1592,7 @@ static int mov_to_cr(int gpreg, int cr,
switch ( cr )
{
case 0:
- return svm_set_cr0(value);
+ return hvm_set_cr0(value);
case 3:
return hvm_set_cr3(value);
case 4:
@@ -1688,7 +1677,7 @@ static void svm_cr_access(
gpreg = decode_src_reg(prefix, buffer[index+2]);
value = get_reg(gpreg, regs, vmcb) & 0xF;
value = (v->arch.hvm_vcpu.guest_cr[0] & ~0xF) | value;
- result = svm_set_cr0(value);
+ result = hvm_set_cr0(value);
HVMTRACE_1D(LMSW, current, value);
break;
diff -r 034df2dca608 -r 313ab23f05db xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Thu Oct 11 13:32:41 2007 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c Thu Oct 11 13:53:50 2007 +0100
@@ -1022,6 +1022,14 @@ static void vmx_update_guest_cr(struct v
switch ( cr )
{
case 0:
+ /* TS cleared? Then initialise FPU now. */
+ if ( (v == current) && !(v->arch.hvm_vcpu.guest_cr[0] & X86_CR0_TS) &&
+ (v->arch.hvm_vcpu.hw_cr[0] & X86_CR0_TS) )
+ {
+ setup_fpu(v);
+ __vm_clear_bit(EXCEPTION_BITMAP, TRAP_no_device);
+ }
+
v->arch.hvm_vcpu.hw_cr[0] =
v->arch.hvm_vcpu.guest_cr[0] |
X86_CR0_PE | X86_CR0_NE | X86_CR0_PG | X86_CR0_WP;
@@ -2046,13 +2054,6 @@ static int vmx_set_cr0(unsigned long val
if ( rc == 0 )
return 0;
- /* TS cleared? Then initialise FPU now. */
- if ( !(value & X86_CR0_TS) )
- {
- setup_fpu(v);
- __vm_clear_bit(EXCEPTION_BITMAP, TRAP_no_device);
- }
-
/*
* VMX does not implement real-mode virtualization. We emulate
* real-mode by performing a world switch to VMXAssist whenever
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|