Changeset 89419 in vbox for trunk/src/VBox/Devices/Bus
- Timestamp:
- Jun 1, 2021 7:57:29 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuIntel.cpp
r89418 r89419 476 476 typedef struct DMARIOTLBE 477 477 { 478 RTGCPHYS GCPhysBase; 479 uint8_t cShift; 480 uint8_t fPerm; 481 uint16_t idDomain; 482 uint16_t uPadding0; 478 /** The system-physical base address of the translation. */ 479 RTGCPHYS GCPhysBase; 480 /** The page shift of the translation. */ 481 uint8_t cShift; 482 /** The permissions granted. */ 483 uint8_t fPerm; 484 /** The domain ID of the translated region. */ 485 uint16_t idDomain; 483 486 } DMARIOTLBE; 484 487 /** Pointer to an IOTLB entry. */ … … 488 491 489 492 /** 490 * DMA Address Remapping Information. 491 */ 492 typedef struct DMARADDRMAP 493 { 494 /** The device ID (bus, device, function). */ 495 uint16_t idDevice; 493 * DMA Address Request. 494 */ 495 typedef struct DMARADDRREQ 496 { 497 /** The address being accessed. */ 498 uint64_t uDmaAddr; 499 /** The size of the access (in bytes). */ 500 size_t cbDma; 496 501 /** The requested permissions (DMAR_PERM_XXX). */ 497 uint8_t fReqPerm; 502 uint8_t fReqPerm; 503 /** The source device ID (bus, device, function). */ 504 uint16_t idDevice; 505 /** The PASID if present (can be NIL_PCIPASID). */ 506 PCIPASID Pasid; 507 /* The address translation type. */ 508 PCIADDRTYPE enmAddrType; 509 /** The request type. */ 510 VTDREQTYPE enmReqType; 511 } DMARADDRREQ; 512 /** Pointer to a DMA address request. */ 513 typedef DMARADDRREQ *PDMARADDRREQ; 514 /** Pointer to a const DMA request. */ 515 typedef DMARADDRREQ const *PCDMARADDRREQ; 516 517 /** 518 * DMA Address Remap Info. 519 */ 520 typedef struct DMARADDRREMAP 521 { 522 /* The DMA address request. */ 523 DMARADDRREQ AddrReq; 524 /** The table translation mode (VTD_TTM_XXX). */ 525 uint8_t fTtm; 498 526 /** The fault processing disabled (FPD) bit. */ 499 uint8_t fFpd; 500 /** The PASID if present, can be NIL_PCIPASID. */ 501 PCIPASID Pasid; 502 /* The address type of the memory request. */ 503 PCIADDRTYPE enmAddrType; 504 /** The type of the translation request. */ 505 VTDREQTYPE enmReqType; 506 /** The table translation mode (VTD_TTM_XXX). */ 507 uint8_t fTtm; 508 uint8_t uPadding[7]; 509 /** The DMA address being accessed. */ 510 uint64_t uDmaAddr; 511 /** The size of the DMA access (in bytes). */ 512 size_t cbDma; 513 514 /** The IOTLBE for this remapping. */ 515 DMARIOTLBE Iotlbe; 527 uint8_t fFpd; 528 529 /** The IOTLBE results for this remapping. */ 530 DMARIOTLBE Iotlbe; 516 531 /** The size of the contiguous translated region (in bytes). */ 517 size_t 518 } DMARADDR MAP;519 /** Pointer to a DMA address remapping object. */520 typedef DMARADDR MAP *PDMARADDRMAP;521 /** Pointer to a const DMA address remapping object. */522 typedef DMARADDR MAP const *PCDMARADDRMAP;532 size_t cbContiguous; 533 } DMARADDRREMAP; 534 /** Pointer to a DMA remap info. */ 535 typedef DMARADDRREMAP *PDMARADDRREMAP; 536 /** Pointer to a const DMA remap info. */ 537 typedef DMARADDRREMAP const *PCDMARADDRREMAP; 523 538 524 539 … … 1488 1503 * @param pAddrRemap The DMA address remap info. 1489 1504 */ 1490 static void dmarAtFaultRecord(PPDMDEVINS pDevIns, DMARDIAG enmDiag, VTDATFAULT enmAtFault, PCDMARADDR MAP pAddrRemap)1505 static void dmarAtFaultRecord(PPDMDEVINS pDevIns, DMARDIAG enmDiag, VTDATFAULT enmAtFault, PCDMARADDRREMAP pAddrRemap) 1491 1506 { 1492 1507 /* … … 1496 1511 if (!pAddrRemap->fFpd) 1497 1512 { 1498 uint8_t const fType1 = pAddrRemap-> enmReqType & RT_BIT(1);1499 uint8_t const fType2 = pAddrRemap-> enmReqType & RT_BIT(0);1500 uint8_t const fExec = pAddrRemap-> fReqPerm & DMAR_PERM_EXE;1501 uint8_t const fPriv = pAddrRemap-> fReqPerm & DMAR_PERM_PRIV;1502 uint64_t const uFrcdHi = RT_BF_MAKE(VTD_BF_1_FRCD_REG_SID, pAddrRemap-> idDevice)1513 uint8_t const fType1 = pAddrRemap->AddrReq.enmReqType & RT_BIT(1); 1514 uint8_t const fType2 = pAddrRemap->AddrReq.enmReqType & RT_BIT(0); 1515 uint8_t const fExec = pAddrRemap->AddrReq.fReqPerm & DMAR_PERM_EXE; 1516 uint8_t const fPriv = pAddrRemap->AddrReq.fReqPerm & DMAR_PERM_PRIV; 1517 uint64_t const uFrcdHi = RT_BF_MAKE(VTD_BF_1_FRCD_REG_SID, pAddrRemap->AddrReq.idDevice) 1503 1518 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_T2, fType2) 1504 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_PP, PCIPASID_IS_VALID(pAddrRemap-> Pasid))1519 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_PP, PCIPASID_IS_VALID(pAddrRemap->AddrReq.Pasid)) 1505 1520 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_EXE, fExec) 1506 1521 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_PRIV, fPriv) 1507 1522 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_FR, enmAtFault) 1508 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_PV, PCIPASID_VAL(pAddrRemap-> Pasid))1509 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_AT, pAddrRemap-> enmAddrType)1523 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_PV, PCIPASID_VAL(pAddrRemap->AddrReq.Pasid)) 1524 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_AT, pAddrRemap->AddrReq.enmAddrType) 1510 1525 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_T1, fType1) 1511 1526 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_F, 1); 1512 uint64_t const uFrcdLo = pAddrRemap-> uDmaAddr & X86_PAGE_BASE_MASK;1527 uint64_t const uFrcdLo = pAddrRemap->AddrReq.uDmaAddr & X86_PAGE_BASE_MASK; 1513 1528 dmarPrimaryFaultRecord(pDevIns, enmDiag, uFrcdHi, uFrcdLo); 1514 1529 } … … 1892 1907 * @param pThis The shared DMAR device state. 1893 1908 * @param pCtxEntry The context entry. 1894 * @param pcPagingLevel Where to store the paging level. 1909 * @param pcPagingLevel Where to store the paging level. Optional, can be 1910 * NULL. 1895 1911 */ 1896 1912 static bool dmarDrLegacyModeIsAwValid(PCDMAR pThis, PCVTD_CONTEXT_ENTRY_T pCtxEntry, uint8_t *pcPagingLevel) … … 1902 1918 Assert(!(fSagaw & ~(RT_BIT(1) | RT_BIT(2) | RT_BIT(3)))); 1903 1919 1904 *pcPagingLevel = fAw + 2; 1920 uint8_t const cPagingLevel = fAw + 2; 1921 if (pcPagingLevel) 1922 *pcPagingLevel = cPagingLevel; 1905 1923 1906 1924 /* With pass-through, the address width must be the largest AGAW supported by hardware. */ … … 1908 1926 { 1909 1927 Assert(pThis->cMaxPagingLevel >= 3 && pThis->cMaxPagingLevel <= 5); /* Paranoia. */ 1910 return *pcPagingLevel == pThis->cMaxPagingLevel;1928 return cPagingLevel == pThis->cMaxPagingLevel; 1911 1929 } 1912 1930 … … 1980 1998 */ 1981 1999 static int dmarDrSecondLevelTranslate(PPDMDEVINS pDevIns, VTD_SLP_ENTRY_T SlpEntry, uint8_t cPagingLevel, uint16_t idDomain, 1982 PDMARADDR MAP pAddrRemap)2000 PDMARADDRREMAP pAddrRemap) 1983 2001 { 1984 2002 PCDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PCDMAR); … … 2004 2022 2005 2023 /* Second-level translations restricts input address to an implementation-specific MGAW. */ 2006 uint64_t const uDmaAddr = pAddrRemap-> uDmaAddr;2024 uint64_t const uDmaAddr = pAddrRemap->AddrReq.uDmaAddr; 2007 2025 if (!(uDmaAddr & pThis->fInvMgawMask)) 2008 2026 { /* likely */ } … … 2050 2068 * See Intel spec. 7.1.3 "Fault conditions and Remapping hardware behavior for various request". 2051 2069 */ 2052 uint8_t const fReqPerm = pAddrRemap-> fReqPerm & pThis->fPermValidMask;2070 uint8_t const fReqPerm = pAddrRemap->AddrReq.fReqPerm & pThis->fPermValidMask; 2053 2071 uint8_t const fPtPerm = uPtEntity & pThis->fPermValidMask; 2054 2072 if ((fPtPerm & fReqPerm) == fReqPerm) … … 2128 2146 * @param pAddrRemap The DMA address remap info. 2129 2147 */ 2130 static int dmarDrLegacyModeRemapAddr(PPDMDEVINS pDevIns, uint64_t uRtaddrReg, PDMARADDR MAP pAddrRemap)2148 static int dmarDrLegacyModeRemapAddr(PPDMDEVINS pDevIns, uint64_t uRtaddrReg, PDMARADDRREMAP pAddrRemap) 2131 2149 { 2132 2150 Assert(pAddrRemap->fTtm == VTD_TTM_LEGACY_MODE); /* Paranoia. */ 2133 2151 2134 2152 /* Read the root-entry from guest memory. */ 2135 uint8_t const idxRootEntry = RT_HI_U8(pAddrRemap-> idDevice);2153 uint8_t const idxRootEntry = RT_HI_U8(pAddrRemap->AddrReq.idDevice); 2136 2154 VTD_ROOT_ENTRY_T RootEntry; 2137 2155 int rc = dmarDrReadRootEntry(pDevIns, uRtaddrReg, idxRootEntry, &RootEntry); … … 2150 2168 /* Read the context-entry from guest memory. */ 2151 2169 RTGCPHYS const GCPhysCtxTable = RT_BF_GET(uRootEntryQword0, VTD_BF_0_ROOT_ENTRY_CTP); 2152 uint8_t const idxCtxEntry = RT_LO_U8(pAddrRemap-> idDevice);2170 uint8_t const idxCtxEntry = RT_LO_U8(pAddrRemap->AddrReq.idDevice); 2153 2171 VTD_CONTEXT_ENTRY_T CtxEntry; 2154 2172 rc = dmarDrReadCtxEntry(pDevIns, GCPhysCtxTable, idxCtxEntry, &CtxEntry); … … 2183 2201 * through SLPTPTR. Translated requests and Translation Requests are blocked. 2184 2202 */ 2185 if (pAddrRemap-> enmAddrType == PCIADDRTYPE_UNTRANSLATED)2203 if (pAddrRemap->AddrReq.enmAddrType == PCIADDRTYPE_UNTRANSLATED) 2186 2204 { 2187 2205 /* Validate the address width and get the paging level. */ … … 2218 2236 if (pThis->fExtCapReg & VTD_BF_ECAP_REG_PT_MASK) 2219 2237 { 2220 if (pAddrRemap-> enmAddrType == PCIADDRTYPE_UNTRANSLATED)2238 if (pAddrRemap->AddrReq.enmAddrType == PCIADDRTYPE_UNTRANSLATED) 2221 2239 { 2222 2240 /** @todo Check AW == maximum SAGAW bit? */ 2223 pAddrRemap->Iotlbe.GCPhysBase = pAddrRemap-> uDmaAddr & X86_PAGE_4K_BASE_MASK;2241 pAddrRemap->Iotlbe.GCPhysBase = pAddrRemap->AddrReq.uDmaAddr & X86_PAGE_4K_BASE_MASK; 2224 2242 pAddrRemap->Iotlbe.cShift = X86_PAGE_4K_SHIFT; 2225 2243 pAddrRemap->Iotlbe.fPerm = DMAR_PERM_ALL; 2226 2244 pAddrRemap->Iotlbe.idDomain = idDomain; 2227 pAddrRemap->cbContiguous = pAddrRemap-> cbDma;2245 pAddrRemap->cbContiguous = pAddrRemap->AddrReq.cbDma; 2228 2246 return VINF_SUCCESS; 2229 2247 } … … 2281 2299 * @param pAddrRemap The DMA address remap info. 2282 2300 */ 2283 static int dmarDrScalableModeRemapAddr(PPDMDEVINS pDevIns, uint64_t uRtaddrReg, PDMARADDR MAP pAddrRemap)2301 static int dmarDrScalableModeRemapAddr(PPDMDEVINS pDevIns, uint64_t uRtaddrReg, PDMARADDRREMAP pAddrRemap) 2284 2302 { 2285 2303 PCDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PDMAR); … … 2367 2385 2368 2386 uint8_t const fTtm = RT_BF_GET(uRtaddrReg, VTD_BF_RTADDR_REG_TTM); 2369 DMARADDR MAP AddrRemap;2387 DMARADDRREMAP AddrRemap; 2370 2388 RT_ZERO(AddrRemap); 2371 AddrRemap. idDevice = idDevice;2372 AddrRemap. fReqPerm = fReqPerm;2373 AddrRemap. Pasid = NIL_PCIPASID;2374 AddrRemap. enmAddrType = PCIADDRTYPE_UNTRANSLATED;2375 AddrRemap. enmReqType = enmReqType;2376 AddrRemap. fTtm = fTtm;2377 AddrRemap. uDmaAddr = uIova;2378 AddrRemap. cbDma = cbIova;2379 AddrRemap.Iotlbe.GCPhysBase = NIL_RTGCPHYS;2389 AddrRemap.AddrReq.uDmaAddr = uIova; 2390 AddrRemap.AddrReq.cbDma = cbIova; 2391 AddrRemap.AddrReq.fReqPerm = fReqPerm; 2392 AddrRemap.AddrReq.idDevice = idDevice; 2393 AddrRemap.AddrReq.Pasid = NIL_PCIPASID; 2394 AddrRemap.AddrReq.enmAddrType = PCIADDRTYPE_UNTRANSLATED; 2395 AddrRemap.AddrReq.enmReqType = enmReqType; 2396 AddrRemap.fTtm = fTtm; 2397 AddrRemap.Iotlbe.GCPhysBase = NIL_RTGCPHYS; 2380 2398 2381 2399 int rc;
Note:
See TracChangeset
for help on using the changeset viewer.