# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1213697481 -3600
# Node ID 7a741ec5503fa9e3c8c6c99726aa79c679d9dc56
# Parent e5e36ebe727a6d31b4013c63b89b322f0d7302eb
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@xxxxxxxxxx>
xen-unstable changeset: 16970:aecbf98aa7099458fe6895bbd8f15d506e0901b3
xen-unstable date: Sun Feb 03 09:30:59 2008 +0000
---
xen/arch/x86/hvm/vmx/vmcs.c | 3 ++-
xen/arch/x86/hvm/vmx/vmx.c | 11 +++++++++++
xen/include/asm-x86/hvm/vmx/vmcs.h | 2 ++
3 files changed, 15 insertions(+), 1 deletion(-)
diff -r e5e36ebe727a -r 7a741ec5503f xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c Mon Jun 16 11:56:31 2008 +0100
+++ b/xen/arch/x86/hvm/vmx/vmcs.c Tue Jun 17 11:11:21 2008 +0100
@@ -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. */
diff -r e5e36ebe727a -r 7a741ec5503f xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Mon Jun 16 11:56:31 2008 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c Tue Jun 17 11:11:21 2008 +0100
@@ -738,6 +738,13 @@ static int vmx_load_vmcs_ctxt(struct vcp
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);
@@ -1230,6 +1237,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) )
diff -r e5e36ebe727a -r 7a741ec5503f xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h Mon Jun 16 11:56:31 2008 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h Tue Jun 17 11:11:21 2008 +0100
@@ -86,6 +86,8 @@ struct arch_vmx_struct {
struct vmx_msr_entry *msr_area;
unsigned int host_msr_count;
struct vmx_msr_entry *host_msr_area;
+
+ unsigned long host_cr0;
#ifdef VMXASSIST
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|