Index: trunk/src/VBox/HostDrivers/Support/SUPDrv.c
===================================================================
--- trunk/src/VBox/HostDrivers/Support/SUPDrv.c	(revision 47571)
+++ trunk/src/VBox/HostDrivers/Support/SUPDrv.c	(revision 47572)
@@ -367,4 +367,5 @@
     { "RTStrPrintfV",                           (void *)RTStrPrintfV },
     { "RTThreadCreate",                         (void *)RTThreadCreate },
+    { "RTThreadCtxHooksAreRegistered",          (void *)RTThreadCtxHooksAreRegistered },
     { "RTThreadCtxHooksCreate",                 (void *)RTThreadCtxHooksCreate },
     { "RTThreadCtxHooksDeregister",             (void *)RTThreadCtxHooksDeregister },
Index: trunk/src/VBox/Runtime/r0drv/generic/threadctxhooks-r0drv-generic.cpp
===================================================================
--- trunk/src/VBox/Runtime/r0drv/generic/threadctxhooks-r0drv-generic.cpp	(revision 47571)
+++ trunk/src/VBox/Runtime/r0drv/generic/threadctxhooks-r0drv-generic.cpp	(revision 47572)
@@ -75,2 +75,10 @@
 RT_EXPORT_SYMBOL(RTThreadCtxHooksDeregister);
 
+
+RTDECL(bool) RTThreadCtxHooksAreRegistered(RTTHREADCTX hThreadCtx)
+{
+    NOREF(hThreadCtx);
+    return false;
+}
+RT_EXPORT_SYMBOL(RTThreadCtxHooksAreRegistered);
+
Index: trunk/src/VBox/Runtime/r0drv/linux/threadctxhooks-r0drv-linux.c
===================================================================
--- trunk/src/VBox/Runtime/r0drv/linux/threadctxhooks-r0drv-linux.c	(revision 47571)
+++ trunk/src/VBox/Runtime/r0drv/linux/threadctxhooks-r0drv-linux.c	(revision 47572)
@@ -212,5 +212,5 @@
     PRTTHREADCTXINT pThis = hThreadCtx;
     if (pThis == NIL_RTTHREADCTX)
-        return VINF_SUCCESS;
+        return VERR_INVALID_HANDLE;
     AssertPtr(pThis);
     AssertMsgReturn(pThis->u32Magic == RTTHREADCTXINT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis),
@@ -242,5 +242,5 @@
     PRTTHREADCTXINT pThis = hThreadCtx;
     if (pThis == NIL_RTTHREADCTX)
-        return VINF_SUCCESS;
+        return VERR_INVALID_HANDLE;
     AssertPtr(pThis);
     AssertMsgReturn(pThis->u32Magic == RTTHREADCTXINT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis),
@@ -257,4 +257,19 @@
 RT_EXPORT_SYMBOL(RTThreadCtxHooksDeregister);
 
+
+RTDECL(bool) RTThreadCtxHooksAreRegistered(RTTHREADCTX hThreadCtx)
+{
+    /*
+     * Validate input.
+     */
+    PRTTHREADCTXINT pThis = hThreadCtx;
+    if (pThis == NIL_RTTHREADCTX)
+        return false;
+    AssertPtr(pThis);
+    AssertMsg(pThis->u32Magic == RTTHREADCTXINT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis));
+
+    return pThis->fRegistered;
+}
+
 #else    /* Not supported / Not needed */
 
@@ -300,4 +315,12 @@
 RT_EXPORT_SYMBOL(RTThreadCtxHooksDeregister);
 
+
+RTDECL(bool) RTThreadCtxHooksAreRegistered(RTTHREADCTX hThreadCtx)
+{
+    NOREF(hThreadCtx);
+    return false;
+}
+RT_EXPORT_SYMBOL(RTThreadCtxHooksAreRegistered);
+
 #endif   /* Not supported / Not needed */
 
Index: trunk/src/VBox/Runtime/r0drv/solaris/threadctxhooks-r0drv-solaris.c
===================================================================
--- trunk/src/VBox/Runtime/r0drv/solaris/threadctxhooks-r0drv-solaris.c	(revision 47571)
+++ trunk/src/VBox/Runtime/r0drv/solaris/threadctxhooks-r0drv-solaris.c	(revision 47572)
@@ -281,5 +281,5 @@
     PRTTHREADCTXINT pThis = hThreadCtx;
     if (pThis == NIL_RTTHREADCTX)
-        return VINF_SUCCESS;
+        return VERR_INVALID_HANDLE;
     AssertPtr(pThis);
     AssertMsgReturn(pThis->u32Magic == RTTHREADCTXINT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis),
@@ -305,5 +305,5 @@
     PRTTHREADCTXINT pThis = hThreadCtx;
     if (pThis == NIL_RTTHREADCTX)
-        return VINF_SUCCESS;
+        return VERR_INVALID_HANDLE;
     AssertPtr(pThis);
     AssertMsgReturn(pThis->u32Magic == RTTHREADCTXINT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis),
@@ -320,2 +320,17 @@
 }
 
+
+RTDECL(bool) RTThreadCtxHooksAreRegistered(RTTHREADCTX hThreadCtx)
+{
+    /*
+     * Validate input.
+     */
+    PRTTHREADCTXINT pThis = hThreadCtx;
+    if (pThis == NIL_RTTHREADCTX)
+        return false;
+    AssertPtr(pThis);
+    AssertMsg(pThis->u32Magic == RTTHREADCTXINT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis));
+
+    return pThis->fRegistered;
+}
+
Index: trunk/src/VBox/Runtime/testcase/tstR0ThreadPreemption.cpp
===================================================================
--- trunk/src/VBox/Runtime/testcase/tstR0ThreadPreemption.cpp	(revision 47571)
+++ trunk/src/VBox/Runtime/testcase/tstR0ThreadPreemption.cpp	(revision 47572)
@@ -299,4 +299,11 @@
             }
 
+            bool fRegistered = RTThreadCtxHooksAreRegistered(NIL_RTTHREADCTX);
+            if (fRegistered)
+            {
+                RTStrPrintf(pszErr, cchErr, "!RTThreadCtxHooksAreRegistered returns true before creating any hooks");
+                break;
+            }
+
             RTTHREADCTX hThreadCtx;
             int rc = RTThreadCtxHooksCreate(&hThreadCtx);
@@ -307,4 +314,12 @@
                 else
                     RTStrPrintf(pszErr, cchErr, "!RTThreadCtxHooksCreate returns %Rrc", rc);
+                break;
+            }
+
+            fRegistered = RTThreadCtxHooksAreRegistered(hThreadCtx);
+            if (fRegistered)
+            {
+                RTStrPrintf(pszErr, cchErr, "!RTThreadCtxHooksAreRegistered returns true before registering any hooks");
+                RTThreadCtxHooksRelease(hThreadCtx);
                 break;
             }
@@ -330,4 +345,5 @@
             if (RT_FAILURE(rc))
             {
+                RTThreadPreemptRestore(&PreemptState);
                 RTMemFree(pCtxData);
                 RTStrPrintf(pszErr, cchErr, "!RTThreadCtxHooksRegister returns %Rrc", rc);
@@ -335,14 +351,24 @@
             }
 
+            fRegistered = RTThreadCtxHooksAreRegistered(hThreadCtx);
+            if (!fRegistered)
+            {
+                RTThreadPreemptRestore(&PreemptState);
+                RTMemFree(pCtxData);
+                RTStrPrintf(pszErr, cchErr, "!RTThreadCtxHooksAreRegistered return false when hooks are supposedly registered");
+                break;
+            }
+
             RTThreadPreemptRestore(&PreemptState);
 
             /* Check if the preempting callback has/will been invoked. */
-            const uint32_t  cMsTimeout           = 8000;
+            const uint32_t  cMsTimeout           = 10000;
             const uint32_t  cMsSleepGranularity  = 50;
             uint32_t        cMsSlept             = 0;
+            RTCPUID         uCurrentCpuId        = NIL_RTCPUID;
             for (;;)
             {
                 RTThreadPreemptDisable(&PreemptState);
-                const RTCPUID uCurrentCpuId = RTMpCpuId();
+                uCurrentCpuId = RTMpCpuId();
                 RTThreadPreemptRestore(&PreemptState);
 
@@ -359,6 +385,15 @@
             if (!ASMAtomicReadBool(&pCtxData->fPreemptingInvoked))
             {
-                RTStrPrintf(pszErr, cchErr, "!tstR0ThreadCtxHooks[RTTHREADCTXEVENT_PREEMPTING] not invoked after ca. %u ms",
-                            cMsSlept);
+                if (pCtxData->uSourceCpuId != uCurrentCpuId)
+                {
+                    RTStrPrintf(pszErr, cchErr,
+                                "!tstR0ThreadCtxHooks[RTTHREADCTXEVENT_PREEMPTING] not invoked before migrating from CPU %RU32 to %RU32",
+                                pCtxData->uSourceCpuId, uCurrentCpuId);
+                }
+                else
+                {
+                    RTStrPrintf(pszErr, cchErr, "!tstR0ThreadCtxHooks[RTTHREADCTXEVENT_PREEMPTING] not invoked after ca. %u ms",
+                                cMsSlept);
+                }
             }
             else if (!pCtxData->fPreemptingSuccess)
@@ -391,4 +426,12 @@
             RTThreadCtxHooksDeregister(hThreadCtx);
 
+            fRegistered = RTThreadCtxHooksAreRegistered(hThreadCtx);
+            if (fRegistered)
+            {
+                RTMemFree(pCtxData);
+                RTStrPrintf(pszErr, cchErr, "!RTThreadCtxHooksAreRegistered return true when hooks are deregistered");
+                break;
+            }
+
             Assert(RTThreadPreemptIsEnabled(NIL_RTTHREAD));
             uint32_t cRefs = RTThreadCtxHooksRelease(hThreadCtx);
