Changeset 89498 in vbox
- Timestamp:
- Jun 4, 2021 7:45:24 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuIntel.cpp
r89495 r89498 2138 2138 * Unlike AMD IOMMU paging, here there is no feature for "skipping" levels. 2139 2139 */ 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 { 2164 2146 /* 2165 2147 * Check I/O permissions. … … 2204 2186 if (fLargePage && iLevel > 0) 2205 2187 { 2206 Assert(iLevel == 1 || iLevel == 2); 2188 Assert(iLevel == 1 || iLevel == 2); /* Is guaranteed by the reserved bits check above. */ 2207 2189 uint8_t const fSllpsMask = RT_BF_GET(pThis->fCapReg, VTD_BF_CAP_REG_SLLPS); 2208 2190 if (fSllpsMask & RT_BIT(iLevel - 1)) … … 2234 2216 return dmarDrUpdateIoPageOut(pDevIns, GCPhysBase, cLevelShift, fPtPerm, pMemReqIn, pMemReqAux, pIoPageOut); 2235 2217 } 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 } 2240 2245 } 2241 2246
Note:
See TracChangeset
for help on using the changeset viewer.