VirtualBox

Changeset 61847 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Jun 23, 2016 12:03:01 PM (9 years ago)
Author:
vboxsync
Message:

IOAPIC, VMM/APIC: Use dedicated rc for when the APIC doesn't accept an IRQ (very rare but can happen).
Also added more stats, assertions to verify interrupt delivery a bit better.

Location:
trunk/src/VBox/VMM
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/APICAll.cpp

    r61807 r61847  
    598598 * @param   enmDeliveryMode     The delivery mode.
    599599 * @param   pDestCpuSet         The destination CPU set.
     600 * @param   pfIntrAccepted      Where to store whether this interrupt was
     601 *                              accepted by the target APIC(s) or not.
     602 *                              Optional, can be NULL.
    600603 * @param   rcRZ                The return code if the operation cannot be
    601604 *                              performed in the current context.
    602605 */
    603606static VBOXSTRICTRC apicSendIntr(PVM pVM, PVMCPU pVCpu, uint8_t uVector, XAPICTRIGGERMODE enmTriggerMode,
    604                                  XAPICDELIVERYMODE enmDeliveryMode, PCVMCPUSET pDestCpuSet, int rcRZ)
    605 {
    606     VBOXSTRICTRC  rcStrict = VINF_SUCCESS;
    607     VMCPUID const cCpus    = pVM->cCpus;
     607                                 XAPICDELIVERYMODE enmDeliveryMode, PCVMCPUSET pDestCpuSet, bool *pfIntrAccepted, int rcRZ)
     608{
     609    VBOXSTRICTRC  rcStrict  = VINF_SUCCESS;
     610    VMCPUID const cCpus     = pVM->cCpus;
     611    bool          fAccepted = false;
    608612    switch (enmDeliveryMode)
    609613    {
     
    614618                if (   VMCPUSET_IS_PRESENT(pDestCpuSet, idCpu)
    615619                    && apicIsEnabled(&pVM->aCpus[idCpu]))
    616                     apicPostInterrupt(&pVM->aCpus[idCpu], uVector, enmTriggerMode);
     620                    fAccepted = apicPostInterrupt(&pVM->aCpus[idCpu], uVector, enmTriggerMode);
    617621            }
    618622            break;
     
    624628            if (   idCpu < pVM->cCpus
    625629                && apicIsEnabled(&pVM->aCpus[idCpu]))
    626                 apicPostInterrupt(&pVM->aCpus[idCpu], uVector, enmTriggerMode);
     630                fAccepted = apicPostInterrupt(&pVM->aCpus[idCpu], uVector, enmTriggerMode);
    627631            else
    628                 Log2(("APIC: apicSendIntr: No CPU found for lowest-priority delivery mode!\n"));
     632                AssertMsgFailed(("APIC: apicSendIntr: No CPU found for lowest-priority delivery mode!\n"));
    629633            break;
    630634        }
     
    638642                    Log2(("APIC: apicSendIntr: Raising SMI on VCPU%u\n", idCpu));
    639643                    apicSetInterruptFF(&pVM->aCpus[idCpu], PDMAPICIRQ_SMI);
     644                    fAccepted = true;
    640645                }
    641646            }
     
    652657                    Log2(("APIC: apicSendIntr: Raising NMI on VCPU%u\n", idCpu));
    653658                    apicSetInterruptFF(&pVM->aCpus[idCpu], PDMAPICIRQ_NMI);
     659                    fAccepted = true;
    654660                }
    655661            }
     
    665671                    Log2(("APIC: apicSendIntr: Issuing INIT to VCPU%u\n", idCpu));
    666672                    VMMR3SendInitIpi(pVM, idCpu);
     673                    fAccepted = true;
    667674                }
    668675#else
    669676            /* We need to return to ring-3 to deliver the INIT. */
    670677            rcStrict = rcRZ;
     678            fAccepted = true;
    671679#endif
    672680            break;
     
    681689                    Log2(("APIC: apicSendIntr: Issuing SIPI to VCPU%u\n", idCpu));
    682690                    VMMR3SendStartupIpi(pVM, idCpu, uVector);
     691                    fAccepted = true;
    683692                }
    684693#else
    685694            /* We need to return to ring-3 to deliver the SIPI. */
    686695            rcStrict = rcRZ;
     696            fAccepted = true;
    687697            Log2(("APIC: apicSendIntr: SIPI issued, returning to RZ. rc=%Rrc\n", rcRZ));
    688698#endif
     
    697707                    Log2(("APIC: apicSendIntr: Raising EXTINT on VCPU%u\n", idCpu));
    698708                    apicSetInterruptFF(&pVM->aCpus[idCpu], PDMAPICIRQ_EXTINT);
     709                    fAccepted = true;
    699710                }
    700711            break;
     
    735746        }
    736747    }
     748
     749    if (pfIntrAccepted)
     750        *pfIntrAccepted = fAccepted;
     751
    737752    return rcStrict;
    738753}
     
    10061021    }
    10071022
    1008     return apicSendIntr(pVCpu->CTX_SUFF(pVM), pVCpu, uVector, enmTriggerMode, enmDeliveryMode, &DestCpuSet, rcRZ);
     1023    return apicSendIntr(pVCpu->CTX_SUFF(pVM), pVCpu, uVector, enmTriggerMode, enmDeliveryMode, &DestCpuSet,
     1024                        NULL /* pfIntrAccepted */, rcRZ);
    10091025}
    10101026
     
    12541270        apicSignalNextPendingIntr(pVCpu);
    12551271    }
     1272    else
     1273        AssertMsgFailed(("APIC%u: apicSetEoi: Failed to find any ISR bit\n", pVCpu->idCpu));
    12561274
    12571275    return VINF_SUCCESS;
     
    22752293          uVector));
    22762294
     2295    bool     fIntrAccepted;
    22772296    VMCPUSET DestCpuSet;
    22782297    apicGetDestCpuSet(pVM, fDestMask, fBroadcastMask, enmDestMode, enmDeliveryMode, &DestCpuSet);
    22792298    VBOXSTRICTRC rcStrict = apicSendIntr(pVM, NULL /* pVCpu */, uVector, enmTriggerMode, enmDeliveryMode, &DestCpuSet,
    2280                                          VINF_SUCCESS /* rcRZ */);
    2281     return VBOXSTRICTRC_VAL(rcStrict);
     2299                                         &fIntrAccepted, VINF_SUCCESS /* rcRZ */);
     2300    if (fIntrAccepted)
     2301        return VBOXSTRICTRC_VAL(rcStrict);
     2302    return VERR_APIC_INTR_DISCARDED;
    22822303}
    22832304
     
    23792400                        VMCPUSET_ADD(&DestCpuSet, pVCpu->idCpu);
    23802401                        rcStrict = apicSendIntr(pVCpu->CTX_SUFF(pVM), pVCpu, uVector, enmTriggerMode, enmDeliveryMode,
    2381                                                 &DestCpuSet, rcRZ);
     2402                                                &DestCpuSet, NULL /* pfIntrAccepted */, rcRZ);
    23822403                    }
    23832404                    break;
     
    23922413                    uint8_t const uVector = XAPIC_LVT_GET_VECTOR(uLvt);
    23932414                    rcStrict = apicSendIntr(pVCpu->CTX_SUFF(pVM), pVCpu, uVector, enmTriggerMode, enmDeliveryMode, &DestCpuSet,
    2394                                             rcRZ);
     2415                                            NULL /* pfIntrAccepted */, rcRZ);
    23952416                    break;
    23962417                }
     
    26002621 * Don't use this function to try and deliver ExtINT style interrupts.
    26012622 *
     2623 * @returns true if the interrupt was accepted, false otherwise.
    26022624 * @param   pVCpu               The cross context virtual CPU structure.
    26032625 * @param   uVector             The vector of the interrupt to be posted.
     
    26062628 * @thread  Any.
    26072629 */
    2608 VMM_INT_DECL(void) apicPostInterrupt(PVMCPU pVCpu, uint8_t uVector, XAPICTRIGGERMODE enmTriggerMode)
     2630VMM_INT_DECL(bool) apicPostInterrupt(PVMCPU pVCpu, uint8_t uVector, XAPICTRIGGERMODE enmTriggerMode)
    26092631{
    26102632    Assert(pVCpu);
    26112633    Assert(uVector > XAPIC_ILLEGAL_VECTOR_END);
    26122634
    2613     PVM      pVM      = pVCpu->CTX_SUFF(pVM);
    2614     PCAPIC   pApic    = VM_TO_APIC(pVM);
    2615     PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
     2635    PVM      pVM       = pVCpu->CTX_SUFF(pVM);
     2636    PCAPIC   pApic     = VM_TO_APIC(pVM);
     2637    PAPICCPU pApicCpu  = VMCPU_TO_APICCPU(pVCpu);
     2638    bool     fAccepted = true;
    26162639
    26172640    STAM_PROFILE_START(&pApicCpu->StatPostIntr, a);
     
    26302653        if (!apicTestVectorInReg(&pXApicPage->irr, uVector))     /* PAV */
    26312654        {
    2632             Log2(("APIC: APICPostInterrupt: SrcCpu=%u TargetCpu=%u uVector=%#x\n", VMMGetCpuId(pVM), pVCpu->idCpu, uVector));
     2655            Log2(("APIC: apicPostInterrupt: SrcCpu=%u TargetCpu=%u uVector=%#x\n", VMMGetCpuId(pVM), pVCpu->idCpu, uVector));
    26332656            if (enmTriggerMode == XAPICTRIGGERMODE_EDGE)
    26342657            {
     
    26412664                    if (!fAlreadySet)
    26422665                    {
    2643                         Log2(("APIC: APICPostInterrupt: Setting UPDATE_APIC FF for edge-triggered intr. uVector=%#x\n", uVector));
     2666                        Log2(("APIC: apicPostInterrupt: Setting UPDATE_APIC FF for edge-triggered intr. uVector=%#x\n", uVector));
    26442667                        apicSetInterruptFF(pVCpu, PDMAPICIRQ_UPDATE_PENDING);
    26452668                    }
     
    26562679                if (!fAlreadySet)
    26572680                {
    2658                     Log2(("APIC: APICPostInterrupt: Setting UPDATE_APIC FF for level-triggered intr. uVector=%#x\n", uVector));
     2681                    Log2(("APIC: apicPostInterrupt: Setting UPDATE_APIC FF for level-triggered intr. uVector=%#x\n", uVector));
    26592682                    apicSetInterruptFF(pVCpu, PDMAPICIRQ_UPDATE_PENDING);
    26602683                }
     
    26632686        else
    26642687        {
    2665             Log2(("APIC: APICPostInterrupt: SrcCpu=%u TargetCpu=%u. Vector %#x Already in IRR, skipping\n", VMMGetCpuId(pVM),
     2688            Log2(("APIC: apicPostInterrupt: SrcCpu=%u TargetCpu=%u. Vector %#x Already in IRR, skipping\n", VMMGetCpuId(pVM),
    26662689                  pVCpu->idCpu, uVector));
    26672690            STAM_COUNTER_INC(&pApicCpu->StatPostIntrAlreadyPending);
     
    26692692    }
    26702693    else
     2694    {
     2695        fAccepted = false;
    26712696        apicSetError(pVCpu, XAPIC_ESR_RECV_ILLEGAL_VECTOR);
     2697    }
    26722698
    26732699    STAM_PROFILE_STOP(&pApicCpu->StatPostIntr, a);
     2700    return fAccepted;
    26742701}
    26752702
     
    28172844
    28182845    /* Update edge-triggered pending interrupts. */
     2846    PAPICPIB pPib = (PAPICPIB)pApicCpu->CTX_SUFF(pvApicPib);
    28192847    for (;;)
    28202848    {
     
    28232851            break;
    28242852
    2825         PAPICPIB pPib = (PAPICPIB)pApicCpu->CTX_SUFF(pvApicPib);
    28262853        AssertCompile(RT_ELEMENTS(pXApicPage->irr.u) == 2 * RT_ELEMENTS(pPib->aVectorBitmap));
    2827 
    28282854        for (size_t idxPib = 0, idxReg = 0; idxPib < RT_ELEMENTS(pPib->aVectorBitmap); idxPib++, idxReg += 2)
    28292855        {
     
    28452871
    28462872    /* Update level-triggered pending interrupts. */
     2873    pPib = (PAPICPIB)&pApicCpu->ApicPibLevel;
    28472874    for (;;)
    28482875    {
     
    28512878            break;
    28522879
    2853         PAPICPIB pPib = (PAPICPIB)&pApicCpu->ApicPibLevel;
    28542880        AssertCompile(RT_ELEMENTS(pXApicPage->irr.u) == 2 * RT_ELEMENTS(pPib->aVectorBitmap));
    2855 
    28562881        for (size_t idxPib = 0, idxReg = 0; idxPib < RT_ELEMENTS(pPib->aVectorBitmap); idxPib++, idxReg += 2)
    28572882        {
  • trunk/src/VBox/VMM/VMMAll/PDMAll.cpp

    r61685 r61847  
    6464     * The local APIC has a higher priority than the PIC.
    6565     */
     66    int rc = VERR_NO_DATA;
    6667    if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC))
    6768    {
     
    7172        uint32_t uTagSrc;
    7273        uint8_t  uVector;
    73         int rc = pVM->pdm.s.Apic.CTX_SUFF(pfnGetInterrupt)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, &uVector, &uTagSrc);
     74        rc = pVM->pdm.s.Apic.CTX_SUFF(pfnGetInterrupt)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, &uVector, &uTagSrc);
    7475        if (RT_SUCCESS(rc))
    7576        {
     
    119120
    120121    pdmUnlock(pVM);
    121     return VERR_NO_DATA;
     122    return rc;
    122123}
    123124
  • trunk/src/VBox/VMM/VMMR3/APIC.cpp

    r61812 r61847  
    17971797    } while(0)
    17981798
    1799     bool const fHasRC = !HMIsEnabled(pVM);
     1799    bool const fHasRC = !HMIsEnabledNotMacro(pVM);
    18001800    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
    18011801    {
  • trunk/src/VBox/VMM/include/APICInternal.h

    r61809 r61847  
    14421442                                             uint8_t uVector, uint8_t uPolarity, uint8_t uTriggerMode, uint32_t uTagSrc);
    14431443
    1444 VMM_INT_DECL(void)            apicPostInterrupt(PVMCPU pVCpu, uint8_t uVector, XAPICTRIGGERMODE enmTriggerMode);
     1444VMM_INT_DECL(bool)            apicPostInterrupt(PVMCPU pVCpu, uint8_t uVector, XAPICTRIGGERMODE enmTriggerMode);
    14451445VMM_INT_DECL(void)            apicStartTimer(PVMCPU pVCpu, uint32_t uInitialCount);
    14461446VMM_INT_DECL(void)            apicStopTimer(PVMCPU pVCpu);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette