VirtualBox

Changeset 89498 in vbox


Ignore:
Timestamp:
Jun 4, 2021 7:45:24 AM (3 years ago)
Author:
vboxsync
Message:

Intel IOMMU: bugref:9967 We need to validate the top level paging entity as well.

File:
1 edited

Legend:

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

    r89495 r89498  
    21382138     * Unlike AMD IOMMU paging, here there is no feature for "skipping" levels.
    21392139     */
    2140     uint64_t uPtEntity = pMemReqAux->uSlptPtr;
    2141     for (int8_t iLevel = pMemReqAux->cPagingLevel - 1; iLevel >= 0; iLevel--)
    2142     {
    2143         /*
    2144          * Read the paging entry for the current level.
    2145          */
    2146         uint8_t const cLevelShift = X86_PAGE_4K_SHIFT + (iLevel * 9);
    2147         {
    2148             uint16_t const idxPte         = (uDmaAddr >> cLevelShift) & UINT64_C(0x1ff);
    2149             uint64_t const offPte         = idxPte << 3;
    2150             RTGCPHYS const GCPhysPtEntity = uPtEntity | offPte;
    2151             int const rc = PDMDevHlpPhysReadMeta(pDevIns, GCPhysPtEntity, &uPtEntity, sizeof(uPtEntity));
    2152             if (RT_SUCCESS(rc))
    2153             { /* likely */ }
    2154             else
    2155             {
    2156                 if (pMemReqAux->fTtm == VTD_TTM_LEGACY_MODE)
    2157                     dmarAtFaultRecordEx(pDevIns, kDmarDiag_Atf_Lsl_1, VTDATFAULT_LSL_1, pMemReqIn, pMemReqAux);
    2158                 else
    2159                     dmarAtFaultRecordEx(pDevIns, kDmarDiag_Atf_Ssl_1, VTDATFAULT_SSL_1, pMemReqIn, pMemReqAux);
    2160                 return VERR_IOMMU_ADDR_TRANSLATION_FAILED;
    2161             }
    2162         }
    2163 
     2140    uint64_t uPtEntity   = pMemReqAux->uSlptPtr;
     2141    int8_t   iLevel      = pMemReqAux->cPagingLevel - 1;
     2142    uint8_t  cLevelShift = X86_PAGE_4K_SHIFT + (iLevel * 9);
     2143    Assert(iLevel >= 2);
     2144    for (;;)
     2145    {
    21642146        /*
    21652147         * Check I/O permissions.
     
    22042186        if (fLargePage && iLevel > 0)
    22052187        {
    2206             Assert(iLevel == 1 || iLevel == 2);
     2188            Assert(iLevel == 1 || iLevel == 2);     /* Is guaranteed by the reserved bits check above. */
    22072189            uint8_t const fSllpsMask = RT_BF_GET(pThis->fCapReg, VTD_BF_CAP_REG_SLLPS);
    22082190            if (fSllpsMask & RT_BIT(iLevel - 1))
     
    22342216            return dmarDrUpdateIoPageOut(pDevIns, GCPhysBase, cLevelShift, fPtPerm, pMemReqIn, pMemReqAux, pIoPageOut);
    22352217        }
    2236     }
    2237 
    2238     /* Shouldn't ever reach here. */
    2239     return VERR_IOMMU_IPE_0;
     2218
     2219        /*
     2220         * Move to the next level.
     2221         */
     2222        --iLevel;
     2223        cLevelShift = X86_PAGE_4K_SHIFT + (iLevel * 9);
     2224
     2225        /*
     2226         * Read the paging entry for the next level.
     2227         */
     2228        {
     2229            uint16_t const idxPte         = (uDmaAddr >> cLevelShift) & UINT64_C(0x1ff);
     2230            uint64_t const offPte         = idxPte << 3;
     2231            RTGCPHYS const GCPhysPtEntity = uPtEntity | offPte;
     2232            int const rc = PDMDevHlpPhysReadMeta(pDevIns, GCPhysPtEntity, &uPtEntity, sizeof(uPtEntity));
     2233            if (RT_SUCCESS(rc))
     2234            { /* likely */ }
     2235            else
     2236            {
     2237                if (pMemReqAux->fTtm == VTD_TTM_LEGACY_MODE)
     2238                    dmarAtFaultRecordEx(pDevIns, kDmarDiag_Atf_Lsl_1, VTDATFAULT_LSL_1, pMemReqIn, pMemReqAux);
     2239                else
     2240                    dmarAtFaultRecordEx(pDevIns, kDmarDiag_Atf_Ssl_1, VTDATFAULT_SSL_1, pMemReqIn, pMemReqAux);
     2241                return VERR_IOMMU_ADDR_TRANSLATION_FAILED;
     2242            }
     2243        }
     2244    }
    22402245}
    22412246
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