svn commit: r339364 - head/sys/amd64/vmm/amd

John Baldwin jhb at FreeBSD.org
Mon Oct 15 18:12:26 UTC 2018


Author: jhb
Date: Mon Oct 15 18:12:25 2018
New Revision: 339364
URL: https://svnweb.freebsd.org/changeset/base/339364

Log:
  Reload the LDT selector after an AMD-v #VMEXIT.
  
  cpu_switch() always reloads the LDT, so this can only affect the
  hypervisor process itself.  Fix this by explicitly reloading the host
  LDT selector after each #VMEXIT.  The stock bhyve process on FreeBSD
  never uses a custom LDT, so this change is cosmetic.
  
  Reviewed by:	kib
  Tested by:	Mike Tancsa <mike at sentex.net>
  Approved by:	re (gjb)
  MFC after:	2 weeks

Modified:
  head/sys/amd64/vmm/amd/svm.c

Modified: head/sys/amd64/vmm/amd/svm.c
==============================================================================
--- head/sys/amd64/vmm/amd/svm.c	Mon Oct 15 17:50:02 2018	(r339363)
+++ head/sys/amd64/vmm/amd/svm.c	Mon Oct 15 18:12:25 2018	(r339364)
@@ -1940,6 +1940,7 @@ svm_vmrun(void *arg, int vcpu, register_t rip, pmap_t 
 	struct vm *vm;
 	uint64_t vmcb_pa;
 	int handled;
+	uint16_t ldt_sel;
 
 	svm_sc = arg;
 	vm = svm_sc->vm;
@@ -2024,6 +2025,15 @@ svm_vmrun(void *arg, int vcpu, register_t rip, pmap_t 
 			break;
 		}
 
+		/*
+		 * #VMEXIT resumes the host with the guest LDTR, so
+		 * save the current LDT selector so it can be restored
+		 * after an exit.  The userspace hypervisor probably
+		 * doesn't use a LDT, but save and restore it to be
+		 * safe.
+		 */
+		ldt_sel = sldt();
+
 		svm_inj_interrupts(svm_sc, vcpu, vlapic);
 
 		/* Activate the nested pmap on 'curcpu' */
@@ -2053,6 +2063,9 @@ svm_vmrun(void *arg, int vcpu, register_t rip, pmap_t 
 		 * to be restored explicitly.
 		 */
 		restore_host_tss();
+
+		/* Restore host LDTR. */
+		lldt(ldt_sel);
 
 		/* #VMEXIT disables interrupts so re-enable them here. */ 
 		enable_gintr();


More information about the svn-src-all mailing list