Date: Thu, 21 Dec 2017 18:30:11 +0000 (UTC) From: Tycho Nightingale <tychon@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r327065 - head/sys/amd64/vmm/intel Message-ID: <201712211830.vBLIUBYE075062@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: tychon Date: Thu Dec 21 18:30:11 2017 New Revision: 327065 URL: https://svnweb.freebsd.org/changeset/base/327065 Log: Recognize a pending virtual interrupt while emulating the halt instruction. Reviewed by: grehan, rgrimes Sponsored by: Dell EMC Isilon Differential Revision: https://reviews.freebsd.org/D13573 Modified: head/sys/amd64/vmm/intel/vmx.c Modified: head/sys/amd64/vmm/intel/vmx.c ============================================================================== --- head/sys/amd64/vmm/intel/vmx.c Thu Dec 21 16:25:33 2017 (r327064) +++ head/sys/amd64/vmm/intel/vmx.c Thu Dec 21 18:30:11 2017 (r327065) @@ -3174,9 +3174,29 @@ vmx_pending_intr(struct vlapic *vlapic, int *vecptr) pir_desc = vlapic_vtx->pir_desc; pending = atomic_load_acq_long(&pir_desc->pending); - if (!pending) - return (0); /* common case */ + if (!pending) { + /* + * While a virtual interrupt may have already been + * processed the actual delivery maybe pending the + * interruptibility of the guest. Recognize a pending + * interrupt by reevaluating virtual interrupts + * following Section 29.2.1 in the Intel SDM Volume 3. + */ + uint64_t val; + uint8_t rvi, ppr; + vmx_getreg(vlapic_vtx->vmx, vlapic->vcpuid, + VMCS_IDENT(VMCS_GUEST_INTR_STATUS), &val); + rvi = val & APIC_TPR_INT; + lapic = vlapic->apic_page; + ppr = lapic->ppr & APIC_TPR_INT; + if (rvi > ppr) { + return (1); + } + + return (0); + } + /* * If there is an interrupt pending then it will be recognized only * if its priority is greater than the processor priority. @@ -3185,7 +3205,7 @@ vmx_pending_intr(struct vlapic *vlapic, int *vecptr) * interrupt will be recognized. */ lapic = vlapic->apic_page; - ppr = lapic->ppr & 0xf0; + ppr = lapic->ppr & APIC_TPR_INT; if (ppr == 0) return (1); @@ -3195,7 +3215,7 @@ vmx_pending_intr(struct vlapic *vlapic, int *vecptr) for (i = 3; i >= 0; i--) { pirval = pir_desc->pir[i]; if (pirval != 0) { - vpr = (i * 64 + flsl(pirval) - 1) & 0xf0; + vpr = (i * 64 + flsl(pirval) - 1) & APIC_TPR_INT; return (vpr > ppr); } }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201712211830.vBLIUBYE075062>