svn commit: r242122 - in projects/bhyve/sys/amd64/vmm: . intel

Neel Natu neel at FreeBSD.org
Fri Oct 26 03:12:41 UTC 2012


Author: neel
Date: Fri Oct 26 03:12:40 2012
New Revision: 242122
URL: http://svn.freebsd.org/changeset/base/242122

Log:
  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

Modified:
  projects/bhyve/sys/amd64/vmm/intel/vmcs.c
  projects/bhyve/sys/amd64/vmm/vmm.c

Modified: projects/bhyve/sys/amd64/vmm/intel/vmcs.c
==============================================================================
--- projects/bhyve/sys/amd64/vmm/intel/vmcs.c	Fri Oct 26 03:02:39 2012	(r242121)
+++ projects/bhyve/sys/amd64/vmm/intel/vmcs.c	Fri Oct 26 03:12:40 2012	(r242122)
@@ -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;
 	

Modified: projects/bhyve/sys/amd64/vmm/vmm.c
==============================================================================
--- projects/bhyve/sys/amd64/vmm/vmm.c	Fri Oct 26 03:02:39 2012	(r242121)
+++ projects/bhyve/sys/amd64/vmm/vmm.c	Fri Oct 26 03:12:40 2012	(r242122)
@@ -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();
 }


More information about the svn-src-projects mailing list