diff options
author | Patrick Mooney <pmooney@pfmooney.com> | 2018-03-01 20:30:19 +0000 |
---|---|---|
committer | Patrick Mooney <pmooney@pfmooney.com> | 2018-03-14 21:48:37 +0000 |
commit | 9c78fec9bbf9d3887166ba5cb4678f16a7b5a47d (patch) | |
tree | 867ff09b722e78b730ad1898b352123fa67ef372 | |
parent | ea521b0a8f47a63c4e2209c44b1fb8cce70e8474 (diff) | |
download | illumos-joyent-9c78fec9bbf9d3887166ba5cb4678f16a7b5a47d.tar.gz |
OS-6716 bhyve guest VCPUs pause intermittently
Reviewed by: John Levon <john.levon@joyent.com>
Reviewed by: Bryan Cantrill <bryan@joyent.com>
Approved by: Bryan Cantrill <bryan@joyent.com>
-rw-r--r-- | usr/src/uts/i86pc/io/vmm/intel/vmx.c | 33 | ||||
-rw-r--r-- | usr/src/uts/i86pc/sys/vmm.h | 1 |
2 files changed, 29 insertions, 5 deletions
diff --git a/usr/src/uts/i86pc/io/vmm/intel/vmx.c b/usr/src/uts/i86pc/io/vmm/intel/vmx.c index 71a4f7b0fc..f628e0b8ab 100644 --- a/usr/src/uts/i86pc/io/vmm/intel/vmx.c +++ b/usr/src/uts/i86pc/io/vmm/intel/vmx.c @@ -36,7 +36,7 @@ * http://www.illumos.org/license/CDDL. * * Copyright 2015 Pluribus Networks Inc. - * Copyright 2017 Joyent, Inc. + * Copyright 2018 Joyent, Inc. */ #include <sys/cdefs.h> @@ -2448,6 +2448,10 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit) vmm_stat_incr(vmx->vm, vcpu, VMEXIT_HLT, 1); vmexit->exitcode = VM_EXITCODE_HLT; vmexit->u.hlt.rflags = vmcs_read(VMCS_GUEST_RFLAGS); + if (virtual_interrupt_delivery) { + vmexit->u.hlt.intr_status = + vmcs_read(VMCS_GUEST_INTR_STATUS); + } break; case EXIT_REASON_MTF: vmm_stat_incr(vmx->vm, vcpu, VMEXIT_MTRAP, 1); @@ -3358,8 +3362,27 @@ 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. + */ + struct vm_exit *vmexit; + uint8_t rvi, ppr; + + vmexit = vm_exitinfo(vlapic->vm, vlapic->vcpuid); + rvi = vmexit->u.hlt.intr_status & 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 @@ -3369,7 +3392,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); @@ -3379,7 +3402,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); } } diff --git a/usr/src/uts/i86pc/sys/vmm.h b/usr/src/uts/i86pc/sys/vmm.h index ded10a79df..cc87b8df30 100644 --- a/usr/src/uts/i86pc/sys/vmm.h +++ b/usr/src/uts/i86pc/sys/vmm.h @@ -648,6 +648,7 @@ struct vm_exit { } spinup_ap; struct { uint64_t rflags; + uint64_t intr_status; } hlt; struct { int vector; |