VirtualBox

Changeset 100774 in vbox for trunk/src


Ignore:
Timestamp:
Aug 1, 2023 8:01:46 PM (19 months ago)
Author:
vboxsync
Message:

DrvVUSBRootHub: Attempt at fixing situation where vusbR3RhSavePrep encounters a non-NULL pLoad member because the timer hasn't run yet. Immediate issue was using the wrong free function, but further issues turned up after that, leading to performing the depending re-attach prior whatever vusbR3RhSavePrep does so the state is somewhat sane. Regression from r150140, possibly.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/USB/DrvVUSBRootHub.cpp

    r99739 r100774  
    419419static int vusbHubDetach(PVUSBROOTHUB pThis, PVUSBDEV pDev)
    420420{
    421     Assert(pDev->i16Port != -1);
     421    /*
     422     * It is possible to race the re-attach timer callback in some extreme cases,
     423     * typically involving custom VBox builds that does very little guest code
     424     * execution before terminating the VM again (e.g. IEM debugging).
     425     */
     426    Assert(pDev->i16Port != -1 || pThis->pLoad);
     427    if (pDev->i16Port == -1 && pThis->pLoad)
     428        return VINF_SUCCESS;
    422429
    423430    /*
     
    13051312
    13061313/**
     1314 * Helper that frees up pThis->pLoad.
     1315 *
     1316 * This is called in a few places.
     1317 */
     1318static void vushR3RhFreeLoadData(PVUSBROOTHUB pThis, PPDMDRVINS pDrvIns)
     1319{
     1320    PVUSBROOTHUBLOAD const pLoad = pThis->pLoad;
     1321    if (pLoad)
     1322    {
     1323        pThis->pLoad = NULL;
     1324        PDMDrvHlpTimerDestroy(pDrvIns, pLoad->hTimer);
     1325        pLoad->hTimer = NIL_TMTIMERHANDLE;
     1326        RTMemFree(pLoad);
     1327    }
     1328}
     1329
     1330
     1331/**
    13071332 * @callback_method_impl{FNSSMDRVSAVEPREP, All URBs needs to be canceled.}
    13081333 */
     
    13121337    LogFlow(("vusbR3RhSavePrep:\n"));
    13131338    RT_NOREF(pSSM);
     1339
     1340    /*
     1341     * If there is old load state hanging around, we'll have to execute it first
     1342     * to get the hub into the right state prior to saving. This isn't entirely
     1343     * right wrt snapshotting and continuing execution, but OTOH it will screw up
     1344     * if shutting down afterwards.
     1345     */
     1346    PVUSBROOTHUBLOAD const pLoad = pThis->pLoad;
     1347    if (pLoad)
     1348    {
     1349        for (unsigned i = 0; i < pLoad->cDevs; i++)
     1350            vusbHubAttach(pThis, pLoad->apDevs[i]);
     1351        vushR3RhFreeLoadData(pThis, pDrvIns);
     1352    }
    13141353
    13151354    /*
     
    13411380    RTCritSectLeave(&pThis->CritSectDevices);
    13421381
    1343     /*
    1344      * Kill old load data which might be hanging around.
    1345      */
    1346     if (pThis->pLoad)
    1347     {
    1348         PDMDrvHlpTimerDestroy(pDrvIns, pThis->pLoad->hTimer);
    1349         pThis->pLoad->hTimer = NIL_TMTIMERHANDLE;
    1350         PDMDrvHlpMMHeapFree(pDrvIns, pThis->pLoad);
    1351         pThis->pLoad = NULL;
    1352     }
    1353 
    13541382    return VINF_SUCCESS;
    13551383}
     
    14061434    if (!pThis->pLoad)
    14071435    {
     1436        /** @todo allocate first, it may fail later and we'll potentially leave things
     1437         *        dangling. */
    14081438        VUSBROOTHUBLOAD Load;
    14091439        unsigned        i;
     
    14321462        if (Load.cDevs)
    14331463        {
    1434             pThis->pLoad = (PVUSBROOTHUBLOAD)RTMemAllocZ(sizeof(Load));
     1464            pThis->pLoad = (PVUSBROOTHUBLOAD)RTMemDup(&Load, sizeof(Load));
    14351465            if (!pThis->pLoad)
    14361466                return VERR_NO_MEMORY;
    1437             *pThis->pLoad = Load;
    14381467        }
    14391468    }
     
    14451474
    14461475/**
    1447  * Reattaches devices after a saved state load.
     1476 * Timer callback that reattaches devices after a saved state load.
     1477 *
    14481478 */
    14491479static DECLCALLBACK(void) vusbR3RhLoadReattachDevices(PPDMDRVINS pDrvIns, TMTIMERHANDLE hTimer, void *pvUser)
     
    14511481    PVUSBROOTHUB        pThis = PDMINS_2_DATA(pDrvIns, PVUSBROOTHUB);
    14521482    PVUSBROOTHUBLOAD    pLoad = pThis->pLoad;
     1483    AssertPtrReturnVoid(pLoad);
    14531484    LogFlow(("vusbR3RhLoadReattachDevices:\n"));
    14541485    Assert(hTimer == pLoad->hTimer); RT_NOREF(pvUser);
     
    14631494     * Cleanup.
    14641495     */
    1465     PDMDrvHlpTimerDestroy(pDrvIns, hTimer);
    1466     pLoad->hTimer = NIL_TMTIMERHANDLE;
    1467     RTMemFree(pLoad);
    1468     pThis->pLoad = NULL;
     1496    vushR3RhFreeLoadData(pThis, pDrvIns);
    14691497}
    14701498
     
    14821510     * Start a timer if we've got devices to reattach
    14831511     */
    1484     if (pThis->pLoad)
     1512    PVUSBROOTHUBLOAD const pLoad = pThis->pLoad;
     1513    if (pLoad)
    14851514    {
    14861515        int rc = PDMDrvHlpTMTimerCreate(pDrvIns, TMCLOCK_VIRTUAL, vusbR3RhLoadReattachDevices, NULL,
    14871516                                        TMTIMER_FLAGS_NO_CRIT_SECT | TMTIMER_FLAGS_NO_RING0,
    1488                                         "VUSB reattach on load", &pThis->pLoad->hTimer);
     1517                                        "VUSB reattach on load", &pLoad->hTimer);
     1518        AssertLogRelRC(rc);
    14891519        if (RT_SUCCESS(rc))
    1490             rc = PDMDrvHlpTimerSetMillies(pDrvIns, pThis->pLoad->hTimer, 250);
     1520            rc = PDMDrvHlpTimerSetMillies(pDrvIns, pLoad->hTimer, 250);
     1521        else
     1522            vushR3RhFreeLoadData(pThis, pDrvIns); /** @todo or call vusbR3RhLoadReattachDevices directly then fail? */
    14911523        return rc;
    14921524    }
Note: See TracChangeset for help on using the changeset viewer.

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