mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
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>
This commit is contained in:
1 parent
7eec742d38
commit
b2e1b25f9c
4 files changed
+15
-14
No files matched your search
@@ -489,7 +489,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. */
|
||||
|
||||
@@ -742,6 +742,13 @@ static int vmx_load_vmcs_ctxt(struct vcpu *v, struct hvm_hw_cpu *ctxt)
|
||||
|
||||
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);
|
||||
@@ -1232,6 +1239,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) )
|
||||
{
|
||||
|
||||
@@ -19,19 +19,6 @@
|
||||
#ifndef __ASM_X86_HVM_VMX_CPU_H__
|
||||
#define __ASM_X86_HVM_VMX_CPU_H__
|
||||
|
||||
/*
|
||||
* Virtual CPU
|
||||
*/
|
||||
struct arch_state_struct {
|
||||
unsigned long mode_flags; /* vm86, 32-bit, 64-bit, etc. */
|
||||
/* debug registers */
|
||||
/* MSRs */
|
||||
};
|
||||
|
||||
#define VMX_MF_VM86 0
|
||||
#define VMX_MF_32 1
|
||||
#define VMX_MF_64 2
|
||||
|
||||
#define NUM_CORES_RESET_MASK 0x00003FFF
|
||||
#define NUM_THREADS_RESET_MASK 0xFF00FFFF
|
||||
|
||||
|
||||
@@ -92,6 +92,8 @@ struct arch_vmx_struct {
|
||||
unsigned int host_msr_count;
|
||||
struct vmx_msr_entry *host_msr_area;
|
||||
|
||||
unsigned long host_cr0;
|
||||
|
||||
#ifdef VMXASSIST
|
||||
unsigned long vmxassist_enabled:1;
|
||||
unsigned long irqbase_mode:1;
|
||||
|
||||