Changeset 89216 in vbox for trunk/src/VBox/Devices/Bus
- Timestamp:
- May 21, 2021 11:17:05 AM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 144558
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuIntel.cpp
r89201 r89216 1237 1237 1238 1238 /** 1239 * Records a primary fault. 1240 * 1241 * @param pDevIns The IOMMU device instance. 1242 * @param enmDiag The diagnostic reason. 1243 * @param uFrcdHi The FRCD_HI_REG value for this fault. 1244 * @param uFrcdLo The FRCD_LO_REG value for this fault. 1245 */ 1246 static void dmarPrimaryFaultRecord(PPDMDEVINS pDevIns, DMARDIAG enmDiag, uint64_t uFrcdHi, uint64_t uFrcdLo) 1247 { 1248 PDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PDMAR); 1249 PCDMARCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PCDMARCC); 1250 1251 DMAR_LOCK(pDevIns, pThisCC); 1252 1253 /* Update the diagnostic reason. */ 1254 pThis->enmDiag = enmDiag; 1255 1256 /* We don't support advance fault logging. */ 1257 Assert(!(dmarRegRead32(pThis, VTD_MMIO_OFF_GSTS_REG) & VTD_BF_GSTS_REG_AFLS_MASK)); 1258 1259 if (dmarPrimaryFaultCanRecord(pDevIns, pThis)) 1260 { 1261 /* Update the fault recording registers with the fault information. */ 1262 dmarRegWriteRaw64(pThis, DMAR_MMIO_OFF_FRCD_HI_REG, uFrcdHi); 1263 dmarRegWriteRaw64(pThis, DMAR_MMIO_OFF_FRCD_LO_REG, uFrcdLo); 1264 1265 /* Set the Pending Primary Fault (PPF) field in the status register. */ 1266 dmarRegChangeRaw32(pThis, VTD_MMIO_OFF_FSTS_REG, UINT32_MAX, VTD_BF_FSTS_REG_PPF_MASK); 1267 1268 /* Raise interrupt if necessary. */ 1269 dmarFaultEventRaiseInterrupt(pDevIns); 1270 } 1271 1272 DMAR_UNLOCK(pDevIns, pThisCC); 1273 } 1274 1275 1276 /** 1239 1277 * Records an interrupt request fault. 1240 1278 * … … 1245 1283 * @param idxIntr The interrupt index. 1246 1284 */ 1247 static void dmarIrFaultRecord(PPDMDEVINS pDevIns, DMARDIAG enmDiag, VTDINTRFAULT enmIntrFault, uint16_t idDevice, 1248 uint16_t idxIntr) 1249 { 1250 PDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PDMAR); 1251 PCDMARCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PCDMARCC); 1252 1253 DMAR_LOCK(pDevIns, pThisCC); 1254 1255 /* Update the diagnostic reason. */ 1256 pThis->enmDiag = enmDiag; 1257 1258 /* We don't support advance fault logging. */ 1259 Assert(!(dmarRegRead32(pThis, VTD_MMIO_OFF_GSTS_REG) & VTD_BF_GSTS_REG_AFLS_MASK)); 1260 1261 if (dmarPrimaryFaultCanRecord(pDevIns, pThis)) 1262 { 1263 /* Update the fault recording registers with the fault information. */ 1264 uint64_t const uFrcdHi = RT_BF_MAKE(VTD_BF_1_FRCD_REG_SID, idDevice) 1265 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_FR, enmIntrFault) 1266 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_F, 1); 1267 uint64_t const uFrcdLo = (uint64_t)idxIntr << 48; 1268 dmarRegWriteRaw64(pThis, DMAR_MMIO_OFF_FRCD_HI_REG, uFrcdHi); 1269 dmarRegWriteRaw64(pThis, DMAR_MMIO_OFF_FRCD_LO_REG, uFrcdLo); 1270 1271 /* Set the Pending Primary Fault (PPF) field in the status register. */ 1272 dmarRegChangeRaw32(pThis, VTD_MMIO_OFF_FSTS_REG, UINT32_MAX, VTD_BF_FSTS_REG_PPF_MASK); 1273 1274 /* Raise interrupt if necessary. */ 1275 dmarFaultEventRaiseInterrupt(pDevIns); 1276 } 1277 1278 DMAR_UNLOCK(pDevIns, pThisCC); 1285 static void dmarIntrFaultRecord(PPDMDEVINS pDevIns, DMARDIAG enmDiag, VTDINTRFAULT enmIntrFault, uint16_t idDevice, 1286 uint16_t idxIntr) 1287 { 1288 uint64_t const uFrcdHi = RT_BF_MAKE(VTD_BF_1_FRCD_REG_SID, idDevice) 1289 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_FR, enmIntrFault) 1290 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_F, 1); 1291 uint64_t const uFrcdLo = (uint64_t)idxIntr << 48; 1292 dmarPrimaryFaultRecord(pDevIns, enmDiag, uFrcdHi, uFrcdLo); 1279 1293 } 1280 1294 … … 1293 1307 * @param pIrte The IRTE that caused this fault. 1294 1308 */ 1295 static void dmarI rFaultRecordQualified(PPDMDEVINS pDevIns, DMARDIAG enmDiag, VTDINTRFAULT enmIntrFault, uint16_t idDevice,1296 uint16_t idxIntr, PCVTD_IRTE_T pIrte)1309 static void dmarIntrFaultRecordQualified(PPDMDEVINS pDevIns, DMARDIAG enmDiag, VTDINTRFAULT enmIntrFault, uint16_t idDevice, 1310 uint16_t idxIntr, PCVTD_IRTE_T pIrte) 1297 1311 { 1298 1312 Assert(vtdIrFaultIsQualified(enmIntrFault)); 1299 1313 Assert(pIrte); 1300 1314 if (!(pIrte->au64[0] & VTD_BF_0_IRTE_FPD_MASK)) 1301 return dmarIrFaultRecord(pDevIns, enmDiag, enmIntrFault, idDevice, idxIntr); 1315 return dmarIntrFaultRecord(pDevIns, enmDiag, enmIntrFault, idDevice, idxIntr); 1316 } 1317 1318 1319 /** 1320 * Records an address translation fault. 1321 * 1322 * @param pDevIns The IOMMU device instance. 1323 * @param enmDiag The diagnostic reason. 1324 * @param enmAddrFault The address translation fault reason. 1325 * @param idDevice The device ID (bus, device, function). 1326 * @param uFaultAddr The page address of the faulted request. 1327 * @param enmReqType The type of the faulted request. 1328 * @param uAddrType The address type of the faulted request (only applicable 1329 * when device-TLB is supported). 1330 * @param fHasPasid Whether the faulted request has a PASID TLP prefix. 1331 * @param uPasid The PASID value when a PASID TLP prefix is present. 1332 * @param fExec Execute permission was requested by the faulted request. 1333 * @param fPriv Supervisor privilege permission was requested by the 1334 * faulted request. 1335 */ 1336 static void dmarAddrFaultRecord(PPDMDEVINS pDevIns, DMARDIAG enmDiag, VTDADDRFAULT enmAddrFault, uint16_t idDevice, 1337 uint64_t uFaultAddr, VTDREQTYPE enmReqType, uint8_t uAddrType, bool fHasPasid, uint32_t uPasid, 1338 bool fExec, bool fPriv) 1339 { 1340 uint8_t const fType1 = enmReqType & RT_BIT(1); 1341 uint8_t const fType2 = enmReqType & RT_BIT(0); 1342 uint64_t const uFrcdHi = RT_BF_MAKE(VTD_BF_1_FRCD_REG_SID, idDevice) 1343 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_T2, fType2) 1344 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_PP, fHasPasid) 1345 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_EXE, fExec) 1346 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_PRIV, fPriv) 1347 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_FR, enmAddrFault) 1348 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_PV, uPasid) 1349 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_AT, uAddrType) 1350 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_T1, fType1) 1351 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_F, 1); 1352 uint64_t const uFrcdLo = uFaultAddr & X86_PAGE_BASE_MASK; 1353 dmarPrimaryFaultRecord(pDevIns, enmDiag, uFrcdHi, uFrcdLo); 1302 1354 } 1303 1355 … … 1705 1757 DMAR_UNLOCK(pDevIns, pThisCC); 1706 1758 1707 1708 1759 if (uGstsReg & VTD_BF_GSTS_REG_TES_MASK) 1709 1760 { 1761 VTDREQTYPE enmReqType; 1710 1762 if (fFlags & PDMIOMMU_MEM_F_READ) 1763 { 1711 1764 STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatMemRead)); 1765 enmReqType = VTDREQTYPE_READ; 1766 } 1712 1767 else 1768 { 1713 1769 STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatMemWrite)); 1770 enmReqType = VTDREQTYPE_WRITE; 1771 } 1714 1772 1715 1773 uint8_t const fTtm = RT_BF_GET(uRtaddrReg, VTD_BF_RTADDR_REG_TTM); … … 1721 1779 if (pThis->fExtCapReg & VTD_BF_ECAP_REG_ADMS_MASK) 1722 1780 { 1723 1724 1781 } 1725 1782 } … … 1899 1956 return VINF_SUCCESS; 1900 1957 } 1901 dmarI rFaultRecordQualified(pDevIns, kDmarDiag_Ir_Rfi_Irte_Mode_Invalid,1902 VTDINTRFAULT_IRTE_PRESENT_RSVD, idDevice, idxIntr, &Irte);1958 dmarIntrFaultRecordQualified(pDevIns, kDmarDiag_Ir_Rfi_Irte_Mode_Invalid, 1959 VTDINTRFAULT_IRTE_PRESENT_RSVD, idDevice, idxIntr, &Irte); 1903 1960 } 1904 1961 else 1905 dmarI rFaultRecordQualified(pDevIns, enmIrDiag, VTDINTRFAULT_IRTE_PRESENT_RSVD, idDevice, idxIntr,1906 &Irte);1962 dmarIntrFaultRecordQualified(pDevIns, enmIrDiag, VTDINTRFAULT_IRTE_PRESENT_RSVD, idDevice, idxIntr, 1963 &Irte); 1907 1964 } 1908 1965 else 1909 dmarI rFaultRecordQualified(pDevIns, kDmarDiag_Ir_Rfi_Irte_Rsvd, VTDINTRFAULT_IRTE_PRESENT_RSVD, idDevice,1910 idxIntr, &Irte);1966 dmarIntrFaultRecordQualified(pDevIns, kDmarDiag_Ir_Rfi_Irte_Rsvd, VTDINTRFAULT_IRTE_PRESENT_RSVD, 1967 idDevice, idxIntr, &Irte); 1911 1968 } 1912 1969 else 1913 dmarI rFaultRecordQualified(pDevIns, kDmarDiag_Ir_Rfi_Irte_Not_Present, VTDINTRFAULT_IRTE_NOT_PRESENT,1914 idDevice, idxIntr, &Irte);1970 dmarIntrFaultRecordQualified(pDevIns, kDmarDiag_Ir_Rfi_Irte_Not_Present, VTDINTRFAULT_IRTE_NOT_PRESENT, 1971 idDevice, idxIntr, &Irte); 1915 1972 } 1916 1973 else 1917 dmarI rFaultRecord(pDevIns, kDmarDiag_Ir_Rfi_Irte_Read_Failed, VTDINTRFAULT_IRTE_READ_FAILED, idDevice, idxIntr);1974 dmarIntrFaultRecord(pDevIns, kDmarDiag_Ir_Rfi_Irte_Read_Failed, VTDINTRFAULT_IRTE_READ_FAILED, idDevice, idxIntr); 1918 1975 } 1919 1976 else 1920 dmarI rFaultRecord(pDevIns, kDmarDiag_Ir_Rfi_Intr_Index_Invalid, VTDINTRFAULT_INTR_INDEX_INVALID, idDevice, idxIntr);1977 dmarIntrFaultRecord(pDevIns, kDmarDiag_Ir_Rfi_Intr_Index_Invalid, VTDINTRFAULT_INTR_INDEX_INVALID, idDevice, idxIntr); 1921 1978 } 1922 1979 else 1923 dmarI rFaultRecord(pDevIns, kDmarDiag_Ir_Rfi_Rsvd, VTDINTRFAULT_REMAPPABLE_INTR_RSVD, idDevice, 0 /* idxIntr */);1980 dmarIntrFaultRecord(pDevIns, kDmarDiag_Ir_Rfi_Rsvd, VTDINTRFAULT_REMAPPABLE_INTR_RSVD, idDevice, 0 /* idxIntr */); 1924 1981 return VERR_IOMMU_INTR_REMAP_DENIED; 1925 1982 } … … 1965 2022 || !(uGstsReg & VTD_BF_GSTS_REG_CFIS_MASK)) 1966 2023 { 1967 dmarI rFaultRecord(pDevIns, kDmarDiag_Ir_Cfi_Blocked, VTDINTRFAULT_CFI_BLOCKED, idDevice, 0 /* idxIntr */);2024 dmarIntrFaultRecord(pDevIns, kDmarDiag_Ir_Cfi_Blocked, VTDINTRFAULT_CFI_BLOCKED, idDevice, 0 /* idxIntr */); 1968 2025 return VERR_IOMMU_INTR_REMAP_DENIED; 1969 2026 } … … 2009 2066 switch (off) 2010 2067 { 2011 case VTD_MMIO_OFF_GCMD_REG: /* 32-bit */2068 case VTD_MMIO_OFF_GCMD_REG: /* 32-bit */ 2012 2069 { 2013 2070 rcStrict = dmarGcmdRegWrite(pDevIns, uRegWritten); … … 2015 2072 } 2016 2073 2017 case VTD_MMIO_OFF_CCMD_REG: /* 64-bit */2074 case VTD_MMIO_OFF_CCMD_REG: /* 64-bit */ 2018 2075 case VTD_MMIO_OFF_CCMD_REG + 4: 2019 2076 { … … 2022 2079 } 2023 2080 2024 case VTD_MMIO_OFF_FSTS_REG: /* 32-bit */2081 case VTD_MMIO_OFF_FSTS_REG: /* 32-bit */ 2025 2082 { 2026 2083 rcStrict = dmarFstsRegWrite(pDevIns, uRegWritten, uPrev); … … 2028 2085 } 2029 2086 2030 case VTD_MMIO_OFF_FECTL_REG: /* 32-bit */2087 case VTD_MMIO_OFF_FECTL_REG: /* 32-bit */ 2031 2088 { 2032 2089 rcStrict = dmarFectlRegWrite(pDevIns, uRegWritten); … … 2034 2091 } 2035 2092 2036 case VTD_MMIO_OFF_IQT_REG: /* 64-bit */2037 /* VTD_MMIO_OFF_IQT_REG + 4: */ /* High 32-bits reserved. */2093 case VTD_MMIO_OFF_IQT_REG: /* 64-bit */ 2094 /* VTD_MMIO_OFF_IQT_REG + 4: */ /* High 32-bits reserved. */ 2038 2095 { 2039 2096 rcStrict = dmarIqtRegWrite(pDevIns, offReg, uRegWritten); … … 2041 2098 } 2042 2099 2043 case VTD_MMIO_OFF_IQA_REG: /* 64-bit */2044 /* VTD_MMIO_OFF_IQA_REG + 4: */ /* High 32-bits data. */2100 case VTD_MMIO_OFF_IQA_REG: /* 64-bit */ 2101 /* VTD_MMIO_OFF_IQA_REG + 4: */ /* High 32-bits data. */ 2045 2102 { 2046 2103 rcStrict = dmarIqaRegWrite(pDevIns, offReg, uRegWritten); … … 2048 2105 } 2049 2106 2050 case VTD_MMIO_OFF_ICS_REG: /* 32-bit */2107 case VTD_MMIO_OFF_ICS_REG: /* 32-bit */ 2051 2108 { 2052 2109 rcStrict = dmarIcsRegWrite(pDevIns, uRegWritten); … … 2054 2111 } 2055 2112 2056 case VTD_MMIO_OFF_IECTL_REG: /* 32-bit */2113 case VTD_MMIO_OFF_IECTL_REG: /* 32-bit */ 2057 2114 { 2058 2115 rcStrict = dmarIectlRegWrite(pDevIns, uRegWritten); … … 2060 2117 } 2061 2118 2062 case DMAR_MMIO_OFF_FRCD_HI_REG: /* 64-bit */2119 case DMAR_MMIO_OFF_FRCD_HI_REG: /* 64-bit */ 2063 2120 case DMAR_MMIO_OFF_FRCD_HI_REG + 4: 2064 2121 {
Note:
See TracChangeset
for help on using the changeset viewer.