Changeset 108864 in vbox for trunk/src/VBox/VMM/VMMR3/GICR3.cpp
- Timestamp:
- Apr 7, 2025 9:10:44 AM (2 weeks ago)
- svn:sync-xref-src-repo-rev:
- 168314
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/GICR3.cpp
r108835 r108864 309 309 return VINF_SUCCESS; 310 310 311 PGICDEV pGicDev = PDMDEVINS_2_DATA(pDevIns, PGICDEV); 311 PGICDEV pGicDev = PDMDEVINS_2_DATA(pDevIns, PGICDEV); 312 PGITSDEV pGitsDev = &pGicDev->Gits; 312 313 AssertPtrReturn(pGicDev, VERR_INVALID_PARAMETER); 313 314 LogFlowFunc(("Command-queue thread spawned and initialized\n")); 314 315 315 316 /* 316 * Pre-allocate the maximum size of the command queue allowed by the spec.317 * This prevents trashing the heap as well as deal with out-of-memory situations317 * Pre-allocate the maximum size of the command queue allowed by the ARM GIC spec. 318 * This prevents trashing the heap as well as dealing with out-of-memory situations 318 319 * up-front while starting the VM. It also simplifies the code from having to 319 320 * dynamically grow/shrink the allocation based on how software sizes the queue. 320 321 * Guests normally don't alter the queue size all the time, but that's not an 321 * assumption we can make. 322 */ 323 uint16_t const cMaxPages = GITS_BF_CTRL_REG_CBASER_SIZE_MASK + 1; 324 size_t const cbCmdQueue = cMaxPages << GUEST_PAGE_SHIFT; 325 void *pvCommands = RTMemAllocZ(cbCmdQueue); 326 AssertLogRelMsgReturn(pvCommands, ("Failed to alloc %.Rhcb (%zu bytes) for GITS command queue\n", cbCmdQueue, cbCmdQueue), 322 * assumption we can make. Another benefit is that we can avoid releasing and 323 * re-acquiring the device critical section if/when guests modifies the command 324 * queue size. 325 */ 326 uint16_t const cMaxPages = GITS_BF_CTRL_REG_CBASER_SIZE_MASK + 1; 327 size_t const cbCmds = cMaxPages << GITS_CMD_QUEUE_PAGE_SHIFT; 328 void *pvCmds = RTMemAllocZ(cbCmds); 329 AssertLogRelMsgReturn(pvCmds, ("Failed to alloc %.Rhcb (%zu bytes) for the GITS command queue\n", cbCmds, cbCmds), 327 330 VERR_NO_MEMORY); 328 331 329 332 while (pThread->enmState == PDMTHREADSTATE_RUNNING) 330 333 { 331 /* 332 * Sleep until we are woken up. 333 */ 334 /* Sleep until we are woken up. */ 334 335 { 335 int const rc = PDMDevHlpSUPSemEventWaitNoResume(pDevIns, pGicDev->hEvtCmdQueue, RT_INDEFINITE_WAIT); 336 AssertLogRelMsgReturnStmt(RT_SUCCESS(rc) || rc == VERR_INTERRUPTED, ("%Rrc\n", rc), RTMemFree(pvCommands), rc); 336 int const rcLock = PDMDevHlpSUPSemEventWaitNoResume(pDevIns, pGitsDev->hEvtCmdQueue, RT_INDEFINITE_WAIT); 337 AssertLogRelMsgReturnStmt(RT_SUCCESS(rcLock) || rcLock == VERR_INTERRUPTED, ("%Rrc\n", rcLock), 338 RTMemFree(pvCmds), rcLock); 337 339 if (pThread->enmState != PDMTHREADSTATE_RUNNING) 338 340 break; 339 341 } 340 342 341 int const rcLock = PDMDevHlpCritSectEnter(pDevIns, pDevIns->pCritSectRoR3, VINF_SUCCESS); 342 PDM_CRITSECT_RELEASE_ASSERT_RC_DEV(pDevIns, pDevIns->pCritSectRoR3, rcLock); 343 344 /** @todo Process commands. */ 345 346 PDMDevHlpCritSectLeave(pDevIns, pDevIns->pCritSectRoR3); 347 } 348 349 RTMemFree(pvCommands); 343 /* Process the command queue. */ 344 int const rc = gitsR3CmdQueueProcess(pDevIns, pGitsDev, pvCmds, cbCmds); 345 if (RT_FAILURE(rc)) 346 break; 347 } 348 349 RTMemFree(pvCmds); 350 350 351 351 LogFlowFunc(("Command-queue thread terminating\n")); … … 357 357 * Wakes up the command-queue thread so it can respond to a state change. 358 358 * 359 * @return sVBox status code.359 * @return VBox status code. 360 360 * @param pDevIns The device instance. 361 361 * @param pThread The command-queue thread. … … 365 365 static DECLCALLBACK(int) gicItsR3CmdQueueThreadWakeUp(PPDMDEVINS pDevIns, PPDMTHREAD pThread) 366 366 { 367 RT_NOREF 2(pDevIns,pThread);367 RT_NOREF(pThread); 368 368 LogFlowFunc(("\n")); 369 PGICDEV pGicDev = PDMDEVINS_2_DATA(pDevIns, PGICDEV); 370 return PDMDevHlpSUPSemEventSignal(pDevIns, pGicDev->hEvtCmdQueue); 369 PGICDEV pGicDev = PDMDEVINS_2_DATA(pDevIns, PGICDEV); 370 PGITSDEV pGitsDev = &pGicDev->Gits; 371 return PDMDevHlpSUPSemEventSignal(pDevIns, pGitsDev->hEvtCmdQueue); 371 372 } 372 373 … … 638 639 PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns); 639 640 640 PGICDEV pGicDev = PDMDEVINS_2_DATA(pDevIns, PGICDEV); 641 if (pGicDev->hEvtCmdQueue != NIL_SUPSEMEVENT) 642 { 643 PDMDevHlpSUPSemEventClose(pDevIns, pGicDev->hEvtCmdQueue); 644 pGicDev->hEvtCmdQueue = NIL_SUPSEMEVENT; 641 PGICDEV pGicDev = PDMDEVINS_2_DATA(pDevIns, PGICDEV); 642 PGITSDEV pGitsDev = &pGicDev->Gits; 643 if (pGitsDev->hEvtCmdQueue != NIL_SUPSEMEVENT) 644 { 645 PDMDevHlpSUPSemEventClose(pDevIns, pGitsDev->hEvtCmdQueue); 646 pGitsDev->hEvtCmdQueue = NIL_SUPSEMEVENT; 645 647 } 646 648 … … 916 918 917 919 /* Create ITS command-queue thread and semaphore. */ 920 PGITSDEV pGitsDev = &pGicDev->Gits; 918 921 char szCmdQueueThread[32]; 919 922 RT_ZERO(szCmdQueueThread); 920 923 RTStrPrintf(szCmdQueueThread, sizeof(szCmdQueueThread), "Gits-CmdQ-%u", iInstance); 921 rc = PDMDevHlpThreadCreate(pDevIns, &pGi cDev->pCmdQueueThread, &pGicDev, gicItsR3CmdQueueThread,924 rc = PDMDevHlpThreadCreate(pDevIns, &pGitsDev->pCmdQueueThread, &pGicDev, gicItsR3CmdQueueThread, 922 925 gicItsR3CmdQueueThreadWakeUp, 0 /* cbStack */, RTTHREADTYPE_IO, szCmdQueueThread); 923 926 AssertLogRelRCReturn(rc, rc); 924 927 925 rc = PDMDevHlpSUPSemEventCreate(pDevIns, &pGi cDev->hEvtCmdQueue);928 rc = PDMDevHlpSUPSemEventCreate(pDevIns, &pGitsDev->hEvtCmdQueue); 926 929 AssertLogRelRCReturn(rc, rc); 927 930 }
Note:
See TracChangeset
for help on using the changeset viewer.