summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Mooney <pmooney@pfmooney.com>2018-03-01 20:30:19 +0000
committerPatrick Mooney <pmooney@pfmooney.com>2018-03-14 21:48:37 +0000
commit9c78fec9bbf9d3887166ba5cb4678f16a7b5a47d (patch)
tree867ff09b722e78b730ad1898b352123fa67ef372
parentea521b0a8f47a63c4e2209c44b1fb8cce70e8474 (diff)
downloadillumos-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.c33
-rw-r--r--usr/src/uts/i86pc/sys/vmm.h1
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;