Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 11 Jun 2014 17:48:07 +0000 (UTC)
From:      Neel Natu <neel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r267367 - projects/bhyve_svm/sys/amd64/vmm/amd
Message-ID:  <201406111748.s5BHm7Ob004175@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: neel
Date: Wed Jun 11 17:48:07 2014
New Revision: 267367
URL: http://svnweb.freebsd.org/changeset/base/267367

Log:
  Disable global interrupts early so all the software state maintained by bhyve
  is sampled "atomically". Any interrupts after this point will be held pending
  by the CPU until the guest starts executing and will immediately trigger a
  #VMEXIT.
  
  Reviewed by:	Anish Gupta (akgupt3@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	Wed Jun 11 17:19:57 2014	(r267366)
+++ projects/bhyve_svm/sys/amd64/vmm/amd/svm.c	Wed Jun 11 17:48:07 2014	(r267367)
@@ -1156,22 +1156,24 @@ svm_vmrun(void *arg, int vcpu, register_
 	
 	do {
 		vmexit->inst_length = 0;
-		 /* We are asked to give the cpu by scheduler. */
-		if (curthread->td_flags & (TDF_ASTPENDING | TDF_NEEDRESCHED)) {
-			vmexit->exitcode = VM_EXITCODE_BOGUS;
-			vmm_stat_incr(vm, vcpu, VMEXIT_ASTPENDING, 1);
-			VCPU_CTR1(vm, vcpu, 
-				"SVM: ASTPENDING, RIP:0x%lx\n", state->rip);
-			vmexit->rip = state->rip;
-			break;
-		}
+
+		/*
+		 * Disable global interrupts to guarantee atomicity during
+		 * loading of guest state. This includes not only the state
+		 * loaded by the "vmrun" instruction but also software state
+		 * maintained by the hypervisor: suspended and rendezvous
+		 * state, NPT generation number, vlapic interrupts etc.
+		 */
+		disable_gintr();
 
 		if (vcpu_suspended(suspended_cookie)) {
+			enable_gintr();
 			vm_exit_suspended(vm, vcpu, state->rip);
 			break;
 		}
 
 		if (vcpu_rendezvous_pending(rend_cookie)) {
+			enable_gintr();
 			vmexit->exitcode = VM_EXITCODE_RENDEZVOUS;
 			vmm_stat_incr(vm, vcpu, VMEXIT_RENDEZVOUS, 1);
 			VCPU_CTR1(vm, vcpu, 
@@ -1181,32 +1183,36 @@ svm_vmrun(void *arg, int vcpu, register_
 			break;
 		}
 
+		/* We are asked to give the cpu by scheduler. */
+		if (curthread->td_flags & (TDF_ASTPENDING | TDF_NEEDRESCHED)) {
+			enable_gintr();
+			vmexit->exitcode = VM_EXITCODE_BOGUS;
+			vmm_stat_incr(vm, vcpu, VMEXIT_ASTPENDING, 1);
+			VCPU_CTR1(vm, vcpu, 
+				"SVM: ASTPENDING, RIP:0x%lx\n", state->rip);
+			vmexit->rip = state->rip;
+			break;
+		}
+
 		(void)svm_set_vmcb(svm_get_vmcb(svm_sc, vcpu), svm_sc->asid);
-		
+
 		svm_handle_exitintinfo(svm_sc, vcpu);
-		
+
 		(void)svm_inj_interrupts(svm_sc, vcpu, vlapic);
-	
+
 		/* Change TSS type to available.*/
 		setup_tss_type();
 
-		/*
-		 * Disable global interrupt to guarantee atomicity
-		 * during loading of guest state.
-		 * See 15.5.1 "Loading guest state" APM2.
-		 */	
-		disable_gintr();
-
 		/* 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.
 		 */
 		ltr(GSEL(GPROC0_SEL, SEL_KPL));
-		
+
 		/*
 		 * Guest FS and GS selector are stashed by vmload and vmsave.
 		 * Host FS and GS selector are stashed by svm_launch().
@@ -1220,15 +1226,14 @@ svm_vmrun(void *arg, int vcpu, register_
 		 */
 		wrmsr(MSR_GSBASE, (uint64_t)&__pcpu[vcpustate->lastcpu]);
 		wrmsr(MSR_KGSBASE, (uint64_t)&__pcpu[vcpustate->lastcpu]);
-		
-		/* vcpu exit with glbal interrupt disabled. */
+
+		/* #VMEXIT disables interrupts so re-enable them here. */ 
 		enable_gintr();
-		
+
 		/* Handle #VMEXIT and if required return to user space. */
 		loop = svm_vmexit(svm_sc, vcpu, vmexit);
 		vcpustate->loop++;
 		vmm_stat_incr(vm, vcpu, VMEXIT_COUNT, 1);
-
 	} while (loop);
 		
 	return (0);



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