VirtualBox

Changeset 47537 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Aug 5, 2013 10:00:02 AM (11 years ago)
Author:
vboxsync
Message:

HostDrivers/Support: Introduce reference counting for the session object to keep it alive while there is someone accessing it, fixes R0 assertion on OS X when killing the VM process

Location:
trunk/src/VBox/HostDrivers/Support
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDrv.c

    r47352 r47537  
    697697                pSession->u32Cookie         = BIRD_INV;
    698698                pSession->fUnrestricted     = fUnrestricted;
     699                pSession->cRefs             = 1;
    699700                /*pSession->pLdrUsage         = NULL;
    700701                pSession->pVM               = NULL;
     
    742743
    743744/**
    744  * Shared code for cleaning up a session.
     745 * Shared code for cleaning up a session (but not quite freeing it).
     746 *
     747 * This is primarily intended for MAC OS X where we have to clean up the memory
     748 * stuff before the file handle is closed.
    745749 *
    746750 * @param   pDevExt     Device extension.
     
    748752 *                      This data will be freed by this routine.
    749753 */
    750 void VBOXCALL supdrvCloseSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession)
    751 {
    752     VBOXDRV_SESSION_CLOSE(pSession);
    753 
    754     /*
    755      * Cleanup the session first.
    756      */
    757     supdrvCleanupSession(pDevExt, pSession);
    758 
    759     /*
    760      * Free the rest of the session stuff.
    761      */
    762     RTSpinlockDestroy(pSession->Spinlock);
    763     pSession->Spinlock = NIL_RTSPINLOCK;
    764     pSession->pDevExt = NULL;
    765     RTMemFree(pSession);
    766     LogFlow(("supdrvCloseSession: returns\n"));
    767 }
    768 
    769 
    770 /**
    771  * Shared code for cleaning up a session (but not quite freeing it).
    772  *
    773  * This is primarily intended for MAC OS X where we have to clean up the memory
    774  * stuff before the file handle is closed.
    775  *
    776  * @param   pDevExt     Device extension.
    777  * @param   pSession    Session data.
    778  *                      This data will be freed by this routine.
    779  */
    780 void VBOXCALL supdrvCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession)
     754static void supdrvCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession)
    781755{
    782756    int                 rc;
     
    985959}
    986960
     961
     962/**
     963 * Shared code for cleaning up a session.
     964 *
     965 * @param   pDevExt     Device extension.
     966 * @param   pSession    Session data.
     967 *                      This data will be freed by this routine.
     968 */
     969static void supdrvCloseSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession)
     970{
     971    VBOXDRV_SESSION_CLOSE(pSession);
     972
     973    /*
     974     * Cleanup the session first.
     975     */
     976    supdrvCleanupSession(pDevExt, pSession);
     977
     978    /*
     979     * Free the rest of the session stuff.
     980     */
     981    RTSpinlockDestroy(pSession->Spinlock);
     982    pSession->Spinlock = NIL_RTSPINLOCK;
     983    pSession->pDevExt = NULL;
     984    RTMemFree(pSession);
     985    LogFlow(("supdrvCloseSession: returns\n"));
     986}
     987
     988
     989/**
     990 * Retain a session to make sure it doesn't go away while it is in use.
     991 *
     992 * @returns New reference count on success, UINT32_MAX on failure.
     993 * @param   pSession    Session data.
     994 */
     995uint32_t VBOXCALL supdrvSessionRetain(PSUPDRVSESSION pSession)
     996{
     997    AssertPtrReturn(pSession, UINT32_MAX);
     998    AssertReturn(SUP_IS_SESSION_VALID(pSession), UINT32_MAX);
     999
     1000    uint32_t cRefs = ASMAtomicIncU32(&pSession->cRefs);
     1001    AssertMsg(cRefs > 1 && cRefs < _1M, ("%#x %p\n", cRefs, pSession));
     1002    return cRefs;
     1003}
     1004
     1005/**
     1006 * Releases a given session.
     1007 *
     1008 * @returns New reference count on success (0 if closed), UINT32_MAX on failure.
     1009 * @param   pSession    Session data.
     1010 */
     1011uint32_t VBOXCALL supdrvSessionRelease(PSUPDRVSESSION pSession)
     1012{
     1013    AssertPtrReturn(pSession, UINT32_MAX);
     1014    AssertReturn(SUP_IS_SESSION_VALID(pSession), UINT32_MAX);
     1015
     1016    uint32_t cRefs = ASMAtomicDecU32(&pSession->cRefs);
     1017    AssertMsg(cRefs < _1M, ("%#x %p\n", cRefs, pSession));
     1018    if (cRefs == 0)
     1019        supdrvCloseSession(pSession->pDevExt, pSession);
     1020    return cRefs;
     1021}
    9871022
    9881023/**
     
    21212156            REQ_CHECK_IDC_SIZE(SUPDRV_IDC_REQ_DISCONNECT, sizeof(*pReqHdr));
    21222157
    2123             supdrvCloseSession(pDevExt, pSession);
     2158            supdrvSessionRelease(pSession);
    21242159            return pReqHdr->rc = VINF_SUCCESS;
    21252160        }
  • trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h

    r45188 r47537  
    419419    /** Set if is an unrestricted session, clear if restricted. */
    420420    bool                            fUnrestricted;
     421    /* Reference counter. */
     422    uint32_t volatile               cRefs;
    421423
    422424    /** The VM associated with the session. */
     
    693695void VBOXCALL   supdrvDeleteDevExt(PSUPDRVDEVEXT pDevExt);
    694696int  VBOXCALL   supdrvCreateSession(PSUPDRVDEVEXT pDevExt, bool fUser, bool fUnrestricted,  PSUPDRVSESSION *ppSession);
    695 void VBOXCALL   supdrvCloseSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession);
    696 void VBOXCALL   supdrvCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession);
     697uint32_t VBOXCALL supdrvSessionRetain(PSUPDRVSESSION pSession);
     698uint32_t VBOXCALL supdrvSessionRelease(PSUPDRVSESSION pSession);
    697699
    698700int  VBOXCALL   supdrvTracerInit(PSUPDRVDEVEXT pDevExt);
  • trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp

    r45250 r47537  
    524524    while (pSession && pSession->Process != Process && pSession->fUnrestricted == fUnrestricted && pSession->fOpened)
    525525        pSession = pSession->pNextHash;
     526
     527    if (RT_LIKELY(pSession))
     528        supdrvSessionRetain(pSession);
    526529    RTSpinlockReleaseNoInts(g_Spinlock);
    527530    if (!pSession)
     
    536539     * the session and iCmd, and only returns a VBox status code.
    537540     */
     541    int rc;
    538542    if (   (    iCmd == SUP_IOCTL_FAST_DO_RAW_RUN
    539543            ||  iCmd == SUP_IOCTL_FAST_DO_HM_RUN
    540544            ||  iCmd == SUP_IOCTL_FAST_DO_NOP)
    541545        && fUnrestricted)
    542         return supdrvIOCtlFast(iCmd, *(uint32_t *)pData, &g_DevExt, pSession);
    543     return VBoxDrvDarwinIOCtlSlow(pSession, iCmd, pData, pProcess);
     546        rc = supdrvIOCtlFast(iCmd, *(uint32_t *)pData, &g_DevExt, pSession);
     547    else
     548        rc = VBoxDrvDarwinIOCtlSlow(pSession, iCmd, pData, pProcess);
     549
     550    supdrvSessionRelease(pSession);
     551    return rc;
    544552}
    545553
     
    11551163
    11561164                LogFlow(("org_virtualbox_SupDrvClient::start: already got a session for this process (%p)\n", pCur));
    1157                 supdrvCloseSession(&g_DevExt, m_pSession);
     1165                supdrvSessionRelease(m_pSession);
    11581166            }
    11591167
     
    12311239     * Close the session.
    12321240     */
    1233     supdrvCloseSession(&g_DevExt, pSession);
     1241    supdrvSessionRelease(pSession);
    12341242}
    12351243
  • trunk/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c

    r44182 r47537  
    292292     * Close the session.
    293293     */
    294     supdrvCloseSession(&g_VBoxDrvFreeBSDDevExt, pSession);
     294    supdrvSessionRelease(&g_VBoxDrvFreeBSDDevExt, pSession);
    295295    ASMAtomicDecU32(&g_cUsers);
    296296}
  • trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c

    r46374 r47537  
    550550    Log(("VBoxDrvLinuxClose: pFilp=%p pSession=%p pid=%d/%d %s\n",
    551551         pFilp, pFilp->private_data, RTProcSelf(), current->pid, current->comm));
    552     supdrvCloseSession(&g_DevExt, (PSUPDRVSESSION)pFilp->private_data);
     552    supdrvSessionRelease((PSUPDRVSESSION)pFilp->private_data);
    553553    pFilp->private_data = NULL;
    554554    return 0;
  • trunk/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.cpp

    r44173 r47537  
    222222     * Close the session.
    223223     */
    224     supdrvCloseSession(&g_DevExt, pSession);
     224    supdrvSessionRelease(pSession);
    225225    return 0;
    226226}
     
    244244               &&   (   pSession->sfn != sfn
    245245                     || pSession->Process != Process));
     246
     247        if (RT_LIKELY(pSession))
     248            supdrvSessionRetain(pSession);
    246249    }
    247250    RTSpinlockReleaseNoInts(g_Spinlock);
     
    256259     */
    257260    supdrvIOCtlFast(iFunction, 0, &g_DevExt, pSession);
     261    supdrvSessionRelease(pSession);
    258262    return 0;
    259263}
     
    277281               &&   (   pSession->sfn != sfn
    278282                     || pSession->Process != Process));
     283
     284        if (RT_LIKELY(pSession))
     285            supdrvSessionRetain(pSession);
    279286    }
    280287    RTSpinlockReleaseNoInts(g_Spinlock);
     
    346353         */
    347354        int rc2 = KernVMUnlock(&Lock);
    348         AssertMsg(!rc2, ("rc2=%d\n", rc2)); NOREF(rc2);
    349 
    350         Log2(("VBoxDrvIOCtl: returns %d\n", rc));
    351         return rc;
    352     }
    353     return VERR_NOT_SUPPORTED;
     355        AssertMsg(!rc2, ("rc2=%d\n", rc2)); NOREF(rc2);s
     356    }
     357    else
     358        rc = VERR_NOT_SUPPORTED;
     359
     360    supdrvSessionRelease(pSession);
     361    Log2(("VBoxDrvIOCtl: returns %d\n", rc));
     362    return rc;
    354363}
    355364
  • trunk/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c

    r45433 r47537  
    623623     * Close the session.
    624624     */
    625     supdrvCloseSession(&g_DevExt, pSession);
     625    supdrvSessionRelease(pSession);
    626626    return 0;
    627627}
  • trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp

    r44528 r47537  
    386386    if (pSession)
    387387    {
    388         supdrvCloseSession(pDevExt, (PSUPDRVSESSION)pFileObj->FsContext);
     388        supdrvSessionRelease((PSUPDRVSESSION)pFileObj->FsContext);
    389389        pFileObj->FsContext = NULL;
    390390    }
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