VirtualBox

Ignore:
Timestamp:
Apr 7, 2025 9:10:44 AM (2 weeks ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
168314
Message:

VMM/GIC: bugref:10877 GIC ITS command-queue, work-in-progress.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/GICR3.cpp

    r108835 r108864  
    309309        return VINF_SUCCESS;
    310310
    311     PGICDEV pGicDev = PDMDEVINS_2_DATA(pDevIns, PGICDEV);
     311    PGICDEV  pGicDev  = PDMDEVINS_2_DATA(pDevIns, PGICDEV);
     312    PGITSDEV pGitsDev = &pGicDev->Gits;
    312313    AssertPtrReturn(pGicDev, VERR_INVALID_PARAMETER);
    313314    LogFlowFunc(("Command-queue thread spawned and initialized\n"));
    314315
    315316    /*
    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 situations
     317     * 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
    318319     * up-front while starting the VM. It also simplifies the code from having to
    319320     * dynamically grow/shrink the allocation based on how software sizes the queue.
    320321     * 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),
    327330                          VERR_NO_MEMORY);
    328331
    329332    while (pThread->enmState == PDMTHREADSTATE_RUNNING)
    330333    {
    331         /*
    332          * Sleep until we are woken up.
    333          */
     334        /* Sleep until we are woken up. */
    334335        {
    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);
    337339            if (pThread->enmState != PDMTHREADSTATE_RUNNING)
    338340                break;
    339341        }
    340342
    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);
    350350
    351351    LogFlowFunc(("Command-queue thread terminating\n"));
     
    357357 * Wakes up the command-queue thread so it can respond to a state change.
    358358 *
    359  * @returns VBox status code.
     359 * @return VBox status code.
    360360 * @param   pDevIns     The device instance.
    361361 * @param   pThread     The command-queue thread.
     
    365365static DECLCALLBACK(int) gicItsR3CmdQueueThreadWakeUp(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
    366366{
    367     RT_NOREF2(pDevIns, pThread);
     367    RT_NOREF(pThread);
    368368    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);
    371372}
    372373
     
    638639    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
    639640
    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;
    645647    }
    646648
     
    916918
    917919            /* Create ITS command-queue thread and semaphore. */
     920            PGITSDEV pGitsDev = &pGicDev->Gits;
    918921            char szCmdQueueThread[32];
    919922            RT_ZERO(szCmdQueueThread);
    920923            RTStrPrintf(szCmdQueueThread, sizeof(szCmdQueueThread), "Gits-CmdQ-%u", iInstance);
    921             rc = PDMDevHlpThreadCreate(pDevIns, &pGicDev->pCmdQueueThread, &pGicDev, gicItsR3CmdQueueThread,
     924            rc = PDMDevHlpThreadCreate(pDevIns, &pGitsDev->pCmdQueueThread, &pGicDev, gicItsR3CmdQueueThread,
    922925                                       gicItsR3CmdQueueThreadWakeUp, 0 /* cbStack */, RTTHREADTYPE_IO, szCmdQueueThread);
    923926            AssertLogRelRCReturn(rc, rc);
    924927
    925             rc = PDMDevHlpSUPSemEventCreate(pDevIns, &pGicDev->hEvtCmdQueue);
     928            rc = PDMDevHlpSUPSemEventCreate(pDevIns, &pGitsDev->hEvtCmdQueue);
    926929            AssertLogRelRCReturn(rc, rc);
    927930        }
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette