Changeset 88574 in vbox for trunk/src/VBox/Devices/Bus
- Timestamp:
- Apr 19, 2021 11:27:23 AM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuIntel.cpp
r88558 r88574 54 54 || (a_off) - DMAR_MMIO_GROUP_1_OFF_FIRST < DMAR_MMIO_GROUP_1_SIZE) 55 55 56 /** @name DMAR implementation specifics. 57 * @{ */ 56 /** Acquires the DMAR lock but returns with the given error code on failure. */ 57 #define DMAR_LOCK_RET(a_pDevIns, a_pThisCC, a_rcBusy) \ 58 do { \ 59 if ((a_pThisCC)->CTX_SUFF(pIommuHlp)->pfnLock((a_pDevIns), (a_rcBusy)) == VINF_SUCCESS) \ 60 { /* likely */ } \ 61 else \ 62 return (a_rcBusy); \ 63 } while (0) 64 65 /** Release the DMAR lock. */ 66 #define DMAR_UNLOCK(a_pDevIns, a_pThisCC) (a_pThisCC)->CTX_SUFF(pIommuHlp)->pfnUnlock(a_pDevIns) 67 68 /** Checks whether the calling thread is the owner of the DMAR lock. */ 69 #define DMAR_LOCK_IS_OWNER(a_pDevIns, a_pThisCC) (a_pThisCC)->CTX_SUFF(pIommuHlp)->pfnLockIsOwner(a_pDevIns) 70 71 /** Asserts that the calling thread owns the DMAR lock. */ 72 #define DMAR_ASSERT_LOCK_IS_OWNER(a_pDevIns, a_pThisCC) \ 73 do { \ 74 Assert((a_pThisCC)->CTX_SUFF(pIommuHlp)->pfnLockIsOwner(a_pDevIns)); \ 75 RT_NOREF1(a_pThisCC); \ 76 } while (0) 77 58 78 /** The number of fault recording registers our implementation supports. 59 79 * Normal guest operation shouldn't trigger faults anyway, so we only support the … … 98 118 /** DMAR implementation's minor version number (exposed to software). */ 99 119 #define DMAR_VER_MINOR 0 100 /** @} */101 120 102 121 /** Release log prefix string. */ … … 243 262 /** Pointer to the DMAR device state for the current context. */ 244 263 typedef CTX_SUFF(PDMAR) PDMARCC; 264 /** Pointer to the const DMAR device state for the current context. */ 265 typedef const CTX_SUFF(PDMAR) PCDMARCC; 245 266 246 267 … … 606 627 607 628 /** 629 * Modifies a 32-bit register. 630 * 631 * @param pThis The shared DMAR device state. 632 * @param offReg The MMIO offset of the register. 633 * @param fAndMask The AND mask (applied first). 634 * @param fOrMask The OR mask. 635 */ 636 static void dmarRegChange32(PDMAR pThis, uint16_t offReg, uint32_t fAndMask, uint32_t fOrMask) 637 { 638 uint8_t idxGroup; 639 uint8_t *pabRegs = dmarRegGetGroup(pThis, offReg, sizeof(uint32_t), &idxGroup); 640 NOREF(idxGroup); 641 uint32_t uReg = *(uint32_t *)(pabRegs + offReg); 642 uReg = (uReg & fAndMask) | fOrMask; 643 *(uint32_t *)(pabRegs + offReg) = uReg; 644 } 645 646 647 /** 648 * Modifies a 64-bit register. 649 * 650 * @param pThis The shared DMAR device state. 651 * @param offReg The MMIO offset of the register. 652 * @param fAndMask The AND mask (applied first). 653 * @param fOrMask The OR mask. 654 */ 655 static void dmarRegChange64(PDMAR pThis, uint16_t offReg, uint64_t fAndMask, uint64_t fOrMask) 656 { 657 uint8_t idxGroup; 658 uint8_t *pabRegs = dmarRegGetGroup(pThis, offReg, sizeof(uint64_t), &idxGroup); 659 NOREF(idxGroup); 660 uint64_t uReg = *(uint64_t *)(pabRegs + offReg); 661 uReg = (uReg & fAndMask) | fOrMask; 662 *(uint64_t *)(pabRegs + offReg) = uReg; 663 } 664 665 666 /** 608 667 * Reads a 64-bit register with exactly the value it contains. 609 668 * … … 751 810 uint64_t const uRtAddrReg = dmarRegRead64(pThis, VTD_MMIO_OFF_RTADDR_REG); 752 811 return RT_BF_GET(uRtAddrReg, VTD_BF_RTADDR_REG_TTM); 812 } 813 814 815 /** 816 * Raises an IQE (invalidation queue error) fault. 817 * 818 * @param pDevIns The IOMMU device instance. 819 * @param pThis The shared DMAR device state. 820 * @param enmIqei The IQE information. 821 * @param enmDiag The diagnostic reason. 822 */ 823 static void dmarFaultRaiseIqe(PPDMDEVINS pDevIns, DMARDIAG enmDiag, VTD_IQERCD_IQEI_T enmIqei) 824 { 825 PDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PDMAR); 826 PCDMARCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PCDMARCC); 827 DMAR_ASSERT_LOCK_IS_OWNER(pDevIns, pThisCC); 828 829 /* Set the error bit. */ 830 uint32_t const fIqe = RT_BF_MAKE(VTD_BF_FSTS_REG_IQE, 1); 831 dmarRegChange32(pThis, VTD_MMIO_OFF_FSTS_REG, UINT32_MAX, fIqe); 832 833 /* Set the error information. */ 834 uint64_t const fIqei = RT_BF_MAKE(VTD_BF_IQERCD_REG_IQEI, enmIqei); 835 dmarRegChange64(pThis, VTD_MMIO_OFF_IQERCD_REG, UINT64_MAX, fIqei); 836 837 /* Update diagnostic reason. */ 838 pThis->enmDiag = enmDiag; 839 840 /** @todo Raise interrupt based on FECTL_REG. */ 753 841 } 754 842 … … 820 908 } 821 909 else 822 { 823 /* Raise invalidation queue error as queue tail not aligned to 256-bits. */ 824 /** @todo Raise error. */ 825 } 910 dmarFaultRaiseIqe(pDevIns, kDmarDiag_IqtReg_Qt_NotAligned, kQueueTailNotAligned); 826 911 } 827 912 return VINF_SUCCESS; … … 969 1054 970 1055 #ifdef IN_RING3 1056 /** 1057 * @callback_method_impl{FNDBGFHANDLERDEV} 1058 */ 1059 static DECLCALLBACK(void) dmarR3DbgInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs) 1060 { 1061 PCDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PDMAR); 1062 PCPDMPCIDEV pPciDev = pDevIns->apPciDevs[0]; 1063 PDMPCIDEV_ASSERT_VALID(pDevIns, pPciDev); 1064 1065 bool const fVerbose = RTStrCmp(pszArgs, "verbose") == 0; 1066 1067 DMARDIAG const enmDiag = pThis->enmDiag; 1068 const char *pszDiag = enmDiag < RT_ELEMENTS(g_apszDmarDiagDesc) ? g_apszDmarDiagDesc[enmDiag] : "(Unknown)"; 1069 1070 pHlp->pfnPrintf(pHlp, "Intel-IOMMU:\n"); 1071 pHlp->pfnPrintf(pHlp, " Diag = %u (%s)\n", enmDiag, pszDiag); 1072 pHlp->pfnPrintf(pHlp, "\n"); 1073 } 1074 1075 971 1076 /** 972 1077 * Initializes all registers in the DMAR unit. … … 1214 1319 AssertRCReturn(rc, rc); 1215 1320 1321 /* 1322 * Register debugger info items. 1323 */ 1324 PDMDevHlpDBGFInfoRegister(pDevIns, "iommu", "Display IOMMU state.", dmarR3DbgInfo); 1325 1216 1326 #ifdef VBOX_WITH_STATISTICS 1217 1327 /* … … 1294 1404 AssertReturn(pThisCC->CTX_SUFF(pIommuHlp)->u32Version == CTX_SUFF(PDM_IOMMUHLP)_VERSION, VERR_VERSION_MISMATCH); 1295 1405 AssertReturn(pThisCC->CTX_SUFF(pIommuHlp)->u32TheEnd == CTX_SUFF(PDM_IOMMUHLP)_VERSION, VERR_VERSION_MISMATCH); 1296 AssertPtrReturn(pThisCC->CTX_SUFF(pIommuHlp)->pfnLock, VERR_INVALID_POINTER); 1297 AssertPtrReturn(pThisCC->CTX_SUFF(pIommuHlp)->pfnUnlock, VERR_INVALID_POINTER); 1406 AssertPtrReturn(pThisCC->CTX_SUFF(pIommuHlp)->pfnLock, VERR_INVALID_POINTER); 1407 AssertPtrReturn(pThisCC->CTX_SUFF(pIommuHlp)->pfnUnlock, VERR_INVALID_POINTER); 1408 AssertPtrReturn(pThisCC->CTX_SUFF(pIommuHlp)->pfnLockIsOwner, VERR_INVALID_POINTER); 1298 1409 1299 1410 return VINF_SUCCESS;
Note:
See TracChangeset
for help on using the changeset viewer.