VirtualBox

Changeset 53717 in vbox for trunk/src/VBox/Runtime/r0drv


Ignore:
Timestamp:
Jan 2, 2015 4:28:08 PM (10 years ago)
Author:
vboxsync
Message:

IPRT/r0drv/nt: Fixed crash in rtmpNtDPCWrapper.

Location:
trunk/src/VBox/Runtime/r0drv
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r0drv/mp-r0drv.h

    r52581 r53717  
    5454    RTCPUID     idCpu;
    5555    uint32_t volatile cHits;
     56#ifdef RT_OS_WINDOWS
     57    /** Turns out that KeFlushQueuedDpcs doesn't necessarily wait till all
     58     * callbacks are done.  So, do reference counting to make sure we don't free
     59     * this structure befor all CPUs have completely handled their requests.  */
     60    int32_t volatile  cRefs;
     61#endif
    5662#ifdef RT_OS_LINUX
    5763    PRTCPUSET   pWorkerSet;
  • trunk/src/VBox/Runtime/r0drv/nt/mp-r0drv-nt.cpp

    r52618 r53717  
    199199    PRTMPARGS pArgs = (PRTMPARGS)DeferredContext;
    200200    ASMAtomicIncU32(&pArgs->cHits);
     201
    201202    pArgs->pfnWorker(KeGetCurrentProcessorNumber(), pArgs->pvUser1, pArgs->pvUser2);
     203
     204    /* Dereference the argument structure. */
     205    int32_t cRefs = ASMAtomicDecS32(&pArgs->cRefs);
     206    Assert(cRefs >= 0);
     207    if (cRefs == 0)
     208        ExFreePool(pArgs);
    202209}
    203210
     
    246253    pArgs->idCpu     = NIL_RTCPUID;
    247254    pArgs->cHits     = 0;
     255    pArgs->cRefs     = 1;
    248256
    249257    paExecCpuDpcs = (KDPC *)(pArgs + 1);
     
    276284     * If someone knows a better way to get this done, please let bird know.
    277285     */
     286    ASMCompilerBarrier(); /* paranoia */
    278287    if (enmCpuid == RT_NT_CPUID_SPECIFIC)
    279288    {
     289        ASMAtomicIncS32(&pArgs->cRefs);
    280290        BOOLEAN ret = KeInsertQueueDpc(&paExecCpuDpcs[0], 0, 0);
    281291        Assert(ret);
     
    290300                &&  (Mask & RT_BIT_64(i)))
    291301            {
     302                ASMAtomicIncS32(&pArgs->cRefs);
    292303                BOOLEAN ret = KeInsertQueueDpc(&paExecCpuDpcs[i], 0, 0);
    293304                Assert(ret);
     
    303314    /** @todo Consider changing this to an active wait using some atomic inc/dec
    304315     *  stuff (and check for the current cpu above in the specific case). */
     316    /** @todo Seems KeFlushQueuedDpcs doesn't wait for the DPCs to be completely
     317     *        executed. Seen pArgs being freed while some CPU was using it before
     318     *        cRefs was added. */
    305319    g_pfnrtNtKeFlushQueuedDpcs();
    306320
    307     ExFreePool(pArgs);
     321    /* Dereference the argument structure. */
     322    int32_t cRefs = ASMAtomicDecS32(&pArgs->cRefs);
     323    Assert(cRefs >= 0);
     324    if (cRefs == 0)
     325        ExFreePool(pArgs);
     326
    308327    return VINF_SUCCESS;
    309328}
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