Changeset 89418 in vbox for trunk/src/VBox
- Timestamp:
- Jun 1, 2021 6:52:41 AM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuIntel.cpp
r89407 r89418 151 151 /** DMA request permission: Write. */ 152 152 #define DMAR_PERM_WRITE RT_BIT(1) 153 /** DMA request permission: Execute . */153 /** DMA request permission: Execute (ER). */ 154 154 #define DMAR_PERM_EXE RT_BIT(2) 155 /** DMA request permission: Supervisor privilege . */155 /** DMA request permission: Supervisor privilege (PR). */ 156 156 #define DMAR_PERM_PRIV RT_BIT(3) 157 157 /** DMA request permissions: All. */ … … 189 189 kDmarDiag_Atf_Lct_4_3, 190 190 kDmarDiag_Atf_Lct_5, 191 kDmarDiag_Atf_Lgn_1_1, 192 kDmarDiag_Atf_Lgn_1_2, 193 kDmarDiag_Atf_Lgn_1_3, 191 194 kDmarDiag_Atf_Lrt_1, 192 195 kDmarDiag_Atf_Lrt_2, … … 198 201 kDmarDiag_Atf_Rta_1_2, 199 202 kDmarDiag_Atf_Rta_1_3, 203 kDmarDiag_Atf_Sgn_5, 200 204 kDmarDiag_Atf_Ssl_1, 201 205 kDmarDiag_Atf_Ssl_2, … … 262 266 DMARDIAG_DESC(Atf_Lct_4_3 ), 263 267 DMARDIAG_DESC(Atf_Lct_5 ), 268 DMARDIAG_DESC(Atf_Lgn_1_1 ), 269 DMARDIAG_DESC(Atf_Lgn_1_2 ), 270 DMARDIAG_DESC(Atf_Lgn_1_3 ), 264 271 DMARDIAG_DESC(Atf_Lrt_1 ), 265 272 DMARDIAG_DESC(Atf_Lrt_2 ), … … 271 278 DMARDIAG_DESC(Atf_Rta_1_2 ), 272 279 DMARDIAG_DESC(Atf_Rta_1_3 ), 280 DMARDIAG_DESC(Atf_Sgn_5 ), 273 281 DMARDIAG_DESC(Atf_Ssl_1 ), 274 282 DMARDIAG_DESC(Atf_Ssl_2 ), … … 344 352 /** Host-address width (HAW) base address mask. */ 345 353 uint64_t fHawBaseMask; 346 /** Maximum guest-address width (MGAW) baseaddress mask. */347 uint64_t f MgawBaseMask;354 /** Maximum guest-address width (MGAW) invalid address mask. */ 355 uint64_t fInvMgawMask; 348 356 /** Maximum supported paging level (3, 4 or 5). */ 349 uint8_t uMaxPagingLevel;357 uint8_t cMaxPagingLevel; 350 358 /** DMA request valid permissions mask. */ 351 359 uint8_t fPermValidMask; … … 1884 1892 * @param pThis The shared DMAR device state. 1885 1893 * @param pCtxEntry The context entry. 1886 * @param p uPagingLevel Where to store the paging level.1887 */ 1888 static bool dmarDrLegacyModeIsAwValid(PCDMAR pThis, PCVTD_CONTEXT_ENTRY_T pCtxEntry, uint8_t *p uPagingLevel)1894 * @param pcPagingLevel Where to store the paging level. 1895 */ 1896 static bool dmarDrLegacyModeIsAwValid(PCDMAR pThis, PCVTD_CONTEXT_ENTRY_T pCtxEntry, uint8_t *pcPagingLevel) 1889 1897 { 1890 1898 uint8_t const fTt = RT_BF_GET(pCtxEntry->au64[0], VTD_BF_0_CONTEXT_ENTRY_TT); … … 1894 1902 Assert(!(fSagaw & ~(RT_BIT(1) | RT_BIT(2) | RT_BIT(3)))); 1895 1903 1896 *p uPagingLevel = fAw + 2;1904 *pcPagingLevel = fAw + 2; 1897 1905 1898 1906 /* With pass-through, the address width must be the largest AGAW supported by hardware. */ 1899 1907 if (fTt == VTD_TT_UNTRANSLATED_PT) 1900 1908 { 1901 Assert(pThis-> uMaxPagingLevel >= 3 && pThis->uMaxPagingLevel <= 5); /* Paranoia. */1902 return *p uPagingLevel == pThis->uMaxPagingLevel;1909 Assert(pThis->cMaxPagingLevel >= 3 && pThis->cMaxPagingLevel <= 5); /* Paranoia. */ 1910 return *pcPagingLevel == pThis->cMaxPagingLevel; 1903 1911 } 1904 1912 … … 1967 1975 * @param pDevIns The IOMMU device instance. 1968 1976 * @param SlpEntry The second-level paging entry. 1969 * @param uPagingLevel The paging level.1977 * @param cPagingLevel The paging level. 1970 1978 * @param idDomain The domain ID for the translation. 1971 1979 * @param pAddrRemap The DMA address remap info. 1972 1980 */ 1973 static int dmarDrSecondLevelTranslate(PPDMDEVINS pDevIns, VTD_SLP_ENTRY_T SlpEntry, uint8_t uPagingLevel, uint16_t idDomain,1981 static int dmarDrSecondLevelTranslate(PPDMDEVINS pDevIns, VTD_SLP_ENTRY_T SlpEntry, uint8_t cPagingLevel, uint16_t idDomain, 1974 1982 PDMARADDRMAP pAddrRemap) 1975 1983 { … … 1983 1991 VTD_SL_PML5E_VALID_MASK }; 1984 1992 1985 /* Mask of valid large-page paging entry bits. */1993 /* Mask of valid large-page (1GB, 2MB) paging entries. */ 1986 1994 static uint64_t const s_auLargePageRsvd[] = { 0, 1987 1995 VTD_SL_PDE2M_VALID_MASK, … … 1991 1999 1992 2000 /* Paranoia. */ 1993 Assert( uPagingLevel >= 3 && uPagingLevel <= 5);2001 Assert(cPagingLevel >= 3 && cPagingLevel <= 5); 1994 2002 AssertCompile(RT_ELEMENTS(s_auPtEntityRsvd) == RT_ELEMENTS(s_auLargePageRsvd)); 1995 2003 AssertCompile(RT_ELEMENTS(s_auPtEntityRsvd) == 5); 2004 2005 /* Second-level translations restricts input address to an implementation-specific MGAW. */ 2006 uint64_t const uDmaAddr = pAddrRemap->uDmaAddr; 2007 if (!(uDmaAddr & pThis->fInvMgawMask)) 2008 { /* likely */ } 2009 else 2010 { 2011 if (pAddrRemap->fTtm == VTD_TTM_LEGACY_MODE) 2012 dmarAtFaultRecord(pDevIns, kDmarDiag_Atf_Lgn_1_1, VTDATFAULT_LGN_1_1, pAddrRemap); 2013 else 2014 dmarAtFaultRecord(pDevIns, kDmarDiag_Atf_Sgn_5, VTDATFAULT_SGN_5, pAddrRemap); 2015 return VERR_IOMMU_ADDR_TRANSLATION_FAILED; 2016 } 1996 2017 1997 2018 /* … … 1999 2020 * Unlike AMD IOMMU paging, here there is no feature for "skipping" levels. 2000 2021 */ 2001 uint64_t uPtEntity = SlpEntry; 2002 uint64_t const uDmaAddr = pAddrRemap->uDmaAddr & pThis->fMgawBaseMask; 2003 uint64_t const fHawBaseMask = pThis->fHawBaseMask; 2004 for (int8_t iLevel = uPagingLevel - 1; iLevel >= 0; iLevel--) 2022 uint64_t uPtEntity = SlpEntry; 2023 for (int8_t iLevel = cPagingLevel - 1; iLevel >= 0; iLevel--) 2005 2024 { 2006 2025 /* … … 2011 2030 uint16_t const idxPte = (uDmaAddr >> cLevelShift) & UINT64_C(0x1ff); 2012 2031 uint64_t const offPte = idxPte << 3; 2013 /** @todo if we validate 63:HAW (since hardware treats it as reserved and we should fault if that's the case, we might not need to & fHawbaseMask here. */ 2014 RTGCPHYS const GCPhysPtEntity = (uPtEntity & fHawBaseMask) | offPte; 2032 RTGCPHYS const GCPhysPtEntity = uPtEntity | offPte; 2015 2033 int const rc = PDMDevHlpPhysReadMeta(pDevIns, GCPhysPtEntity, &uPtEntity, sizeof(uPtEntity)); 2016 2034 if (RT_SUCCESS(rc)) … … 2168 2186 { 2169 2187 /* Validate the address width and get the paging level. */ 2170 uint8_t uPagingLevel;2171 if (dmarDrLegacyModeIsAwValid(pThis, &CtxEntry, & uPagingLevel))2188 uint8_t cPagingLevel; 2189 if (dmarDrLegacyModeIsAwValid(pThis, &CtxEntry, &cPagingLevel)) 2172 2190 { 2173 2191 /* Read the SLPTPTR from guest memory. */ … … 2178 2196 { 2179 2197 /* Finally... perform second-level translation. */ 2180 return dmarDrSecondLevelTranslate(pDevIns, SlpEntry, uPagingLevel, idDomain,2198 return dmarDrSecondLevelTranslate(pDevIns, SlpEntry, cPagingLevel, idDomain, 2181 2199 pAddrRemap); 2182 2200 } … … 3461 3479 dmarRegWriteRaw64(pThis, VTD_MMIO_OFF_CAP_REG, pThis->fCapReg); 3462 3480 3463 pThis->fHawBaseMask 3464 pThis->f MgawBaseMask = pThis->fHawBaseMask;3465 pThis-> uMaxPagingLevel = vtdCapRegGetMaxPagingLevel(fSagaw);3481 pThis->fHawBaseMask = ~(UINT64_MAX << cGstPhysAddrBits) & X86_PAGE_4K_BASE_MASK; 3482 pThis->fInvMgawMask = UINT64_MAX << cGstPhysAddrBits; 3483 pThis->cMaxPagingLevel = vtdCapRegGetMaxPagingLevel(fSagaw); 3466 3484 } 3467 3485 … … 3730 3748 uint16_t const offFrcd = RT_BF_GET(pThis->fCapReg, VTD_BF_CAP_REG_FRO); 3731 3749 uint16_t const offIva = RT_BF_GET(pThis->fExtCapReg, VTD_BF_ECAP_REG_IRO); 3732 LogRel(("%s: VER=%u.%u CAP=%#RX64 ECAP=%#RX64 (MGAW=%u bits, SAGAW=%#x HAW =%#RX64 MGAW=%#RX64 FRO=%#x IRO=%#x) mapped at %#RGp\n",3750 LogRel(("%s: VER=%u.%u CAP=%#RX64 ECAP=%#RX64 (MGAW=%u bits, SAGAW=%#x HAW_Base=%#RX64 MGAW_Inv=%#RX64 FRO=%#x IRO=%#x) mapped at %#RGp\n", 3733 3751 DMAR_LOG_PFX, RT_BF_GET(uVerReg, VTD_BF_VER_REG_MAX), RT_BF_GET(uVerReg, VTD_BF_VER_REG_MIN), 3734 pThis->fCapReg, pThis->fExtCapReg, cMgawBits, fSagaw, pThis->fHawBaseMask, pThis->f MgawBaseMask, offFrcd, offIva,3752 pThis->fCapReg, pThis->fExtCapReg, cMgawBits, fSagaw, pThis->fHawBaseMask, pThis->fInvMgawMask, offFrcd, offIva, 3735 3753 DMAR_MMIO_BASE_PHYSADDR)); 3736 3754
Note:
See TracChangeset
for help on using the changeset viewer.