Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 4 May 2019 00:56:47 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r347073 - stable/11/sys/amd64/vmm/intel
Message-ID:  <201905040056.x440ulAM004347@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Sat May  4 00:56:47 2019
New Revision: 347073
URL: https://svnweb.freebsd.org/changeset/base/347073

Log:
  MFC 327065:
  Recognize a pending virtual interrupt while emulating the halt instruction.

Modified:
  stable/11/sys/amd64/vmm/intel/vmx.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/amd64/vmm/intel/vmx.c
==============================================================================
--- stable/11/sys/amd64/vmm/intel/vmx.c	Fri May  3 23:07:07 2019	(r347072)
+++ stable/11/sys/amd64/vmm/intel/vmx.c	Sat May  4 00:56:47 2019	(r347073)
@@ -3361,9 +3361,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.
@@ -3372,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);
 
@@ -3383,7 +3403,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;
 			break;
 		}
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201905040056.x440ulAM004347>