Index: /trunk/include/VBox/vmm/hm.h
===================================================================
--- /trunk/include/VBox/vmm/hm.h	(revision 54711)
+++ /trunk/include/VBox/vmm/hm.h	(revision 54712)
@@ -179,5 +179,5 @@
 VMMR0_INT_DECL(void)            HMR0SavePendingIOPortRead(PVMCPU pVCpu, RTGCPTR GCPtrRip, RTGCPTR GCPtrRipNext,
                                                           unsigned uPort, unsigned uAndVal, unsigned cbSize);
-/** Disables preemption if required. */
+#ifdef VBOX_STRICT
 # define HM_DISABLE_PREEMPT_IF_NEEDED() \
     RTTHREADPREEMPTSTATE PreemptStateInternal = RTTHREADPREEMPTSTATE_INITIALIZER; \
@@ -190,5 +190,4 @@
     } else do { } while (0)
 
-/** Restores preemption if previously disabled by HM_DISABLE_PREEMPT(). */
 # define HM_RESTORE_PREEMPT_IF_NEEDED() \
     do \
@@ -197,4 +196,11 @@
             RTThreadPreemptRestore(&PreemptStateInternal); \
     } while (0)
+#else
+# define HM_DISABLE_PREEMPT_IF_NEEDED() \
+    RTTHREADPREEMPTSTATE PreemptStateInternal = RTTHREADPREEMPTSTATE_INITIALIZER; \
+    RTThreadPreemptDisable(&PreemptStateInternal);
+
+# define HM_RESTORE_PREEMPT_IF_NEEDED() do { RTThreadPreemptRestore(&PreemptStateInternal); } while(0)
+#endif /* VBOX_STRICT */
 
 VMMR0_INT_DECL(int)             HMR0SetupVM(PVM pVM);
Index: /trunk/src/VBox/VMM/VMMR0/HMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HMR0.cpp	(revision 54711)
+++ /trunk/src/VBox/VMM/VMMR0/HMR0.cpp	(revision 54712)
@@ -1427,7 +1427,4 @@
     /* Clear it while leaving HM context, hmPokeCpuForTlbFlush() relies on this. */
     pVCpu->hm.s.idEnteredCpu = NIL_RTCPUID;
-
-    /* Clear the VCPU <-> host CPU mapping as we've left HM context (for the preemption hook case). */
-    ASMAtomicWriteU32(&pVCpu->idHostCpu, NIL_RTCPUID);
 
     return VINF_SUCCESS;
Index: /trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp	(revision 54711)
+++ /trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp	(revision 54712)
@@ -2097,6 +2097,5 @@
 
     /* Deregister hook now that we've left HM context before re-enabling preemption. */
-    if (VMMR0ThreadCtxHooksAreRegistered(pVCpu))
-        VMMR0ThreadCtxHooksDeregister(pVCpu);
+    VMMR0ThreadCtxHooksDeregister(pVCpu);
 
     /* Leave HM context. This takes care of local init (term). */
@@ -2154,7 +2153,6 @@
         CPUMR0DebugStateMaybeSaveGuestAndRestoreHost(pVCpu, false /* save DR6 */);
 
-        /* Deregister hook now that we've left HM context before re-enabling preemption. */
-        if (VMMR0ThreadCtxHooksAreRegistered(pVCpu))
-            VMMR0ThreadCtxHooksDeregister(pVCpu);
+        /* Deregister the hook now that we've left HM context before re-enabling preemption. */
+        VMMR0ThreadCtxHooksDeregister(pVCpu);
 
         /* Leave HM context. This takes care of local init (term). */
Index: /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 54711)
+++ /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 54712)
@@ -7108,8 +7108,7 @@
 
     /* Deregister hook now that we've left HM context before re-enabling preemption. */
-    /** @todo This is bad. Deregistering here means we need to VMCLEAR always
+    /** @todo Deregistering here means we need to VMCLEAR always
      *        (longjmp/exit-to-r3) in VT-x which is not efficient. */
-    if (VMMR0ThreadCtxHooksAreRegistered(pVCpu))
-        VMMR0ThreadCtxHooksDeregister(pVCpu);
+    VMMR0ThreadCtxHooksDeregister(pVCpu);
 
     /* Leave HM context. This takes care of local init (term). */
@@ -7278,6 +7277,5 @@
         }
 
-        if (VMMR0ThreadCtxHooksAreRegistered(pVCpu))
-            VMMR0ThreadCtxHooksDeregister(pVCpu);
+        VMMR0ThreadCtxHooksDeregister(pVCpu);
 
         HMR0LeaveCpu(pVCpu);
Index: /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp	(revision 54711)
+++ /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp	(revision 54712)
@@ -510,5 +510,14 @@
 VMMR0DECL(int) VMMR0ThreadCtxHooksDeregister(PVMCPU pVCpu)
 {
-    return RTThreadCtxHooksDeregister(pVCpu->vmm.s.hR0ThreadCtx);
+    if (pVCpu->vmm.s.hR0ThreadCtx != NIL_RTTHREADCTX)
+    {
+        Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));
+        int rc = RTThreadCtxHooksDeregister(pVCpu->vmm.s.hR0ThreadCtx);
+        AssertRCReturn(rc, rc);
+    }
+
+    /* Clear the VCPU <-> host CPU mapping as we've left HM context. See @bugref{7726} comment #19. */
+    ASMAtomicWriteU32(&pVCpu->idHostCpu, NIL_RTCPUID);
+    return VINF_SUCCESS;
 }
 
