Unconditionally enable fpu emulation by setting CR0.TS in the host after the

guest does a vm exit.

This allows us to trap any fpu access in the host context while the fpu still
has "dirty" state belonging to the guest.

Reported by: "s vas" on freebsd-virtualization@
Obtained from:	NetApp
This commit is contained in:
Neel Natu 2012-10-26 03:12:40 +00:00
parent f76fc5d414
commit bd8572e0be
2 changed files with 22 additions and 1 deletions

View File

@ -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;

View File

@ -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();
}