The branch main has been updated by corvink:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=0912408a281f203c43d0b3f73c38117336588342

commit 0912408a281f203c43d0b3f73c38117336588342
Author:     Vitaliy Gusev <[email protected]>
AuthorDate: 2023-04-26 08:17:50 +0000
Commit:     Corvin Köhne <[email protected]>
CommitDate: 2023-04-26 08:38:46 +0000

    vmm: fix HLT loop while vcpu has requested virtual interrupts
    
    This fixes the detection of pending interrupts when pirval is 0 and the
    pending bit is set
    
    More information how this situation occurs, can be found here:
    
https://github.com/freebsd/freebsd-src/blob/c5b5f2d8086f540fefe4826da013dd31d4e45fe8/sys/amd64/vmm/intel/vmx.c#L4016-L4031
    
    Reviewed by:            corvink, markj
    Fixes:                  02cc877968bbcd57695035c67114a67427f54549 
("Recognize a pending virtual interrupt while emulating the halt instruction.")
    MFC after:              1 week
    Sponsored by:           vStack
    Differential Revision:  https://reviews.freebsd.org/D39620
---
 sys/amd64/vmm/intel/vmx.c | 44 +++++++++++++++++++-------------------------
 1 file changed, 19 insertions(+), 25 deletions(-)

diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c
index 91406f0614ce..32e53de4e8ee 100644
--- a/sys/amd64/vmm/intel/vmx.c
+++ b/sys/amd64/vmm/intel/vmx.c
@@ -3763,7 +3763,8 @@ vmx_pending_intr(struct vlapic *vlapic, int *vecptr)
        struct pir_desc *pir_desc;
        struct LAPIC *lapic;
        uint64_t pending, pirval;
-       uint32_t ppr, vpr;
+       uint8_t ppr, vpr, rvi;
+       struct vm_exit *vmexit;
        int i;
 
        /*
@@ -3774,31 +3775,26 @@ vmx_pending_intr(struct vlapic *vlapic, int *vecptr)
 
        vlapic_vtx = (struct vlapic_vtx *)vlapic;
        pir_desc = vlapic_vtx->pir_desc;
+       lapic = vlapic->apic_page;
 
-       pending = atomic_load_acq_long(&pir_desc->pending);
-       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->vcpu);
-               KASSERT(vmexit->exitcode == VM_EXITCODE_HLT,
-                   ("vmx_pending_intr: exitcode not 'HLT'"));
-               rvi = vmexit->u.hlt.intr_status & APIC_TPR_INT;
-               lapic = vlapic->apic_page;
-               ppr = lapic->ppr & APIC_TPR_INT;
-               if (rvi > ppr) {
-                       return (1);
-               }
+       /*
+        * 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 30.2.1 in the Intel SDM Volume 3.
+        */
+       vmexit = vm_exitinfo(vlapic->vcpu);
+       KASSERT(vmexit->exitcode == VM_EXITCODE_HLT,
+           ("vmx_pending_intr: exitcode not 'HLT'"));
+       rvi = vmexit->u.hlt.intr_status & APIC_TPR_INT;
+       ppr = lapic->ppr & APIC_TPR_INT;
+       if (rvi > ppr)
+               return (1);
 
+       pending = atomic_load_acq_long(&pir_desc->pending);
+       if (!pending)
                return (0);
-       }
 
        /*
         * If there is an interrupt pending then it will be recognized only
@@ -3807,8 +3803,6 @@ vmx_pending_intr(struct vlapic *vlapic, int *vecptr)
         * Special case: if the processor priority is zero then any pending
         * interrupt will be recognized.
         */
-       lapic = vlapic->apic_page;
-       ppr = lapic->ppr & APIC_TPR_INT;
        if (ppr == 0)
                return (1);
 

Reply via email to