svn commit: r271086 - projects/bhyve_svm/sys/amd64/vmm/amd

Neel Natu neel at FreeBSD.org
Thu Sep 4 06:00:19 UTC 2014


Author: neel
Date: Thu Sep  4 06:00:18 2014
New Revision: 271086
URL: http://svnweb.freebsd.org/changeset/base/271086

Log:
  Consolidate the code to restore the host TSS after a #VMEXIT into a single
  function restore_host_tss().
  
  Don't bother to restore MSR_KGSBASE after a #VMEXIT since it is not used in
  the kernel. It will be restored on return to userspace.
  
  Discussed with:	Anish Gupta (akgupt3 at gmail.com)

Modified:
  projects/bhyve_svm/sys/amd64/vmm/amd/svm.c

Modified: projects/bhyve_svm/sys/amd64/vmm/amd/svm.c
==============================================================================
--- projects/bhyve_svm/sys/amd64/vmm/amd/svm.c	Thu Sep  4 03:31:48 2014	(r271085)
+++ projects/bhyve_svm/sys/amd64/vmm/amd/svm.c	Thu Sep  4 06:00:18 2014	(r271086)
@@ -1104,22 +1104,21 @@ svm_inj_interrupts(struct svm_softc *svm
 	VCPU_CTR1(svm_sc->vm, vcpu, "SVM:event injected,vector=%d.\n", vector);
 }
 
-/*
- * Restore host Task Register selector type after every vcpu exit.
- */
 static void
-setup_tss_type(void)
+restore_host_tss(void)
 {
-	struct system_segment_descriptor *desc;
+	struct system_segment_descriptor *tss_sd;
 
-	desc = (struct system_segment_descriptor *)&gdt[curcpu * NGDT +
-		GPROC0_SEL];
 	/*
-	 * Task selector that should be restored in host is
-	 * 64-bit available(9), not what is read(0xb), see
-	 * APMvol2 Rev3.21 4.8.3 System Descriptors table.
+	 * The TSS descriptor was in use prior to launching the guest so it
+	 * has been marked busy.
+	 *
+	 * 'ltr' requires the descriptor to be marked available so change the
+	 * type to "64-bit available TSS".
 	 */
-	desc->sd_type = 9;
+	tss_sd = PCPU_GET(tss);
+	tss_sd->sd_type = SDT_SYSTSS;
+	ltr(GSEL(GPROC0_SEL, SEL_KPL));
 }
 
 /*
@@ -1241,32 +1240,27 @@ svm_vmrun(void *arg, int vcpu, register_
 
 		svm_inj_interrupts(svm_sc, vcpu, vlapic);
 
-		/* Change TSS type to available.*/
-		setup_tss_type();
-
 		/* Launch Virtual Machine. */
 		svm_launch(vmcb_pa, gctx, hctx);
 
 		/*
-		 * Only GDTR and IDTR of host is saved and restore by SVM,
-		 * LDTR and TR need to be restored by VMM.
-		 * XXX: kernel doesn't use LDT, only user space.
+		 * Restore MSR_GSBASE to point to the pcpu data area.
+		 *
+		 * Note that accesses done via PCPU_GET/PCPU_SET will work
+		 * only after MSR_GSBASE is restored.
+		 *
+		 * Also note that we don't bother restoring MSR_KGSBASE
+		 * since it is not used in the kernel and will be restored
+		 * when the VMRUN ioctl returns to userspace.
 		 */
-		ltr(GSEL(GPROC0_SEL, SEL_KPL));
+		wrmsr(MSR_GSBASE, (uint64_t)&__pcpu[vcpustate->lastcpu]);
 
 		/*
-		 * Guest FS and GS selector are stashed by vmload and vmsave.
-		 * Host FS and GS selector are stashed by svm_launch().
-		 * Host GS base that holds per-cpu need to be restored before
-		 * enabling global interrupt.
-		 * FS is not used by FreeBSD kernel and kernel does restore
-		 * back FS selector and base of user before returning to
-		 * userland.
-		 *
-		 * Note: You can't use 'curcpu' which uses pcpu.
+		 * The host GDTR and IDTR is saved by VMRUN and restored
+		 * automatically on #VMEXIT. However, the host TSS needs
+		 * to be restored explicitly.
 		 */
-		wrmsr(MSR_GSBASE, (uint64_t)&__pcpu[vcpustate->lastcpu]);
-		wrmsr(MSR_KGSBASE, (uint64_t)&__pcpu[vcpustate->lastcpu]);
+		restore_host_tss();
 
 		/* #VMEXIT disables interrupts so re-enable them here. */ 
 		enable_gintr();


More information about the svn-src-projects mailing list