Index: trunk/src/VBox/HostDrivers/Support/SUPDrv.c
===================================================================
--- trunk/src/VBox/HostDrivers/Support/SUPDrv.c	(revision 47536)
+++ trunk/src/VBox/HostDrivers/Support/SUPDrv.c	(revision 47537)
@@ -697,4 +697,5 @@
                 pSession->u32Cookie         = BIRD_INV;
                 pSession->fUnrestricted     = fUnrestricted;
+                pSession->cRefs             = 1;
                 /*pSession->pLdrUsage         = NULL;
                 pSession->pVM               = NULL;
@@ -742,5 +743,8 @@
 
 /**
- * Shared code for cleaning up a session.
+ * Shared code for cleaning up a session (but not quite freeing it).
+ *
+ * This is primarily intended for MAC OS X where we have to clean up the memory
+ * stuff before the file handle is closed.
  *
  * @param   pDevExt     Device extension.
@@ -748,35 +752,5 @@
  *                      This data will be freed by this routine.
  */
-void VBOXCALL supdrvCloseSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession)
-{
-    VBOXDRV_SESSION_CLOSE(pSession);
-
-    /*
-     * Cleanup the session first.
-     */
-    supdrvCleanupSession(pDevExt, pSession);
-
-    /*
-     * Free the rest of the session stuff.
-     */
-    RTSpinlockDestroy(pSession->Spinlock);
-    pSession->Spinlock = NIL_RTSPINLOCK;
-    pSession->pDevExt = NULL;
-    RTMemFree(pSession);
-    LogFlow(("supdrvCloseSession: returns\n"));
-}
-
-
-/**
- * Shared code for cleaning up a session (but not quite freeing it).
- *
- * This is primarily intended for MAC OS X where we have to clean up the memory
- * stuff before the file handle is closed.
- *
- * @param   pDevExt     Device extension.
- * @param   pSession    Session data.
- *                      This data will be freed by this routine.
- */
-void VBOXCALL supdrvCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession)
+static void supdrvCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession)
 {
     int                 rc;
@@ -985,4 +959,65 @@
 }
 
+
+/**
+ * Shared code for cleaning up a session.
+ *
+ * @param   pDevExt     Device extension.
+ * @param   pSession    Session data.
+ *                      This data will be freed by this routine.
+ */
+static void supdrvCloseSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession)
+{
+    VBOXDRV_SESSION_CLOSE(pSession);
+
+    /*
+     * Cleanup the session first.
+     */
+    supdrvCleanupSession(pDevExt, pSession);
+
+    /*
+     * Free the rest of the session stuff.
+     */
+    RTSpinlockDestroy(pSession->Spinlock);
+    pSession->Spinlock = NIL_RTSPINLOCK;
+    pSession->pDevExt = NULL;
+    RTMemFree(pSession);
+    LogFlow(("supdrvCloseSession: returns\n"));
+}
+
+
+/**
+ * Retain a session to make sure it doesn't go away while it is in use.
+ *
+ * @returns New reference count on success, UINT32_MAX on failure.
+ * @param   pSession    Session data.
+ */
+uint32_t VBOXCALL supdrvSessionRetain(PSUPDRVSESSION pSession)
+{
+    AssertPtrReturn(pSession, UINT32_MAX);
+    AssertReturn(SUP_IS_SESSION_VALID(pSession), UINT32_MAX);
+
+    uint32_t cRefs = ASMAtomicIncU32(&pSession->cRefs);
+    AssertMsg(cRefs > 1 && cRefs < _1M, ("%#x %p\n", cRefs, pSession));
+    return cRefs;
+}
+
+/**
+ * Releases a given session.
+ *
+ * @returns New reference count on success (0 if closed), UINT32_MAX on failure.
+ * @param   pSession    Session data.
+ */
+uint32_t VBOXCALL supdrvSessionRelease(PSUPDRVSESSION pSession)
+{
+    AssertPtrReturn(pSession, UINT32_MAX);
+    AssertReturn(SUP_IS_SESSION_VALID(pSession), UINT32_MAX);
+
+    uint32_t cRefs = ASMAtomicDecU32(&pSession->cRefs);
+    AssertMsg(cRefs < _1M, ("%#x %p\n", cRefs, pSession));
+    if (cRefs == 0)
+        supdrvCloseSession(pSession->pDevExt, pSession);
+    return cRefs;
+}
 
 /**
@@ -2121,5 +2156,5 @@
             REQ_CHECK_IDC_SIZE(SUPDRV_IDC_REQ_DISCONNECT, sizeof(*pReqHdr));
 
-            supdrvCloseSession(pDevExt, pSession);
+            supdrvSessionRelease(pSession);
             return pReqHdr->rc = VINF_SUCCESS;
         }
Index: trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h
===================================================================
--- trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h	(revision 47536)
+++ trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h	(revision 47537)
@@ -419,4 +419,6 @@
     /** Set if is an unrestricted session, clear if restricted. */
     bool                            fUnrestricted;
+    /* Reference counter. */
+    uint32_t volatile               cRefs;
 
     /** The VM associated with the session. */
@@ -693,6 +695,6 @@
 void VBOXCALL   supdrvDeleteDevExt(PSUPDRVDEVEXT pDevExt);
 int  VBOXCALL   supdrvCreateSession(PSUPDRVDEVEXT pDevExt, bool fUser, bool fUnrestricted,  PSUPDRVSESSION *ppSession);
-void VBOXCALL   supdrvCloseSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession);
-void VBOXCALL   supdrvCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession);
+uint32_t VBOXCALL supdrvSessionRetain(PSUPDRVSESSION pSession);
+uint32_t VBOXCALL supdrvSessionRelease(PSUPDRVSESSION pSession);
 
 int  VBOXCALL   supdrvTracerInit(PSUPDRVDEVEXT pDevExt);
Index: trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp
===================================================================
--- trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp	(revision 47536)
+++ trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp	(revision 47537)
@@ -524,4 +524,7 @@
     while (pSession && pSession->Process != Process && pSession->fUnrestricted == fUnrestricted && pSession->fOpened)
         pSession = pSession->pNextHash;
+
+    if (RT_LIKELY(pSession))
+        supdrvSessionRetain(pSession);
     RTSpinlockReleaseNoInts(g_Spinlock);
     if (!pSession)
@@ -536,10 +539,15 @@
      * the session and iCmd, and only returns a VBox status code.
      */
+    int rc;
     if (   (    iCmd == SUP_IOCTL_FAST_DO_RAW_RUN
             ||  iCmd == SUP_IOCTL_FAST_DO_HM_RUN
             ||  iCmd == SUP_IOCTL_FAST_DO_NOP)
         && fUnrestricted)
-        return supdrvIOCtlFast(iCmd, *(uint32_t *)pData, &g_DevExt, pSession);
-    return VBoxDrvDarwinIOCtlSlow(pSession, iCmd, pData, pProcess);
+        rc = supdrvIOCtlFast(iCmd, *(uint32_t *)pData, &g_DevExt, pSession);
+    else
+        rc = VBoxDrvDarwinIOCtlSlow(pSession, iCmd, pData, pProcess);
+
+    supdrvSessionRelease(pSession);
+    return rc;
 }
 
@@ -1155,5 +1163,5 @@
 
                 LogFlow(("org_virtualbox_SupDrvClient::start: already got a session for this process (%p)\n", pCur));
-                supdrvCloseSession(&g_DevExt, m_pSession);
+                supdrvSessionRelease(m_pSession);
             }
 
@@ -1231,5 +1239,5 @@
      * Close the session.
      */
-    supdrvCloseSession(&g_DevExt, pSession);
+    supdrvSessionRelease(pSession);
 }
 
Index: trunk/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c
===================================================================
--- trunk/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c	(revision 47536)
+++ trunk/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c	(revision 47537)
@@ -292,5 +292,5 @@
      * Close the session.
      */
-    supdrvCloseSession(&g_VBoxDrvFreeBSDDevExt, pSession);
+    supdrvSessionRelease(&g_VBoxDrvFreeBSDDevExt, pSession);
     ASMAtomicDecU32(&g_cUsers);
 }
Index: trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
===================================================================
--- trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c	(revision 47536)
+++ trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c	(revision 47537)
@@ -550,5 +550,5 @@
     Log(("VBoxDrvLinuxClose: pFilp=%p pSession=%p pid=%d/%d %s\n",
          pFilp, pFilp->private_data, RTProcSelf(), current->pid, current->comm));
-    supdrvCloseSession(&g_DevExt, (PSUPDRVSESSION)pFilp->private_data);
+    supdrvSessionRelease((PSUPDRVSESSION)pFilp->private_data);
     pFilp->private_data = NULL;
     return 0;
Index: trunk/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.cpp
===================================================================
--- trunk/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.cpp	(revision 47536)
+++ trunk/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.cpp	(revision 47537)
@@ -222,5 +222,5 @@
      * Close the session.
      */
-    supdrvCloseSession(&g_DevExt, pSession);
+    supdrvSessionRelease(pSession);
     return 0;
 }
@@ -244,4 +244,7 @@
                &&   (   pSession->sfn != sfn
                      || pSession->Process != Process));
+
+        if (RT_LIKELY(pSession))
+            supdrvSessionRetain(pSession);
     }
     RTSpinlockReleaseNoInts(g_Spinlock);
@@ -256,4 +259,5 @@
      */
     supdrvIOCtlFast(iFunction, 0, &g_DevExt, pSession);
+    supdrvSessionRelease(pSession);
     return 0;
 }
@@ -277,4 +281,7 @@
                &&   (   pSession->sfn != sfn
                      || pSession->Process != Process));
+
+        if (RT_LIKELY(pSession))
+            supdrvSessionRetain(pSession);
     }
     RTSpinlockReleaseNoInts(g_Spinlock);
@@ -346,10 +353,12 @@
          */
         int rc2 = KernVMUnlock(&Lock);
-        AssertMsg(!rc2, ("rc2=%d\n", rc2)); NOREF(rc2);
-
-        Log2(("VBoxDrvIOCtl: returns %d\n", rc));
-        return rc;
-    }
-    return VERR_NOT_SUPPORTED;
+        AssertMsg(!rc2, ("rc2=%d\n", rc2)); NOREF(rc2);s
+    }
+    else
+        rc = VERR_NOT_SUPPORTED;
+
+    supdrvSessionRelease(pSession);
+    Log2(("VBoxDrvIOCtl: returns %d\n", rc));
+    return rc;
 }
 
Index: trunk/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c
===================================================================
--- trunk/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c	(revision 47536)
+++ trunk/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c	(revision 47537)
@@ -623,5 +623,5 @@
      * Close the session.
      */
-    supdrvCloseSession(&g_DevExt, pSession);
+    supdrvSessionRelease(pSession);
     return 0;
 }
Index: trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
===================================================================
--- trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp	(revision 47536)
+++ trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp	(revision 47537)
@@ -386,5 +386,5 @@
     if (pSession)
     {
-        supdrvCloseSession(pDevExt, (PSUPDRVSESSION)pFileObj->FsContext);
+        supdrvSessionRelease((PSUPDRVSESSION)pFileObj->FsContext);
         pFileObj->FsContext = NULL;
     }
