Changeset 88627 in vbox for trunk/src/VBox
- Timestamp:
- Apr 21, 2021 10:27:13 AM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevIommuIntel.cpp
r88625 r88627 111 111 112 112 /** DMAR implementation's major version number (exposed to software). 113 * We report 6 as the major version since we support queued 113 * We report 6 as the major version since we support queued-invalidations as 114 114 * software may make assumptions based on that. 115 115 * … … 171 171 /** The MMIO handle. */ 172 172 IOMMMIOHANDLE hMmio; 173 /** The event semaphore the queued-invalidationthread waits on. */174 SUPSEMEVENT hEvt QueuedInvThread;175 /** Whether the queued-invalidationthread has been signaled. */176 bool volatile f QueuedInvThreadSignaled;173 /** The event semaphore the invalidation-queue thread waits on. */ 174 SUPSEMEVENT hEvtInvQueue; 175 /** Whether the invalidation-queue thread has been signaled. */ 176 bool volatile fInvQueueThreadSignaled; 177 177 /** Padding. */ 178 178 bool afPadding0[3]; … … 233 233 /** The IOMMU helper. */ 234 234 R3PTRTYPE(PCPDMIOMMUHLPR3) pIommuHlpR3; 235 /** The queued-invalidationthread. */236 R3PTRTYPE(PPDMTHREAD) p QueuedInvThread;235 /** The invalidation-queue thread. */ 236 R3PTRTYPE(PPDMTHREAD) pInvQueueThread; 237 237 } DMARR3; 238 238 /** Pointer to the ring-3 DMAR device state. */ … … 851 851 852 852 /** 853 * Checks whether the invalidation-queue is empty. 854 * 855 * @returns @c true if empty, @c false otherwise. 856 * @param pThis The shared DMAR device state. 857 */ 858 static bool dmarInvQueueIsEmpty(PCDMAR pThis) 859 { 860 uint64_t const uIqtReg = dmarRegRead64(pThis, VTD_MMIO_OFF_IQT_REG); 861 uint32_t const offQueueTail = VTD_IQT_REG_GET_QT(uIqtReg); 862 863 uint64_t const uIqhReg = dmarRegRead64(pThis, VTD_MMIO_OFF_IQH_REG); 864 uint32_t const offQueueHead = VTD_IQT_REG_GET_QH(uIqhReg); 865 866 return offQueueTail == offQueueHead; 867 } 868 869 870 /** 871 * Checks whether the invalidation-queue is capable of processing requests. 872 * 873 * @returns @c true if the invalidation-queue can be processed, @c false otherwise. 874 * @param pThis The shared DMAR device state. 875 */ 876 static bool dmarInvQueueCanProcessRequests(PCDMAR pThis) 877 { 878 /* Check if queued-invalidation is enabled. */ 879 uint32_t const uGstsReg = dmarRegRead32(pThis, VTD_MMIO_OFF_GSTS_REG); 880 if (uGstsReg & VTD_BF_GSTS_REG_QIES_MASK) 881 { 882 /* Check if there are no IQ errors and that the queue isn't empty. */ 883 uint32_t const uFstsReg = dmarRegRead32(pThis, VTD_MMIO_OFF_FSTS_REG); 884 if ( !(uFstsReg & VTD_BF_FSTS_REG_IQE_MASK) 885 && !dmarInvQueueIsEmpty(pThis)) 886 return true; 887 } 888 return false; 889 } 890 891 892 /** 893 * Wakes up the invalidation-queue thread if there are requests to be processed. 894 * 895 * @param pDevIns The IOMMU device instance. 896 */ 897 static void dmarInvQueueThreadWakeUpIfNeeded(PPDMDEVINS pDevIns) 898 { 899 PDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PDMAR); 900 PCDMARCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PCDMARCC); 901 Log4Func(("\n")); 902 903 DMAR_ASSERT_LOCK_IS_OWNER(pDevIns, pThisCC); 904 905 if ( dmarInvQueueCanProcessRequests(pThis) 906 && !ASMAtomicXchgBool(&pThis->fInvQueueThreadSignaled, true)) 907 { 908 Log4Func(("Signaling the invalidation-queue thread\n")); 909 PDMDevHlpSUPSemEventSignal(pDevIns, pThis->hEvtInvQueue); 910 } 911 } 912 913 914 /** 853 915 * Raises an interrupt in response to an event. 854 916 * … … 1023 1085 if ( fDw != VTD_IQA_REG_DW_256_BIT 1024 1086 || !(offQueueTail & 0x1f)) 1025 { 1026 /* Don't bother waking the thread if an invalidation-queue error is pending. */ 1027 uint32_t const uFstsReg = dmarRegRead32(pThis, VTD_MMIO_OFF_FSTS_REG); 1028 if (!(uFstsReg & VTD_BF_FSTS_REG_IQE_MASK)) 1029 { 1030 /** @todo Figure out what to do here, like waking up worker thread or 1031 * something. */ 1032 } 1033 } 1087 dmarInvQueueThreadWakeUpIfNeeded(pDevIns); 1034 1088 else 1035 1089 dmarIqeFaultRecord(pDevIns, kDmarDiag_IqtReg_Qt_NotAligned, kQueueTailNotAligned); … … 1217 1271 #ifdef IN_RING3 1218 1272 /** 1219 * The queued-invalidation thread function.1273 * The invalidation-queue thread. 1220 1274 * 1221 1275 * @returns VBox status code. … … 1223 1277 * @param pThread The command thread. 1224 1278 */ 1225 static DECLCALLBACK(int) dmarR3 QueuedInvThread(PPDMDEVINS pDevIns, PPDMTHREAD pThread)1279 static DECLCALLBACK(int) dmarR3InvQueueThread(PPDMDEVINS pDevIns, PPDMTHREAD pThread) 1226 1280 { 1227 1281 NOREF(pThread); … … 1239 1293 * Sleep until we are woken up. 1240 1294 */ 1241 bool const fSignaled = ASMAtomicXchgBool(&pThis->f QueuedInvThreadSignaled, false);1295 bool const fSignaled = ASMAtomicXchgBool(&pThis->fInvQueueThreadSignaled, false); 1242 1296 if (!fSignaled) 1243 1297 { 1244 int rc = PDMDevHlpSUPSemEventWaitNoResume(pDevIns, pThis->hEvt QueuedInvThread, RT_INDEFINITE_WAIT);1298 int rc = PDMDevHlpSUPSemEventWaitNoResume(pDevIns, pThis->hEvtInvQueue, RT_INDEFINITE_WAIT); 1245 1299 AssertLogRelMsgReturn(RT_SUCCESS(rc) || rc == VERR_INTERRUPTED, ("%Rrc\n", rc), rc); 1246 1300 if (RT_UNLIKELY(pThread->enmState != PDMTHREADSTATE_RUNNING)) 1247 1301 break; 1248 ASMAtomicWriteBool(&pThis->f QueuedInvThreadSignaled, false);1302 ASMAtomicWriteBool(&pThis->fInvQueueThreadSignaled, false); 1249 1303 } 1250 1304 1251 1305 /* 1252 * Fetch and process queued-invalidation requests.1306 * Fetch and process invalidation requests. 1253 1307 */ 1254 1308 DMAR_LOCK_RET(pDevIns, pThisR3, VERR_IGNORED); … … 1262 1316 } 1263 1317 1264 LogFlowFunc((" Queued-invalidationthread terminating\n"));1318 LogFlowFunc(("Invalidation-queue thread terminating\n")); 1265 1319 return VINF_SUCCESS; 1266 1320 } … … 1268 1322 1269 1323 /** 1270 * Wakes up the queued-invalidation thread so it can respond to a state change. 1324 * Wakes up the invalidation-queue thread so it can respond to a state 1325 * change. 1271 1326 * 1272 1327 * @returns VBox status code. 1273 1328 * @param pDevIns The IOMMU device instance. 1274 * @param pThread The queued-invalidationthread.1329 * @param pThread The invalidation-queue thread. 1275 1330 * 1276 1331 * @thread EMT. 1277 1332 */ 1278 static DECLCALLBACK(int) dmarR3 QueuedInvThreadWakeUp(PPDMDEVINS pDevIns, PPDMTHREAD pThread)1333 static DECLCALLBACK(int) dmarR3InvQueueThreadWakeUp(PPDMDEVINS pDevIns, PPDMTHREAD pThread) 1279 1334 { 1280 1335 RT_NOREF(pThread); 1281 1336 LogFlowFunc(("\n")); 1282 1337 PCDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PDMAR); 1283 return PDMDevHlpSUPSemEventSignal(pDevIns, pThis->hEvt QueuedInvThread);1338 return PDMDevHlpSUPSemEventSignal(pDevIns, pThis->hEvtInvQueue); 1284 1339 } 1285 1340 … … 1379 1434 /* ECAP_REG */ 1380 1435 { 1381 uint8_t const fQi = 1; /* Queued 1436 uint8_t const fQi = 1; /* Queued-invalidations. */ 1382 1437 uint8_t const fIr = !!(DMAR_ACPI_DMAR_FLAGS & ACPI_DMAR_F_INTR_REMAP); /* Interrupt remapping support. */ 1383 1438 uint8_t const fMhmv = 0xf; /* Maximum handle mask value. */ … … 1461 1516 LogFlowFunc(("\n")); 1462 1517 1463 if (pThis->hEvt QueuedInvThread!= NIL_SUPSEMEVENT)1464 { 1465 PDMDevHlpSUPSemEventClose(pDevIns, pThis->hEvt QueuedInvThread);1466 pThis->hEvt QueuedInvThread= NIL_SUPSEMEVENT;1518 if (pThis->hEvtInvQueue != NIL_SUPSEMEVENT) 1519 { 1520 PDMDevHlpSUPSemEventClose(pDevIns, pThis->hEvtInvQueue); 1521 pThis->hEvtInvQueue = NIL_SUPSEMEVENT; 1467 1522 } 1468 1523 … … 1595 1650 1596 1651 /* 1597 * Create queued-invalidationthread and semaphore.1652 * Create invalidation-queue thread and semaphore. 1598 1653 */ 1599 char sz QueuedInvThread[32];1600 RT_ZERO(sz QueuedInvThread);1601 RTStrPrintf(sz QueuedInvThread, sizeof(szQueuedInvThread), "IOMMU-QI-%u", iInstance);1602 rc = PDMDevHlpThreadCreate(pDevIns, &pThisR3->p QueuedInvThread, pThis, dmarR3QueuedInvThread, dmarR3QueuedInvThreadWakeUp,1603 0 /* cbStack */, RTTHREADTYPE_IO, sz QueuedInvThread);1654 char szInvQueueThread[32]; 1655 RT_ZERO(szInvQueueThread); 1656 RTStrPrintf(szInvQueueThread, sizeof(szInvQueueThread), "IOMMU-QI-%u", iInstance); 1657 rc = PDMDevHlpThreadCreate(pDevIns, &pThisR3->pInvQueueThread, pThis, dmarR3InvQueueThread, dmarR3InvQueueThreadWakeUp, 1658 0 /* cbStack */, RTTHREADTYPE_IO, szInvQueueThread); 1604 1659 AssertLogRelRCReturn(rc, rc); 1605 1660 1606 rc = PDMDevHlpSUPSemEventCreate(pDevIns, &pThis->hEvt QueuedInvThread);1661 rc = PDMDevHlpSUPSemEventCreate(pDevIns, &pThis->hEvtInvQueue); 1607 1662 AssertLogRelRCReturn(rc, rc); 1608 1663
Note:
See TracChangeset
for help on using the changeset viewer.