summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/amd64/vmm/intel/vmcs.c10
-rw-r--r--sys/amd64/vmm/vmm.c13
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();
}
OpenPOWER on IntegriCloud