VirtualBox

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


Ignore:
Timestamp:
May 27, 2021 5:50:20 AM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
144653
Message:

Intel IOMMU: bugref:9967 Figuring out host-address and guest-address width handling.

File:
1 edited

Legend:

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

    r89292 r89306  
    305305    uint64_t                    fExtCapReg;
    306306    /** @} */
     307
     308    /** Host-address width (HAW) mask. */
     309    uint64_t                    fHawMask;
     310    /** Maximum guest-address width (MGAW) mask. */
     311    uint64_t                    fMgawMask;
    307312
    308313    /** The event semaphore the invalidation-queue thread waits on. */
     
    707712
    708713/**
    709  * Returns the number of supported adjusted guest-address width (SAGAW) in bits
    710  * given a CAP_REG.SAGAW value.
    711  *
    712  * @returns Number of SAGAW bits.
    713  * @param   uSagaw  The CAP_REG.SAGAW value.
    714  */
    715 static uint8_t vtdCapRegGetSagawBits(uint8_t uSagaw)
    716 {
    717     if (RT_LIKELY(uSagaw > 0 && uSagaw < 4))
    718         return 30 + (uSagaw * 9);
    719     return 0;
    720 }
    721 
    722 
    723 /**
    724714 * Returns the supported adjusted guest-address width (SAGAW) given the maximum
    725715 * guest address width (MGAW).
     
    18331823
    18341824/**
     1825 * Checks whether the address width (AW) is supported by our hardware
     1826 * implementation for legacy mode address translation.
     1827 *
     1828 * @returns @c true if it's supported, @c false otherwise.
     1829 * @param   pThis       The shared DMAR device state.
     1830 * @param   pCtxEntry   The context entry.
     1831 */
     1832static bool dmarDrLegacyModeIsAwValid(PCDMAR pThis, PCVTD_CONTEXT_ENTRY_T pCtxEntry)
     1833{
     1834    uint8_t const fAw     = RT_BF_GET(pCtxEntry->au64[1], VTD_BF_1_CONTEXT_ENTRY_AW);
     1835    uint8_t const fSagaw  = RT_BF_GET(pThis->fCapReg, VTD_BF_CAP_REG_SAGAW);
     1836    uint8_t const fAwMask = RT_BIT(fAw);
     1837    Assert(!(fSagaw & ~(RT_BIT(1) | RT_BIT(2) | RT_BIT(3))));
     1838    return fAw < 4 ? RT_BOOL(fSagaw & fAwMask) : false;
     1839}
     1840
     1841
     1842/**
    18351843 * Reads a root entry from guest memory.
    18361844 *
     
    18921900                uint8_t const idxCtxEntry = RT_LO_U8(pAddrRemap->idDevice);
    18931901                VTD_CONTEXT_ENTRY_T CtxEntry;
     1902                /* We don't verify bits 63:HAW of GCPhysCtxTable is 0 since reading from such an address should fail anyway. */
    18941903                rc = dmarDrReadCtxEntry(pDevIns, GCPhysCtxTable, idxCtxEntry, &CtxEntry);
    18951904                if (RT_SUCCESS(rc))
     
    19111920                                    if (pAddrRemap->enmAddrType == PCIADDRTYPE_UNTRANSLATED)
    19121921                                    {
    1913                                         /** @todo perform second-level translation. */
    1914                                         return VERR_NOT_IMPLEMENTED;
     1922                                        if (dmarDrLegacyModeIsAwValid(pThis, &CtxEntry))
     1923                                        {
     1924                                            return VERR_NOT_IMPLEMENTED;
     1925                                        }
     1926                                        else
     1927                                            dmarAtFaultQualifiedRecord(pDevIns, kDmarDiag_Atf_Lct_4_1, VTDATFAULT_LCT_4_1,
     1928                                                                       pAddrRemap, uCtxEntryQword0);
    19151929                                    }
    19161930                                    Log4Func(("Translation type blocks translated and translation requests\n"));
     
    29252939    pHlp->pfnPrintf(pHlp, " CAP_REG      = %#RX64\n", uCapReg);
    29262940    {
    2927         uint8_t const uSagaw = RT_BF_GET(uCapReg, VTD_BF_CAP_REG_SAGAW);
    2928         uint8_t const uMgaw  = RT_BF_GET(uCapReg, VTD_BF_CAP_REG_MGAW);
    2929         uint8_t const uNfr   = RT_BF_GET(uCapReg, VTD_BF_CAP_REG_NFR);
     2941        uint8_t const uMgaw = RT_BF_GET(uCapReg, VTD_BF_CAP_REG_MGAW);
     2942        uint8_t const uNfr  = RT_BF_GET(uCapReg, VTD_BF_CAP_REG_NFR);
    29302943        pHlp->pfnPrintf(pHlp, "   ND           = %u\n",         RT_BF_GET(uCapReg, VTD_BF_CAP_REG_ND));
    29312944        pHlp->pfnPrintf(pHlp, "   AFL          = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_AFL));
     
    29342947        pHlp->pfnPrintf(pHlp, "   PHMR         = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_PHMR));
    29352948        pHlp->pfnPrintf(pHlp, "   CM           = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_CM));
    2936         pHlp->pfnPrintf(pHlp, "   SAGAW        = %#x (%u bits)\n", uSagaw, vtdCapRegGetSagawBits(uSagaw));
     2949        pHlp->pfnPrintf(pHlp, "   SAGAW        = %#x\n",        RT_BF_GET(uCapReg, VTD_BF_CAP_REG_SAGAW));
    29372950        pHlp->pfnPrintf(pHlp, "   MGAW         = %#x (%u bits)\n", uMgaw, uMgaw + 1);
    29382951        pHlp->pfnPrintf(pHlp, "   ZLR          = %RTbool\n",    RT_BF_GET(uCapReg, VTD_BF_CAP_REG_ZLR));
     
    31683181                       | RT_BF_MAKE(VTD_BF_CAP_REG_ESRTPS,  fEsrtps);
    31693182        dmarRegWriteRaw64(pThis, VTD_MMIO_OFF_CAP_REG, pThis->fCapReg);
     3183
     3184        pThis->fHawMask  = ~(UINT64_MAX << cGstPhysAddrBits);
     3185        pThis->fMgawMask = pThis->fHawMask;
    31703186    }
    31713187
     
    34243440     * Log some of the features exposed to software.
    34253441     */
    3426     uint32_t const uVerReg         = pThis->uVerReg;
    3427     uint8_t const  cMaxGstAddrBits = RT_BF_GET(pThis->fCapReg, VTD_BF_CAP_REG_MGAW) + 1;
    3428     uint8_t const  cSupGstAddrBits = vtdCapRegGetSagawBits(RT_BF_GET(pThis->fCapReg, VTD_BF_CAP_REG_SAGAW));
    3429     uint16_t const offFrcd         = RT_BF_GET(pThis->fCapReg, VTD_BF_CAP_REG_FRO);
    3430     uint16_t const offIva          = RT_BF_GET(pThis->fExtCapReg, VTD_BF_ECAP_REG_IRO);
    3431     LogRel(("%s: VER=%u.%u CAP=%#RX64 ECAP=%#RX64 (MGAW=%u bits, SAGAW=%u bits, FRO=%#x, IRO=%#x) mapped at %#RGp\n",
     3442    uint32_t const uVerReg   = pThis->uVerReg;
     3443    uint8_t const  cMgawBits = RT_BF_GET(pThis->fCapReg, VTD_BF_CAP_REG_MGAW) + 1;
     3444    uint8_t const  fSagaw    = RT_BF_GET(pThis->fCapReg, VTD_BF_CAP_REG_SAGAW);
     3445    uint16_t const offFrcd   = RT_BF_GET(pThis->fCapReg, VTD_BF_CAP_REG_FRO);
     3446    uint16_t const offIva    = RT_BF_GET(pThis->fExtCapReg, VTD_BF_ECAP_REG_IRO);
     3447    LogRel(("%s: VER=%u.%u CAP=%#RX64 ECAP=%#RX64 (MGAW=%u bits, SAGAW=%#x HAW_Mask=%#RX64 FRO=%#x, IRO=%#x) mapped at %#RGp\n",
    34323448            DMAR_LOG_PFX, RT_BF_GET(uVerReg, VTD_BF_VER_REG_MAX), RT_BF_GET(uVerReg, VTD_BF_VER_REG_MIN),
    3433             pThis->fCapReg, pThis->fExtCapReg, cMaxGstAddrBits, cSupGstAddrBits, offFrcd, offIva, DMAR_MMIO_BASE_PHYSADDR));
     3449            pThis->fCapReg, pThis->fExtCapReg, cMgawBits, fSagaw, pThis->fHawMask, offFrcd, offIva, DMAR_MMIO_BASE_PHYSADDR));
    34343450
    34353451    return VINF_SUCCESS;
Note: See TracChangeset for help on using the changeset viewer.

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