Changeset 89524 in vbox
- Timestamp:
- Jun 5, 2021 7:34:32 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuIntel.cpp
r89523 r89524 1503 1503 * @param pDevIns The IOMMU device instance. 1504 1504 * @param enmDiag The diagnostic reason. 1505 * @param enmIrFault The interrupt fault reason.1506 1505 * @param idDevice The device ID (bus, device, function). 1507 1506 * @param idxIntr The interrupt index. 1508 */ 1509 static void dmarIrFaultRecord(PPDMDEVINS pDevIns, DMARDIAG enmDiag, VTDIRFAULT enmIrFault, uint16_t idDevice, uint16_t idxIntr) 1510 { 1511 /* Update the diagnostic reason. */ 1512 PDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PDMAR); 1513 pThis->enmDiag = enmDiag; 1514 1515 uint64_t const uFrcdHi = RT_BF_MAKE(VTD_BF_1_FRCD_REG_SID, idDevice) 1516 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_FR, enmIrFault) 1517 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_F, 1); 1518 uint64_t const uFrcdLo = (uint64_t)idxIntr << 48; 1519 dmarPrimaryFaultRecord(pDevIns, uFrcdHi, uFrcdLo); 1520 } 1521 1522 1523 /** 1524 * Records a qualified interrupt request fault. 1525 * 1526 * Qualified faults are those that can be suppressed by software using the FPD bit 1527 * in the IRTE. 1528 * 1529 * @param pDevIns The IOMMU device instance. 1530 * @param enmDiag The diagnostic reason. 1531 * @param enmIrFault The interrupt fault reason. 1532 * @param idDevice The device ID (bus, device, function). 1533 * @param idxIntr The interrupt index. 1534 * @param pIrte The IRTE that caused this fault. 1535 */ 1536 static void dmarIrFaultRecordQualified(PPDMDEVINS pDevIns, DMARDIAG enmDiag, VTDIRFAULT enmIrFault, uint16_t idDevice, 1537 uint16_t idxIntr, PCVTD_IRTE_T pIrte) 1538 { 1539 Assert(vtdIrFaultIsQualified(enmIrFault)); 1540 Assert(pIrte); 1541 if (!(pIrte->au64[0] & VTD_BF_0_IRTE_FPD_MASK)) 1542 return dmarIrFaultRecord(pDevIns, enmDiag, enmIrFault, idDevice, idxIntr); 1543 1544 /* Update the diagnostic reason (even if software wants to supress faults). */ 1545 PDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PDMAR); 1546 pThis->enmDiag = enmDiag; 1547 } 1548 1549 1550 /** 1551 * Records an address translation fault. 1552 * 1553 * @param pDevIns The IOMMU device instance. 1554 * @param enmDiag The diagnostic reason. 1555 * @param pMemReqIn The DMA memory request input. 1556 * @param pMemReqAux The DMA memory request auxiliary info. 1557 */ 1558 static void dmarAtFaultRecord(PPDMDEVINS pDevIns, DMARDIAG enmDiag, PCDMARMEMREQIN pMemReqIn, PCDMARMEMREQAUX pMemReqAux) 1507 * @param pIrte The IRTE that caused this fault. Can be NULL if the fault is 1508 * not qualified. 1509 */ 1510 static void dmarIrFaultRecord(PPDMDEVINS pDevIns, DMARDIAG enmDiag, uint16_t idDevice, uint16_t idxIntr, PCVTD_IRTE_T pIrte) 1559 1511 { 1560 1512 /* … … 1565 1517 1566 1518 /* 1519 * Figure out the fault reason to report to software from our diagnostic code. 1520 * The case labels below are sorted alphabetically for convenience. 1521 */ 1522 VTDIRFAULT enmIrFault; 1523 switch (enmDiag) 1524 { 1525 case kDmarDiag_Ir_Cfi_Blocked: enmIrFault = VTDIRFAULT_CFI_BLOCKED; break; 1526 case kDmarDiag_Ir_Rfi_Intr_Index_Invalid: enmIrFault = VTDIRFAULT_INTR_INDEX_INVALID; break; 1527 case kDmarDiag_Ir_Rfi_Irte_Mode_Invalid: enmIrFault = VTDIRFAULT_IRTE_PRESENT_RSVD; break; 1528 case kDmarDiag_Ir_Rfi_Irte_Not_Present: enmIrFault = VTDIRFAULT_IRTE_NOT_PRESENT; break; 1529 case kDmarDiag_Ir_Rfi_Irte_Read_Failed: enmIrFault = VTDIRFAULT_IRTE_READ_FAILED; break; 1530 case kDmarDiag_Ir_Rfi_Irte_Rsvd: 1531 case kDmarDiag_Ir_Rfi_Irte_Svt_Bus: 1532 case kDmarDiag_Ir_Rfi_Irte_Svt_Masked: 1533 case kDmarDiag_Ir_Rfi_Irte_Svt_Rsvd: enmIrFault = VTDIRFAULT_IRTE_PRESENT_RSVD; break; 1534 case kDmarDiag_Ir_Rfi_Rsvd: enmIrFault = VTDIRFAULT_REMAPPABLE_INTR_RSVD; break; 1535 1536 /* Shouldn't ever happen. */ 1537 default: 1538 { 1539 AssertLogRelMsgFailedReturnVoid(("%s: Invalid interrupt remapping fault diagnostic code %#x\n", DMAR_LOG_PFX, 1540 enmDiag)); 1541 } 1542 } 1543 1544 /* 1567 1545 * Qualified faults are those that can be suppressed by software using the FPD bit 1568 * in the contex entry, scalable-mode context entry etc. 1546 * in the interrupt-remapping table entry. 1547 */ 1548 bool fFpd; 1549 bool const fQualifiedFault = vtdIrFaultIsQualified(enmIrFault); 1550 if (fQualifiedFault) 1551 { 1552 AssertReturnVoid(pIrte); 1553 fFpd = RT_BOOL(pIrte->au64[0] & VTD_BF_0_IRTE_FPD_MASK); 1554 } 1555 else 1556 fFpd = false; 1557 1558 if (!fFpd) 1559 { 1560 /* Construct and record the error. */ 1561 uint64_t const uFrcdHi = RT_BF_MAKE(VTD_BF_1_FRCD_REG_SID, idDevice) 1562 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_FR, enmIrFault) 1563 | RT_BF_MAKE(VTD_BF_1_FRCD_REG_F, 1); 1564 uint64_t const uFrcdLo = (uint64_t)idxIntr << 48; 1565 dmarPrimaryFaultRecord(pDevIns, uFrcdHi, uFrcdLo); 1566 } 1567 } 1568 1569 1570 /** 1571 * Records an address translation fault. 1572 * 1573 * @param pDevIns The IOMMU device instance. 1574 * @param enmDiag The diagnostic reason. 1575 * @param pMemReqIn The DMA memory request input. 1576 * @param pMemReqAux The DMA memory request auxiliary info. 1577 */ 1578 static void dmarAtFaultRecord(PPDMDEVINS pDevIns, DMARDIAG enmDiag, PCDMARMEMREQIN pMemReqIn, PCDMARMEMREQAUX pMemReqAux) 1579 { 1580 /* 1581 * Update the diagnostic reason (even if software wants to supress faults). 1582 */ 1583 PDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PDMAR); 1584 pThis->enmDiag = enmDiag; 1585 1586 /* 1587 * Qualified faults are those that can be suppressed by software using the FPD bit 1588 * in the context entry, scalable-mode context entry etc. 1569 1589 */ 1570 1590 if (!pMemReqAux->fFpd) … … 2194 2214 { 2195 2215 dmarAtFaultRecord(pDevIns, kDmarDiag_At_Xm_Perm_Denied, pMemReqIn, pMemReqAux); 2196 return VERR_IOMMU_ADDR_TRANSLATION_FAILED;2216 break; 2197 2217 } 2198 2218 … … 2205 2225 { 2206 2226 dmarAtFaultRecord(pDevIns, kDmarDiag_At_Xm_Pte_Rsvd, pMemReqIn, pMemReqAux); 2207 return VERR_IOMMU_ADDR_TRANSLATION_FAILED;2227 break; 2208 2228 } 2209 2229 … … 2231 2251 2232 2252 dmarAtFaultRecord(pDevIns, kDmarDiag_At_Xm_Pte_Sllps_Invalid, pMemReqIn, pMemReqAux); 2233 return VERR_IOMMU_ADDR_TRANSLATION_FAILED;2253 break; 2234 2254 } 2235 2255 … … 2262 2282 { 2263 2283 dmarAtFaultRecord(pDevIns, kDmarDiag_At_Xm_Read_Pte_Failed, pMemReqIn, pMemReqAux); 2264 return VERR_IOMMU_ADDR_TRANSLATION_FAILED;2284 break; 2265 2285 } 2266 2286 } 2267 2287 } 2288 2289 return VERR_IOMMU_ADDR_TRANSLATION_FAILED; 2268 2290 } 2269 2291 … … 2844 2866 { 2845 2867 fSrcValid = false; 2846 enmIrDiag = kDmarDiag_Ir_Rfi_Irte_Svt_ Bus;2868 enmIrDiag = kDmarDiag_Ir_Rfi_Irte_Svt_Rsvd; 2847 2869 break; 2848 2870 } … … 2857 2879 return VINF_SUCCESS; 2858 2880 } 2859 dmarIrFaultRecordQualified(pDevIns, kDmarDiag_Ir_Rfi_Irte_Mode_Invalid, 2860 VTDIRFAULT_IRTE_PRESENT_RSVD, idDevice, idxIntr, &Irte); 2881 dmarIrFaultRecord(pDevIns, kDmarDiag_Ir_Rfi_Irte_Mode_Invalid, idDevice, idxIntr, &Irte); 2861 2882 } 2862 2883 else 2863 dmarIrFaultRecordQualified(pDevIns, enmIrDiag, VTDIRFAULT_IRTE_PRESENT_RSVD, idDevice, idxIntr, 2864 &Irte); 2884 dmarIrFaultRecord(pDevIns, enmIrDiag, idDevice, idxIntr, &Irte); 2865 2885 } 2866 2886 else 2867 dmarIrFaultRecordQualified(pDevIns, kDmarDiag_Ir_Rfi_Irte_Rsvd, VTDIRFAULT_IRTE_PRESENT_RSVD, 2868 idDevice, idxIntr, &Irte); 2887 dmarIrFaultRecord(pDevIns, kDmarDiag_Ir_Rfi_Irte_Rsvd, idDevice, idxIntr, &Irte); 2869 2888 } 2870 2889 else 2871 dmarIrFaultRecordQualified(pDevIns, kDmarDiag_Ir_Rfi_Irte_Not_Present, VTDIRFAULT_IRTE_NOT_PRESENT, 2872 idDevice, idxIntr, &Irte); 2890 dmarIrFaultRecord(pDevIns, kDmarDiag_Ir_Rfi_Irte_Not_Present, idDevice, idxIntr, &Irte); 2873 2891 } 2874 2892 else 2875 dmarIrFaultRecord(pDevIns, kDmarDiag_Ir_Rfi_Irte_Read_Failed, VTDIRFAULT_IRTE_READ_FAILED, idDevice, idxIntr);2893 dmarIrFaultRecord(pDevIns, kDmarDiag_Ir_Rfi_Irte_Read_Failed, idDevice, idxIntr, NULL /* pIrte */); 2876 2894 } 2877 2895 else 2878 dmarIrFaultRecord(pDevIns, kDmarDiag_Ir_Rfi_Intr_Index_Invalid, VTDIRFAULT_INTR_INDEX_INVALID, idDevice, idxIntr);2896 dmarIrFaultRecord(pDevIns, kDmarDiag_Ir_Rfi_Intr_Index_Invalid, idDevice, idxIntr, NULL /* pIrte */); 2879 2897 } 2880 2898 else 2881 dmarIrFaultRecord(pDevIns, kDmarDiag_Ir_Rfi_Rsvd, VTDIRFAULT_REMAPPABLE_INTR_RSVD, idDevice, 0 /* idxIntr*/);2899 dmarIrFaultRecord(pDevIns, kDmarDiag_Ir_Rfi_Rsvd, idDevice, 0 /* idxIntr */, NULL /* pIrte */); 2882 2900 return VERR_IOMMU_INTR_REMAP_DENIED; 2883 2901 }
Note:
See TracChangeset
for help on using the changeset viewer.