Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 26 Oct 2012 03:12:41 +0000 (UTC)
From:      Neel Natu <neel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r242122 - in projects/bhyve/sys/amd64/vmm: . intel
Message-ID:  <201210260312.q9Q3Cfwh009022@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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();
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201210260312.q9Q3Cfwh009022>