diff options
-rw-r--r-- | sys/amd64/vmm/intel/vmcs.c | 10 | ||||
-rw-r--r-- | sys/amd64/vmm/vmm.c | 13 |
2 files changed, 22 insertions, 1 deletions
diff --git a/sys/amd64/vmm/intel/vmcs.c b/sys/amd64/vmm/intel/vmcs.c index 8c53465..26ac5f8 100644 --- a/sys/amd64/vmm/intel/vmcs.c +++ b/sys/amd64/vmm/intel/vmcs.c @@ -367,7 +367,15 @@ vmcs_set_defaults(struct vmcs *vmcs, goto done; /* Load the control registers */ - cr0 = rcr0(); + + /* + * We always want CR0.TS to be set when the processor does a VM exit. + * + * With emulation turned on unconditionally after a VM exit, we are + * able to trap inadvertent use of the FPU until the guest FPU state + * has been safely squirreled away. + */ + cr0 = rcr0() | CR0_TS; if ((error = vmwrite(VMCS_HOST_CR0, cr0)) != 0) goto done; diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c index 8bc9581..6efc01f 100644 --- a/sys/amd64/vmm/vmm.c +++ b/sys/amd64/vmm/vmm.c @@ -640,14 +640,27 @@ restore_guest_fpustate(struct vcpu *vcpu) /* flush host state to the pcb */ fpuexit(curthread); + + /* restore guest FPU state */ fpu_stop_emulating(); fpurestore(vcpu->guestfpu); + + /* + * The FPU is now "dirty" with the guest's state so turn on emulation + * to trap any access to the FPU by the host. + */ + fpu_start_emulating(); } static void save_guest_fpustate(struct vcpu *vcpu) { + if ((rcr0() & CR0_TS) == 0) + panic("fpu emulation not enabled in host!"); + + /* save guest FPU state */ + fpu_stop_emulating(); fpusave(vcpu->guestfpu); fpu_start_emulating(); } |