VirtualBox

Changeset 89028 in vbox for trunk/src/VBox/Devices/Bus


Ignore:
Timestamp:
May 13, 2021 6:15:39 AM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
144367
Message:

Intel IOMMU: bugref:9967 Handle cases when the invalidation complete event interrupt is masked but unmasked later.
I'm not entire sure if the MSI message can be cached at the time the event was made pending or if the active IEADDR_REG and IEDATA_REG values
can be used to reconstruct the MSI. Using the latter for now.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Bus/DevIommuIntel.cpp

    r89007 r89028  
    11881188    uint32_t const uIcsReg = dmarRegReadRaw32(pThis, VTD_MMIO_OFF_ICS_REG);
    11891189    if (!(uIcsReg & VTD_BF_ICS_REG_IWC_MASK))
     1190    {
     1191        dmarRegChangeRaw32(pThis, VTD_MMIO_OFF_ICS_REG, UINT32_MAX, VTD_BF_ICS_REG_IWC_MASK);
    11901192        dmarEventRaiseInterrupt(pDevIns, DMAREVENTTYPE_INV_COMPLETE);
     1193    }
    11911194}
    11921195#endif /* IN_RING3 */
     
    13981401    }
    13991402
    1400     /** @todo Rest of the bits. */
     1403    /* Translation (DMA remapping). */
     1404    if (fChanged & VTD_BF_GCMD_REG_TE_MASK)
     1405    {
     1406        if (uGcmdReg & VTD_BF_GCMD_REG_TE_MASK)
     1407            dmarRegChangeRaw32(pThis, VTD_MMIO_OFF_GSTS_REG, UINT32_MAX, VTD_BF_GSTS_REG_TES_MASK);
     1408        else
     1409            dmarRegChangeRaw32(pThis, VTD_MMIO_OFF_GSTS_REG, ~VTD_BF_GSTS_REG_TES_MASK, 0 /* fOrMask */);
     1410    }
    14011411
    14021412    return VINF_SUCCESS;
     
    15151525    /* else: 128-bit descriptor width is validated lazily, see explanation in dmarR3InvQueueProcessRequests. */
    15161526
     1527    return VINF_SUCCESS;
     1528}
     1529
     1530
     1531/**
     1532 * Handles writes to ICS_REG.
     1533 *
     1534 * @returns Strict VBox status code.
     1535 * @param   pDevIns     The IOMMU device instance.
     1536 * @param   uIcsReg     The value written to ICS_REG.
     1537 */
     1538static VBOXSTRICTRC dmarIcsRegWrite(PPDMDEVINS pDevIns, uint32_t uIcsReg)
     1539{
     1540    /*
     1541     * If the IP field is set when software services the interrupt condition,
     1542     * (by clearing the IWC field), the IP field must be cleared.
     1543     */
     1544    if (!(uIcsReg & VTD_BF_ICS_REG_IWC_MASK))
     1545    {
     1546        PDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PDMAR);
     1547        dmarRegChangeRaw32(pThis, VTD_MMIO_OFF_IECTL_REG, ~VTD_BF_IECTL_REG_IP_MASK, 0 /* fOrMask */);
     1548    }
     1549    return VINF_SUCCESS;
     1550}
     1551
     1552
     1553/**
     1554 * Handles writes to IECTL_REG.
     1555 *
     1556 * @returns Strict VBox status code.
     1557 * @param   pDevIns     The IOMMU device instance.
     1558 * @param   uIectlReg   The value written to IECTL_REG.
     1559 */
     1560static VBOXSTRICTRC dmarIectlRegWrite(PPDMDEVINS pDevIns, uint32_t uIectlReg)
     1561{
     1562    /*
     1563     * If software unmasks the interrupt when the interrupt is pending, we must raise
     1564     * the interrupt now (which will consequently clear the interrupt pending bit).
     1565     */
     1566    if (    (uIectlReg & VTD_BF_IECTL_REG_IP_MASK)
     1567        && ~(uIectlReg & VTD_BF_IECTL_REG_IM_MASK))
     1568        dmarEventRaiseInterrupt(pDevIns, DMAREVENTTYPE_INV_COMPLETE);
    15171569    return VINF_SUCCESS;
    15181570}
     
    18651917            {
    18661918                rcStrict = dmarIqaRegWrite(pDevIns, offReg, uRegWritten);
     1919                break;
     1920            }
     1921
     1922            case VTD_MMIO_OFF_ICS_REG:        /* 32-bit */
     1923            {
     1924                rcStrict = dmarIcsRegWrite(pDevIns, uRegWritten);
     1925                break;
     1926            }
     1927
     1928            case VTD_MMIO_OFF_IECTL_REG:        /* 32-bit */
     1929            {
     1930                rcStrict = dmarIectlRegWrite(pDevIns, uRegWritten);
    18671931                break;
    18681932            }
     
    24142478    {
    24152479        uint8_t const fCfi = RT_BF_GET(uGcmdReg, VTD_BF_GCMD_REG_CFI);
    2416         pHlp->pfnPrintf(pHlp, "   CFI          = %u (%s)\n", fCfi, fCfi ? "Bypass" : "Block");
     2480        pHlp->pfnPrintf(pHlp, "   CFI          = %u (%s)\n", fCfi, fCfi ? "Passthrough" : "Blocked");
    24172481        pHlp->pfnPrintf(pHlp, "   SIRTP        = %u\n", RT_BF_GET(uGcmdReg, VTD_BF_GCMD_REG_SIRTP));
    24182482        pHlp->pfnPrintf(pHlp, "   IRE          = %u\n", RT_BF_GET(uGcmdReg, VTD_BF_GCMD_REG_IRE));
     
    24272491    {
    24282492        uint8_t const fCfis = RT_BF_GET(uGstsReg, VTD_BF_GSTS_REG_CFIS);
    2429         pHlp->pfnPrintf(pHlp, "   CFIS         = %u (%s)\n", fCfis, fCfis ? "Bypass" : "Block");
     2493        pHlp->pfnPrintf(pHlp, "   CFIS         = %u (%s)\n", fCfis, fCfis ? "Passthrough" : "Blocked");
    24302494        pHlp->pfnPrintf(pHlp, "   IRTPS        = %u\n", RT_BF_GET(uGstsReg, VTD_BF_GSTS_REG_IRTPS));
    24312495        pHlp->pfnPrintf(pHlp, "   IRES         = %u\n", RT_BF_GET(uGstsReg, VTD_BF_GSTS_REG_IRES));
     
    24402504    {
    24412505        uint8_t const uTtm = RT_BF_GET(uRtaddrReg, VTD_BF_RTADDR_REG_TTM);
     2506        pHlp->pfnPrintf(pHlp, "   RTA          = %#RX64\n",   uRtaddrReg & VTD_BF_RTADDR_REG_RTA_MASK);
    24422507        pHlp->pfnPrintf(pHlp, "   TTM          = %u (%s)\n",  uTtm, vtdRtaddrRegGetTtmDesc(uTtm));
    2443         pHlp->pfnPrintf(pHlp, "   RTA          = %#RX64\n",   RT_BF_GET(uRtaddrReg, VTD_BF_RTADDR_REG_RTA));
    24442508    }
    24452509    pHlp->pfnPrintf(pHlp, " CCMD_REG     = %#RX64\n", uCcmdReg);
     
    25012565        uint32_t const cIrtEntries = VTD_IRTA_REG_GET_ENTRY_COUNT(uIrtaReg);
    25022566        uint32_t const cbIrt       = sizeof(VTD_IRTE_T) * cIrtEntries;
    2503         pHlp->pfnPrintf(pHlp, "   IRTA         = %#RX64\n",   RT_BF_GET(uIrtaReg, VTD_BF_IRTA_REG_IRTA));
     2567        pHlp->pfnPrintf(pHlp, "   IRTA         = %#RX64\n",   uIrtaReg & VTD_BF_IRTA_REG_IRTA_MASK);
    25042568        pHlp->pfnPrintf(pHlp, "   EIME         = %RTbool\n",  RT_BF_GET(uIrtaReg, VTD_BF_IRTA_REG_EIME));
    25052569        pHlp->pfnPrintf(pHlp, "   S            = %u entries (%u bytes)\n", cIrtEntries, cbIrt);
     
    25792643                       | RT_BF_MAKE(VTD_BF_CAP_REG_PLMR,    0)     /* Protected Low-Memory Region not supported. */
    25802644                       | RT_BF_MAKE(VTD_BF_CAP_REG_PHMR,    0)     /* Protected High-Memory Region not supported. */
    2581                        | RT_BF_MAKE(VTD_BF_CAP_REG_CM,      1)     /** @todo Figure out if required when we impl. caching. */
     2645                       | RT_BF_MAKE(VTD_BF_CAP_REG_CM,      1)     /* Software should invalidate on mapping structure changes. */
    25822646                       | RT_BF_MAKE(VTD_BF_CAP_REG_SAGAW,   fSlts & uSagaw)
    25832647                       | RT_BF_MAKE(VTD_BF_CAP_REG_MGAW,    uMgaw)
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