VirtualBox

Changeset 89620 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Jun 11, 2021 8:51:10 AM (4 years ago)
Author:
vboxsync
Message:

Intel IOMMU: bugref:9967 Allow PDMIoApicSetEoi operation to be queued to ring-3 if I/O APIC isn't available in R0.
This key change is taking the PDM lock such that it doesn't fail (VINF_SUCCESS instead of VINF_IOM_R3_MMIO_WRITE for rcBusy, which wouldn't have worked anyway when called via APICHvSetEoi for instance).
Also cleaned up the prototype of PDMIoApicSendMsi a bit (use PVMCC instead of PPDMDEVINS).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/DevIoApic.cpp

    r89098 r89620  
    313313    /** Number of IOMMU denied or failed MSIs. */
    314314    STAMCOUNTER             StatIommuDiscardedMsi;
    315     /** Number of returns to ring-3 due to EOI broadcast lock contention. */
    316     STAMCOUNTER             StatEoiContention;
    317315    /** Number of returns to ring-3 due to Set RTE lock contention. */
    318316    STAMCOUNTER             StatSetRteContention;
     
    845843 * @interface_method_impl{PDMIOAPICREG,pfnSetEoi}
    846844 */
    847 static DECLCALLBACK(VBOXSTRICTRC) ioapicSetEoi(PPDMDEVINS pDevIns, uint8_t u8Vector)
     845static DECLCALLBACK(void) ioapicSetEoi(PPDMDEVINS pDevIns, uint8_t u8Vector)
    848846{
    849847    PIOAPIC   pThis   = PDMDEVINS_2_DATA(pDevIns, PIOAPIC);
    850848    PIOAPICCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PIOAPICCC);
     849
     850    LogFlow(("IOAPIC: ioapicSetEoi: u8Vector=%#x (%u)\n", u8Vector, u8Vector));
    851851    STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatSetEoi));
    852     LogFlow(("IOAPIC: ioapicSetEoi: u8Vector=%#x (%u)\n", u8Vector, u8Vector));
    853852
    854853    bool fRemoteIrrCleared = false;
    855     VBOXSTRICTRC rc = IOAPIC_LOCK(pDevIns, pThis, pThisCC, VINF_IOM_R3_MMIO_WRITE);
    856     if (rc == VINF_SUCCESS)
    857     {
    858         for (uint8_t idxRte = 0; idxRte < RT_ELEMENTS(pThis->au64RedirTable); idxRte++)
     854    int rc = IOAPIC_LOCK(pDevIns, pThis, pThisCC, VINF_SUCCESS);
     855    AssertRC(rc);
     856
     857    for (uint8_t idxRte = 0; idxRte < RT_ELEMENTS(pThis->au64RedirTable); idxRte++)
     858    {
     859        uint64_t const u64Rte = pThis->au64RedirTable[idxRte];
     860        if (IOAPIC_RTE_GET_VECTOR(u64Rte) == u8Vector)
    859861        {
    860             uint64_t const u64Rte = pThis->au64RedirTable[idxRte];
    861             if (IOAPIC_RTE_GET_VECTOR(u64Rte) == u8Vector)
    862             {
    863862#ifdef DEBUG_ramshankar
    864                 /* This assertion may trigger when restoring saved-states created using the old, incorrect I/O APIC code. */
    865                 Assert(IOAPIC_RTE_GET_REMOTE_IRR(u64Rte));
     863            /* This assertion may trigger when restoring saved-states created using the old, incorrect I/O APIC code. */
     864            Assert(IOAPIC_RTE_GET_REMOTE_IRR(u64Rte));
    866865#endif
    867                 pThis->au64RedirTable[idxRte] &= ~IOAPIC_RTE_REMOTE_IRR;
    868                 fRemoteIrrCleared = true;
    869                 STAM_COUNTER_INC(&pThis->StatEoiReceived);
    870                 Log2(("IOAPIC: ioapicSetEoi: Cleared remote IRR, idxRte=%u vector=%#x (%u)\n", idxRte, u8Vector, u8Vector));
    871 
    872                 /*
    873                  * Signal the next pending interrupt for this RTE.
    874                  */
    875                 uint32_t const uPinMask = UINT32_C(1) << idxRte;
    876                 if (pThis->uIrr & uPinMask)
    877                     ioapicSignalIntrForRte(pDevIns, pThis, pThisCC, idxRte);
    878             }
     866            pThis->au64RedirTable[idxRte] &= ~IOAPIC_RTE_REMOTE_IRR;
     867            fRemoteIrrCleared = true;
     868            STAM_COUNTER_INC(&pThis->StatEoiReceived);
     869            Log2(("IOAPIC: ioapicSetEoi: Cleared remote IRR, idxRte=%u vector=%#x (%u)\n", idxRte, u8Vector, u8Vector));
     870
     871            /*
     872             * Signal the next pending interrupt for this RTE.
     873             */
     874            uint32_t const uPinMask = UINT32_C(1) << idxRte;
     875            if (pThis->uIrr & uPinMask)
     876                ioapicSignalIntrForRte(pDevIns, pThis, pThisCC, idxRte);
    879877        }
    880 
    881         IOAPIC_UNLOCK(pDevIns, pThis, pThisCC);
     878    }
     879
     880    IOAPIC_UNLOCK(pDevIns, pThis, pThisCC);
     881
    882882#ifndef VBOX_WITH_IOMMU_AMD
    883         AssertMsg(fRemoteIrrCleared, ("Failed to clear remote IRR for vector %#x (%u)\n", u8Vector, u8Vector));
     883    AssertMsg(fRemoteIrrCleared, ("Failed to clear remote IRR for vector %#x (%u)\n", u8Vector, u8Vector));
    884884#endif
    885     }
    886     else
    887         STAM_COUNTER_INC(&pThis->StatEoiContention);
    888 
    889     return rc;
    890885}
    891886
     
    11191114        case IOAPIC_DIRECT_OFF_EOI:
    11201115            if (pThis->u8ApicVer == IOAPIC_VERSION_ICH9)
    1121                 rc = ioapicSetEoi(pDevIns, uValue);
     1116                ioapicSetEoi(pDevIns, uValue);
    11221117            else
    11231118                Log(("IOAPIC: ioapicMmioWrite: Write to EOI register ignored!\n"));
     
    16681663    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatIommuDiscardedMsi,  STAMTYPE_COUNTER, "Iommu/DiscardedMsi",  STAMUNIT_OCCURENCES, "Number of MSIs discarded by the IOMMU.");
    16691664
    1670     PDMDevHlpSTAMRegister(pDevIns, &pThis->StatEoiContention,    STAMTYPE_COUNTER, "CritSect/ContentionSetEoi", STAMUNIT_OCCURENCES, "Number of times the critsect is busy during EOI writes causing trips to R3.");
    16711665    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatSetRteContention, STAMTYPE_COUNTER, "CritSect/ContentionSetRte", STAMUNIT_OCCURENCES, "Number of times the critsect is busy during RTE writes causing trips to R3.");
    16721666
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