Index: /trunk/include/VBox/vmm/gvmm.h
===================================================================
--- /trunk/include/VBox/vmm/gvmm.h	(revision 68010)
+++ /trunk/include/VBox/vmm/gvmm.h	(revision 68011)
@@ -160,7 +160,7 @@
 
 GVMMR0DECL(int)     GVMMR0CreateVM(PSUPDRVSESSION pSession, uint32_t cCpus, PVM *ppVM);
-GVMMR0DECL(int)     GVMMR0InitVM(PVM pVM);
-GVMMR0DECL(void)    GVMMR0DoneInitVM(PVM pVM);
-GVMMR0DECL(bool)    GVMMR0DoingTermVM(PVM pVM, PGVM pGVM);
+GVMMR0DECL(int)     GVMMR0InitVM(PGVM pGVM);
+GVMMR0DECL(void)    GVMMR0DoneInitVM(PGVM pGVM);
+GVMMR0DECL(bool)    GVMMR0DoingTermVM(PGVM pGVM);
 GVMMR0DECL(int)     GVMMR0DestroyVM(PGVM pGVM, PVM pVM);
 GVMMR0DECL(int)     GVMMR0RegisterVCpu(PGVM pGVM, PVM pVM, VMCPUID idCpu);
Index: /trunk/include/VBox/vmm/vmm.h
===================================================================
--- /trunk/include/VBox/vmm/vmm.h	(revision 68010)
+++ /trunk/include/VBox/vmm/vmm.h	(revision 68011)
@@ -523,5 +523,5 @@
 VMMR0DECL(int)       VMMR0EntryEx(PGVM pGVM, PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation,
                                   PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION);
-VMMR0_INT_DECL(int)  VMMR0TermVM(PVM pVM, PGVM pGVM);
+VMMR0_INT_DECL(int)  VMMR0TermVM(PGVM pGVM, PVM pVM, VMCPUID idCpu);
 VMMR0_INT_DECL(bool) VMMR0IsLongJumpArmed(PVMCPU pVCpu);
 VMMR0_INT_DECL(bool) VMMR0IsInRing3LongJump(PVMCPU pVCpu);
Index: /trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp	(revision 68010)
+++ /trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp	(revision 68011)
@@ -359,6 +359,4 @@
 static void gvmmR0InitPerVMData(PGVM pGVM);
 static DECLCALLBACK(void) gvmmR0HandleObjDestructor(void *pvObj, void *pvGVMM, void *pvHandle);
-static int gvmmR0ByVM(PVM pVM, PGVM *ppGVM, PGVMM *ppGVMM, bool fTakeUsedLock);
-static int gvmmR0ByVMAndEMT(PVM pVM, VMCPUID idCpu, PGVM *ppGVM, PGVMM *ppGVMM);
 static int gvmmR0ByGVMandVM(PGVM pGVM, PVM pVM, PGVMM *ppGVMM, bool fTakeUsedLock);
 static int gvmmR0ByGVMandVMandEMT(PGVM pGVM, PVM pVM, VMCPUID idCpu, PGVMM *ppGVMM);
@@ -1070,34 +1068,26 @@
  *
  * @returns VBox status code.
- * @param   pVM         The cross context VM structure.
- */
-GVMMR0DECL(int) GVMMR0InitVM(PVM pVM)
-{
-    LogFlow(("GVMMR0InitVM: pVM=%p\n", pVM));
-
-    /*
-     * Validate the VM structure, state and handle.
-     */
-    PGVM pGVM;
-    PGVMM pGVMM;
-    int rc = gvmmR0ByVMAndEMT(pVM, 0 /* idCpu */, &pGVM, &pGVMM);
-    if (RT_SUCCESS(rc))
-    {
-        if (   !pGVM->gvmm.s.fDoneVMMR0Init
-            && pGVM->aCpus[0].gvmm.s.HaltEventMulti == NIL_RTSEMEVENTMULTI)
-        {
-            for (VMCPUID i = 0; i < pGVM->cCpus; i++)
+ * @param   pGVM        The global (ring-0) VM structure.
+ */
+GVMMR0DECL(int) GVMMR0InitVM(PGVM pGVM)
+{
+    LogFlow(("GVMMR0InitVM: pGVM=%p\n", pGVM));
+
+    int rc = VERR_INTERNAL_ERROR_3;
+    if (   !pGVM->gvmm.s.fDoneVMMR0Init
+        && pGVM->aCpus[0].gvmm.s.HaltEventMulti == NIL_RTSEMEVENTMULTI)
+    {
+        for (VMCPUID i = 0; i < pGVM->cCpus; i++)
+        {
+            rc = RTSemEventMultiCreate(&pGVM->aCpus[i].gvmm.s.HaltEventMulti);
+            if (RT_FAILURE(rc))
             {
-                rc = RTSemEventMultiCreate(&pGVM->aCpus[i].gvmm.s.HaltEventMulti);
-                if (RT_FAILURE(rc))
-                {
-                    pGVM->aCpus[i].gvmm.s.HaltEventMulti = NIL_RTSEMEVENTMULTI;
-                    break;
-                }
+                pGVM->aCpus[i].gvmm.s.HaltEventMulti = NIL_RTSEMEVENTMULTI;
+                break;
             }
         }
-        else
-            rc = VERR_WRONG_ORDER;
-    }
+    }
+    else
+        rc = VERR_WRONG_ORDER;
 
     LogFlow(("GVMMR0InitVM: returns %Rrc\n", rc));
@@ -1110,15 +1100,9 @@
  * of the VM.
  *
- * @param   pVM         The cross context VM structure.
+ * @param   pGVM        The global (ring-0) VM structure.
  * @thread  EMT(0)
  */
-GVMMR0DECL(void) GVMMR0DoneInitVM(PVM pVM)
-{
-    /* Validate the VM structure, state and handle. */
-    PGVM pGVM;
-    PGVMM pGVMM;
-    int rc = gvmmR0ByVMAndEMT(pVM, 0 /* idCpu */, &pGVM, &pGVMM);
-    AssertRCReturnVoid(rc);
-
+GVMMR0DECL(void) GVMMR0DoneInitVM(PGVM pGVM)
+{
     /* Set the indicator. */
     pGVM->gvmm.s.fDoneVMMR0Init = true;
@@ -1130,19 +1114,11 @@
  *
  * @returns true if termination hasn't been done already, false if it has.
- * @param   pVM         The cross context VM structure.
  * @param   pGVM        Pointer to the global VM structure. Optional.
- * @thread  EMT(0)
- */
-GVMMR0DECL(bool) GVMMR0DoingTermVM(PVM pVM, PGVM pGVM)
+ * @thread  EMT(0) or session cleanup thread.
+ */
+GVMMR0DECL(bool) GVMMR0DoingTermVM(PGVM pGVM)
 {
     /* Validate the VM structure, state and handle. */
-    AssertPtrNullReturn(pGVM, false);
-    AssertReturn(!pGVM || pGVM->u32Magic == GVM_MAGIC, false);
-    if (!pGVM)
-    {
-        PGVMM pGVMM;
-        int rc = gvmmR0ByVMAndEMT(pVM, 0 /* idCpu */, &pGVM, &pGVMM);
-        AssertRCReturn(rc, false);
-    }
+    AssertPtrReturn(pGVM, false);
 
     /* Set the indicator. */
@@ -1260,5 +1236,5 @@
         {
             LogFlow(("gvmmR0CleanupVM: Calling VMMR0TermVM\n"));
-            VMMR0TermVM(pGVM->pVM, pGVM);
+            VMMR0TermVM(pGVM, pGVM->pVM, NIL_RTCPUID);
         }
         else
@@ -1763,54 +1739,4 @@
     PGVMM pGVMM;
     return gvmmR0ByVM(pVM, ppGVM, &pGVMM, false /* fTakeUsedLock */);
-}
-
-
-/**
- * Lookup a GVM structure by the shared VM structure and ensuring that the
- * caller is an EMT thread.
- *
- * @returns VBox status code.
- * @param   pVM         The cross context VM structure.
- * @param   idCpu       The Virtual CPU ID of the calling EMT.
- * @param   ppGVM       Where to store the GVM pointer.
- * @param   ppGVMM      Where to store the pointer to the GVMM instance data.
- * @thread  EMT
- *
- * @remarks This will assert in all failure paths.
- */
-static int gvmmR0ByVMAndEMT(PVM pVM, VMCPUID idCpu, PGVM *ppGVM, PGVMM *ppGVMM)
-{
-    PGVMM pGVMM;
-    GVMM_GET_VALID_INSTANCE(pGVMM, VERR_GVMM_INSTANCE);
-
-    /*
-     * Validate.
-     */
-    AssertPtrReturn(pVM, VERR_INVALID_POINTER);
-    AssertReturn(!((uintptr_t)pVM & PAGE_OFFSET_MASK), VERR_INVALID_POINTER);
-
-    uint16_t hGVM = pVM->hSelf;
-    AssertReturn(hGVM != NIL_GVM_HANDLE, VERR_INVALID_HANDLE);
-    AssertReturn(hGVM < RT_ELEMENTS(pGVMM->aHandles), VERR_INVALID_HANDLE);
-
-    /*
-     * Look it up.
-     */
-    PGVMHANDLE pHandle = &pGVMM->aHandles[hGVM];
-    AssertReturn(pHandle->pVM == pVM, VERR_NOT_OWNER);
-    RTPROCESS ProcId = RTProcSelf();
-    AssertReturn(pHandle->ProcId == ProcId, VERR_NOT_OWNER);
-    AssertPtrReturn(pHandle->pvObj, VERR_NOT_OWNER);
-
-    PGVM pGVM = pHandle->pGVM;
-    AssertPtrReturn(pGVM, VERR_NOT_OWNER);
-    AssertReturn(pGVM->pVM == pVM, VERR_NOT_OWNER);
-    RTNATIVETHREAD hAllegedEMT = RTThreadNativeSelf();
-    AssertReturn(idCpu < pGVM->cCpus, VERR_INVALID_CPU_ID);
-    AssertReturn(pGVM->aCpus[idCpu].hEMT == hAllegedEMT, VERR_NOT_OWNER);
-
-    *ppGVM = pGVM;
-    *ppGVMM = pGVMM;
-    return VINF_SUCCESS;
 }
 
Index: /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp	(revision 68010)
+++ /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp	(revision 68011)
@@ -349,10 +349,11 @@
  * @returns VBox status code.
  *
+ * @param   pGVM        The global (ring-0) VM structure.
  * @param   pVM         The cross context VM structure.
  * @param   uSvnRev     The SVN revision of the ring-3 part.
  * @param   uBuildType  Build type indicator.
- * @thread  EMT.
- */
-static int vmmR0InitVM(PVM pVM, uint32_t uSvnRev, uint32_t uBuildType)
+ * @thread  EMT(0)
+ */
+static int vmmR0InitVM(PGVM pGVM, PVM pVM, uint32_t uSvnRev, uint32_t uBuildType)
 {
     VMM_CHECK_SMAP_SETUP();
@@ -374,7 +375,8 @@
         return VERR_VMM_R0_VERSION_MISMATCH;
     }
-    if (    !VALID_PTR(pVM)
-        ||  pVM->pVMR0 != pVM)
-        return VERR_INVALID_PARAMETER;
+
+    int rc = GVMMR0ValidateGVMandVMandEMT(pGVM, pVM, 0 /*idCpu*/);
+    if (RT_FAILURE(rc))
+        return rc;
 
 
@@ -435,5 +437,5 @@
      */
     VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
-    int rc = GVMMR0InitVM(pVM);
+    rc = GVMMR0InitVM(pGVM);
 //    if (RT_SUCCESS(rc))
 //        rc = GMMR0InitPerVMData(pVM);
@@ -471,5 +473,5 @@
                             if (RT_SUCCESS(rc))
                             {
-                                GVMMR0DoneInitVM(pVM);
+                                GVMMR0DoneInitVM(pGVM);
                                 VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
                                 return rc;
@@ -503,10 +505,23 @@
  * @returns VBox status code.
  *
+ * @param   pGVM        The global (ring-0) VM structure.
  * @param   pVM         The cross context VM structure.
- * @param   pGVM        Pointer to the global VM structure. Optional.
- * @thread  EMT or session clean up thread.
- */
-VMMR0_INT_DECL(int) VMMR0TermVM(PVM pVM, PGVM pGVM)
-{
+ * @param   idCpu       Set to 0 if EMT(0) or NIL_VMCPUID if session cleanup
+ *                      thread.
+ * @thread  EMT(0) or session clean up thread.
+ */
+VMMR0_INT_DECL(int) VMMR0TermVM(PGVM pGVM, PVM pVM, VMCPUID idCpu)
+{
+    /*
+     * Check EMT(0) claim if we're called from userland.
+     */
+    if (idCpu != NIL_VMCPUID)
+    {
+        AssertReturn(idCpu == 0, VERR_INVALID_CPU_ID);
+        int rc = GVMMR0ValidateGVMandVMandEMT(pGVM, pVM, idCpu);
+        if (RT_FAILURE(rc))
+            return rc;
+    }
+
 #ifdef VBOX_WITH_PCI_PASSTHROUGH
     PciRawR0TermVM(pVM);
@@ -516,5 +531,5 @@
      * Tell GVMM what we're up to and check that we only do this once.
      */
-    if (GVMMR0DoingTermVM(pVM, pGVM))
+    if (GVMMR0DoingTermVM(pGVM))
     {
         GIMR0TermVM(pVM);
@@ -1507,5 +1522,5 @@
          */
         case VMMR0_DO_VMMR0_INIT:
-            rc = vmmR0InitVM(pVM, RT_LODWORD(u64Arg), RT_HIDWORD(u64Arg));
+            rc = vmmR0InitVM(pGVM, pVM, RT_LODWORD(u64Arg), RT_HIDWORD(u64Arg));
             VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
             break;
@@ -1515,5 +1530,5 @@
          */
         case VMMR0_DO_VMMR0_TERM:
-            rc = VMMR0TermVM(pVM, NULL);
+            rc = VMMR0TermVM(pGVM, pVM, 0 /*idCpu*/);
             VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
             break;
