Date: Wed, 16 Oct 2013 05:43:03 +0000 (UTC) From: Peter Grehan <grehan@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r256588 - projects/bhyve_svm/sys/amd64/vmm/amd Message-ID: <201310160543.r9G5h37q087163@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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@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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201310160543.r9G5h37q087163>