Changeset 89238 in vbox for trunk/src/VBox/Devices/Bus
- Timestamp:
- May 24, 2021 1:53:16 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 144581
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuIntel.cpp
r89236 r89238 395 395 DMAREVENTTYPE_FAULT 396 396 } DMAREVENTTYPE; 397 398 399 /** 400 * DMA address map. 401 * This structure holds information about a DMA address translation. 402 */ 403 typedef struct DMARADDRMAP 404 { 405 /** The device ID (bus, device, function). */ 406 uint16_t idDevice; 407 uint16_t uPadding0; 408 /** The DMA remapping operation request type. */ 409 VTDREQTYPE enmReqType; 410 /** The DMA address being accessed. */ 411 uint64_t uDmaAddr; 412 /** The size of the DMA access (in bytes). */ 413 size_t cbDma; 414 /** The translated system-physical address (HPA). */ 415 RTGCPHYS GCPhysSpa; 416 /** The size of the contiguous translated region (in bytes). */ 417 size_t cbContiguous; 418 } DMARADDRMAP; 419 /** Pointer to a DMA address map. */ 420 typedef DMARADDRMAP *PDMARADDRMAP; 421 /** Pointer to a const DMA address map. */ 422 typedef DMARADDRMAP const *PCDMARADDRMAP; 397 423 398 424 … … 681 707 682 708 /** 683 * Returns whether the interrupt remapping fault is qualified or not.709 * Returns whether the interrupt remapping (IR) fault is qualified or not. 684 710 * 685 711 * @returns @c true if qualified, @c false otherwise. … … 1300 1326 * Records an interrupt request fault. 1301 1327 * 1302 * @param pDevIns 1303 * @param enmDiag 1304 * @param enmIrFault 1305 * @param idDevice 1306 * @param idxIntr 1328 * @param pDevIns The IOMMU device instance. 1329 * @param enmDiag The diagnostic reason. 1330 * @param enmIrFault The interrupt fault reason. 1331 * @param idDevice The device ID (bus, device, function). 1332 * @param idxIntr The interrupt index. 1307 1333 */ 1308 1334 static void dmarIrFaultRecord(PPDMDEVINS pDevIns, DMARDIAG enmDiag, VTDIRFAULT enmIrFault, uint16_t idDevice, uint16_t idxIntr) … … 1322 1348 * in the IRTE. 1323 1349 * 1324 * @param pDevIns 1325 * @param enmDiag 1326 * @param enmIrFault 1327 * @param idDevice 1328 * @param idxIntr 1329 * @param pIrte 1350 * @param pDevIns The IOMMU device instance. 1351 * @param enmDiag The diagnostic reason. 1352 * @param enmIrFault The interrupt fault reason. 1353 * @param idDevice The device ID (bus, device, function). 1354 * @param idxIntr The interrupt index. 1355 * @param pIrte The IRTE that caused this fault. 1330 1356 */ 1331 1357 static void dmarIrFaultRecordQualified(PPDMDEVINS pDevIns, DMARDIAG enmDiag, VTDIRFAULT enmIrFault, uint16_t idDevice, … … 1752 1778 1753 1779 /** 1754 * Performs a PCI target abort for a DMA remapping operation.1780 * Performs a PCI target abort for a DMA remapping (DR) operation. 1755 1781 * 1756 1782 * @param pDevIns The IOMMU device instance. … … 1768 1794 1769 1795 /** 1770 * Validates the table translation mode for a DMA remapping operation.1771 * 1772 * @returns @c true if the TTM is valid, @c false otherwise.1796 * Handles remapping of DMA address requests in legacy mode. 1797 * 1798 * @returns VBox status code. 1773 1799 * @param pDevIns The IOMMU device instance. 1774 1800 * @param uRtaddrReg The current RTADDR_REG value. 1801 * @param pAddrRemap The DMA address remap info. 1802 */ 1803 static int dmarDrLegacyModeRemapAddr(PPDMDEVINS pDevIns, uint64_t uRtaddrReg, PDMARADDRMAP pAddrRemap) 1804 { 1805 RT_NOREF3(pDevIns, uRtaddrReg, pAddrRemap); 1806 return VERR_NOT_IMPLEMENTED; 1807 } 1808 1809 1810 /** 1811 * Handles remapping of DMA address requests in scalable mode. 1812 * 1813 * @returns VBox status code. 1814 * @param pDevIns The IOMMU device instance. 1815 * @param uRtaddrReg The current RTADDR_REG value. 1816 * @param pAddrRemap The DMA address remap info. 1817 */ 1818 static int dmarDrScalableModeRemapAddr(PPDMDEVINS pDevIns, uint64_t uRtaddrReg, PDMARADDRMAP pAddrRemap) 1819 { 1820 PCDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PDMAR); 1821 if (pThis->fExtCapReg & VTD_BF_ECAP_REG_SMTS_MASK) 1822 { 1823 RT_NOREF1(uRtaddrReg); 1824 return VERR_NOT_IMPLEMENTED; 1825 } 1826 1827 dmarAtFaultRecord(pDevIns, kDmarDiag_Atf_Rta_1_3, VTDATFAULT_RTA_1_3, pAddrRemap->idDevice, pAddrRemap->uDmaAddr, 1828 pAddrRemap->enmReqType); 1829 return VERR_IOMMU_ADDR_TRANSLATION_FAILED; 1830 } 1831 1832 1833 /** 1834 * Reads a root entry from guest memory. 1835 * 1836 * @returns VBox status code. 1775 1837 * @param idDevice The device ID (bus, device, function). 1776 * @param uIova The I/O virtual address being accessed. 1777 * @param enmReqType The type of the request (for fault recording). 1778 */ 1779 static bool dmarDrIsTtmValid(PPDMDEVINS pDevIns, uint64_t uRtaddrReg, uint16_t idDevice, uint64_t uIova, VTDREQTYPE enmReqType) 1780 { 1781 bool fValid = true; 1782 PCDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PCDMAR); 1783 uint8_t const fTtm = RT_BF_GET(uRtaddrReg, VTD_BF_RTADDR_REG_TTM); 1784 switch (fTtm) 1785 { 1786 case VTD_TTM_LEGACY_MODE: 1787 break; 1788 1789 case VTD_TTM_SCALABLE_MODE: 1790 { 1791 if (pThis->fExtCapReg & VTD_BF_ECAP_REG_SMTS_MASK) 1792 break; 1793 dmarAtFaultRecord(pDevIns, kDmarDiag_Atf_Rta_1_3, VTDATFAULT_RTA_1_3, idDevice, uIova, enmReqType); 1794 fValid = false; 1795 break; 1796 } 1797 1798 case VTD_TTM_ABORT_DMA_MODE: 1799 { 1800 if (pThis->fExtCapReg & VTD_BF_ECAP_REG_ADMS_MASK) 1801 dmarDrTargetAbort(pDevIns); 1802 else 1803 dmarAtFaultRecord(pDevIns, kDmarDiag_Atf_Rta_1_1, VTDATFAULT_RTA_1_1, idDevice, uIova, enmReqType); 1804 fValid = false; 1805 break; 1806 } 1807 1808 default: 1809 { 1810 dmarAtFaultRecord(pDevIns, kDmarDiag_Atf_Rta_1_2, VTDATFAULT_RTA_1_2, idDevice, uIova, enmReqType); 1811 fValid = false; 1812 break; 1813 } 1814 } 1815 return fValid; 1838 * @param pRootEntry Where to store the read root entry. 1839 */ 1840 static int dmarDrReadRootEntry(PPDMDEVINS pDevIns, uint64_t uRtaddrReg, uint8_t idxEntry, PVTD_ROOT_ENTRY_T pRootEntry) 1841 { 1842 size_t const cbEntry = sizeof(*pRootEntry); 1843 RTGCPHYS const GCPhysEntry = (uRtaddrReg & VTD_BF_RTADDR_REG_RTA_MASK) + (idxEntry * cbEntry); 1844 return PDMDevHlpPhysReadMeta(pDevIns, GCPhysEntry, pRootEntry, cbEntry); 1816 1845 } 1817 1846 … … 1885 1914 } 1886 1915 1887 bool const fTtmValid = dmarDrIsTtmValid(pDevIns, uRtaddrReg, idDevice, uIova, enmReqType); 1888 if (!fTtmValid) 1889 return VERR_IOMMU_ADDR_TRANSLATION_FAILED; 1890 1891 return VERR_NOT_IMPLEMENTED; 1916 DMARADDRMAP AddrRemap; 1917 AddrRemap.idDevice = idDevice; 1918 AddrRemap.enmReqType = enmReqType; 1919 AddrRemap.uDmaAddr = uIova; 1920 AddrRemap.cbDma = cbIova; 1921 AddrRemap.GCPhysSpa = NIL_RTGCPHYS; 1922 AddrRemap.cbContiguous = 0; 1923 1924 int rc; 1925 uint8_t const fTtm = RT_BF_GET(uRtaddrReg, VTD_BF_RTADDR_REG_TTM); 1926 switch (fTtm) 1927 { 1928 case VTD_TTM_LEGACY_MODE: 1929 { 1930 rc = dmarDrLegacyModeRemapAddr(pDevIns, uRtaddrReg, &AddrRemap); 1931 break; 1932 } 1933 1934 case VTD_TTM_SCALABLE_MODE: 1935 { 1936 rc = dmarDrScalableModeRemapAddr(pDevIns, uRtaddrReg, &AddrRemap); 1937 break; 1938 } 1939 1940 case VTD_TTM_ABORT_DMA_MODE: 1941 { 1942 rc = VERR_IOMMU_ADDR_TRANSLATION_FAILED; 1943 if (pThis->fExtCapReg & VTD_BF_ECAP_REG_ADMS_MASK) 1944 dmarDrTargetAbort(pDevIns); 1945 else 1946 dmarAtFaultRecord(pDevIns, kDmarDiag_Atf_Rta_1_1, VTDATFAULT_RTA_1_1, idDevice, uIova, enmReqType); 1947 break; 1948 } 1949 1950 default: 1951 { 1952 rc = VERR_IOMMU_ADDR_TRANSLATION_FAILED; 1953 dmarAtFaultRecord(pDevIns, kDmarDiag_Atf_Rta_1_2, VTDATFAULT_RTA_1_2, idDevice, uIova, enmReqType); 1954 break; 1955 } 1956 } 1957 1958 *pcbContiguous = AddrRemap.cbContiguous; 1959 *pGCPhysSpa = AddrRemap.GCPhysSpa; 1960 return rc; 1892 1961 } 1893 1962
Note:
See TracChangeset
for help on using the changeset viewer.