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

Peter Grehan grehan at FreeBSD.org
Wed Oct 16 05:43:03 UTC 2013


Author: grehan
Date: Wed Oct 16 05:43:03 2013
New Revision: 256588
URL: http://svnweb.freebsd.org/changeset/base/256588

Log:
  Fix SVM handling of ASTPENDING, which manifested as a
  hang on console output (due to a missing interrupt).
  
  SVM does exit processing and then handles ASTPENDING which
  overwrites the already handled SVM exit cause and corrupts
  virtual machine state. For example, if the SVM exit was due to
  an I/O port access but the main loop detected an ASTPENDING,
  the exit would be processed as ASTPENDING and leave the
  device (e.g. emulated UART) for that I/O port in bad state.
  
  Submitted by:	Anish Gupta (akgupt3 at gmail.com)
  Reviewed by:	grehan

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 Oct 16 05:02:01 2013	(r256587)
+++ projects/bhyve_svm/sys/amd64/vmm/amd/svm.c	Wed Oct 16 05:43:03 2013	(r256588)
@@ -678,6 +678,8 @@ svm_vmexit(struct svm_softc *svm_sc, int
 		case VMCB_EXIT_IO:
 			vmm_stat_incr(svm_sc->vm, vcpu, VMEXIT_INOUT, 1);
 			user = svm_handle_io(svm_sc, vcpu, vmexit);
+			VMM_CTR1(svm_sc->vm, vcpu, "SVM:I/O VMEXIT RIP:0x%lx\n",
+				state->rip);
 			break;
 
 		case VMCB_EXIT_CPUID:
@@ -691,7 +693,7 @@ svm_vmexit(struct svm_softc *svm_sc, int
 			user = 0;
 			break;
 
-			case VMCB_EXIT_HLT:
+		case VMCB_EXIT_HLT:
 			vmm_stat_incr(svm_sc->vm, vcpu, VMEXIT_HLT, 1);
  			if (ctrl->v_irq) {
 				 /* Interrupt is pending, can't halt guest. */
@@ -709,7 +711,7 @@ svm_vmexit(struct svm_softc *svm_sc, int
 			}
 			break;
 
-			case VMCB_EXIT_PAUSE:
+		case VMCB_EXIT_PAUSE:
 			VMM_CTR0(svm_sc->vm, vcpu, "SVM:VMEXIT pause");
 			vmexit->exitcode = VM_EXITCODE_PAUSE;
 			vmm_stat_incr(svm_sc->vm, vcpu, VMEXIT_PAUSE, 1);
@@ -975,7 +977,19 @@ svm_vmrun(void *arg, int vcpu, register_
 	/* Update Guest RIP */
 	state->rip = rip;
 	
+	VMM_CTR1(svm_sc->vm, vcpu, "SVM:entered with RIP:0x%lx\n", 
+		state->rip);
 	do {
+		 /* We are asked to give the cpu by scheduler. */
+		if (curthread->td_flags & (TDF_ASTPENDING | TDF_NEEDRESCHED)) {
+			vmexit->exitcode = VM_EXITCODE_BOGUS;
+			vmexit->inst_length = 0;
+			vmm_stat_incr(svm_sc->vm, vcpu, VMEXIT_ASTPENDING, 1);
+			VMM_CTR1(svm_sc->vm, vcpu, "SVM:gave up cpu, RIP:0x%lx\n", 
+				state->rip);
+			break;
+		}
+
 		lapic_timer_tick(svm_sc->vm, vcpu);
 		
 		(void)svm_set_vmcb(svm_get_vmcb(svm_sc, vcpu), svm_sc->asid);
@@ -1022,7 +1036,6 @@ 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. */
 		enable_gintr();
 		
@@ -1031,16 +1044,13 @@ svm_vmrun(void *arg, int vcpu, register_
 		vcpustate->loop++;
 		vmm_stat_incr(svm_sc->vm, vcpu, VMEXIT_COUNT, 1);
 
-		 /* We are asked to give the cpud by scheduler.*/
-		if (curthread->td_flags & (TDF_ASTPENDING | TDF_NEEDRESCHED)) {
-			vmexit->exitcode = VM_EXITCODE_BOGUS;
-			vmexit->inst_length = 0;
-			break;
-		}
-
 		/* Update RIP since we are continuing vcpu execution.*/
 		state->rip = vmexit->rip;
+
+		VMM_CTR1(svm_sc->vm, vcpu, "SVM:loop RIP:0x%lx\n", state->rip); 
 	} while (!user);
+	VMM_CTR1(svm_sc->vm, vcpu, "SVM:exited with RIP:0x%lx\n", 
+		state->rip);
 		
 	return (0);
 }
@@ -1260,7 +1270,7 @@ svm_setcap(void *arg, int vcpu, int type
 	ctrl = svm_get_vmcb_ctrl(svm_sc, vcpu);
 
 	switch (type) {
-	case VM_CAP_HALT_EXIT:
+		case VM_CAP_HALT_EXIT:
 			if (val)
 				ctrl->ctrl1 |= VMCB_INTCPT_HLT;
 			else


More information about the svn-src-projects mailing list