--- VirtualBox-7.0.18/src/VBox/Runtime/r0drv/solaris/initterm-r0drv-solaris.c.orig
+++ VirtualBox-7.0.18/src/VBox/Runtime/r0drv/solaris/initterm-r0drv-solaris.c
@@ -78,6 +78,7 @@
 RTR0FNSOLXCCALL                 g_rtSolXcCall;
 /** Whether to use the old-style installctx()/removectx() routines. */
 bool                            g_frtSolOldThreadCtx = false;
+bool                            g_frtillumosNewThreadCtx = false;
 /** The thread-context hooks callout table structure. */
 RTR0FNSOLTHREADCTX              g_rtSolThreadCtx;
 /** Thread preemption offset in the thread structure. */
@@ -222,18 +223,6 @@
         /*
          * Mandatory: Thread-context hooks.
          */
-        rc = RTR0DbgKrnlInfoQuerySymbol(g_hKrnlDbgInfo, NULL /* pszModule */, "exitctx",  NULL /* ppvSymbol */);
-        if (RT_SUCCESS(rc))
-        {
-            g_rtSolThreadCtx.Install.pfnSol_installctx = (void *)installctx;
-            g_rtSolThreadCtx.Remove.pfnSol_removectx   = (void *)removectx;
-        }
-        else
-        {
-            g_frtSolOldThreadCtx = true;
-            g_rtSolThreadCtx.Install.pfnSol_installctx_old = (void *)installctx;
-            g_rtSolThreadCtx.Remove.pfnSol_removectx_old   = (void *)removectx;
-        }
 
         /*
          * Mandatory: map_addr() hooks.
--- VirtualBox-7.0.18/src/VBox/Runtime/r0drv/solaris/the-solaris-kernel.h.orig
+++ VirtualBox-7.0.18/src/VBox/Runtime/r0drv/solaris/the-solaris-kernel.h
@@ -173,6 +173,15 @@
 {
     union
     {
+        void *(*pfnillumos_installctx)    (kthread_t *pThread, void *pvArg,
+                                           void (*pfnSave)(void *pvArg),
+                                           void (*pfnRestore)(void *pvArg),
+                                           void (*pfnFork)(void *pvThread, void *pvThreadFork),
+                                           void (*pfnLwpCreate)(void *pvThread, void *pvThreadCreate),
+                                           void (*pfnExit)(void *pvThread),
+                                           void (*pfnFree)(void *pvArg, int fIsExec),
+                                           void *ctx);
+
         void *(*pfnSol_installctx)        (kthread_t *pThread, void *pvArg,
                                            void (*pfnSave)(void *pvArg),
                                            void (*pfnRestore)(void *pvArg),
@@ -191,6 +200,14 @@
 
     union
     {
+        int (*pfnillumos_removectx)           (kthread_t *pThread, void *pvArg,
+                                           void (*pfnSave)(void *pvArg),
+                                           void (*pfnRestore)(void *pvArg),
+                                           void (*pfnFork)(void *pvThread, void *pvThreadFork),
+                                           void (*pfnLwpCreate)(void *pvThread, void *pvThreadCreate),
+                                           void (*pfnExit)(void *pvThread),
+                                           void (*pfnFree)(void *pvArg, int fIsExec));
+
         int (*pfnSol_removectx)           (kthread_t *pThread, void *pvArg,
                                            void (*pfnSave)(void *pvArg),
                                            void (*pfnRestore)(void *pvArg),
@@ -211,6 +228,7 @@
 
 extern RTR0FNSOLTHREADCTX       g_rtSolThreadCtx;
 extern bool                     g_frtSolOldThreadCtx;
+extern bool                     g_frtillumosNewThreadCtx;
 
 /*
  * Workaround for older Solaris versions which called map_addr()/choose_addr()/
--- VirtualBox-7.0.18/src/VBox/Runtime/r0drv/solaris/threadctxhooks-r0drv-solaris.c.orig
+++ VirtualBox-7.0.18/src/VBox/Runtime/r0drv/solaris/threadctxhooks-r0drv-solaris.c
@@ -163,6 +163,12 @@
     }
 }
 
+static const struct ctxop_template vbox_ctxop_tpl = {
+	.ct_rev		= CTXOP_TPL_REV,
+	.ct_save	= rtThreadCtxHookSolOut,
+	.ct_restore	= rtThreadCtxHookSolIn,
+	.ct_free	= rtThreadCtxHookSolFree
+};
 
 RTDECL(int) RTThreadCtxHookCreate(PRTTHREADCTXHOOK phCtxHook, uint32_t fFlags, PFNRTTHREADCTXHOOK pfnCallback, void *pvUser)
 {
@@ -192,27 +198,7 @@
      * with preemption disabled. We allocate the context-hooks here and use 'fEnabled' to determine if we can
      * invoke the consumer's hook or not.
      */
-    if (g_frtSolOldThreadCtx)
-    {
-        g_rtSolThreadCtx.Install.pfnSol_installctx_old(curthread,
-                                                       pThis,
-                                                       rtThreadCtxHookSolOut,   /* save */
-                                                       rtThreadCtxHookSolIn,    /* restore */
-                                                       NULL,                    /* fork */
-                                                       NULL,                    /* lwp_create */
-                                                       rtThreadCtxHookSolFree);
-    }
-    else
-    {
-        g_rtSolThreadCtx.Install.pfnSol_installctx(curthread,
-                                                   pThis,
-                                                   rtThreadCtxHookSolOut,       /* save */
-                                                   rtThreadCtxHookSolIn,        /* restore */
-                                                   NULL,                        /* fork */
-                                                   NULL,                        /* lwp_create */
-                                                   NULL,                        /* exit */
-                                                   rtThreadCtxHookSolFree);
-    }
+    ctxop_install(curthread, &vbox_ctxop_tpl, pThis);
 
     *phCtxHook = pThis;
     return VINF_SUCCESS;
@@ -254,27 +240,8 @@
          * ring-0 thread dies, Solaris will call rtThreadCtxHookSolFree() which will free the hook object.
          */
         int rc;
-        if (g_frtSolOldThreadCtx)
-        {
-            rc = g_rtSolThreadCtx.Remove.pfnSol_removectx_old(curthread,
-                                                              pThis,
-                                                              rtThreadCtxHookSolOut,    /* save */
-                                                              rtThreadCtxHookSolIn,     /* restore */
-                                                              NULL,                     /* fork */
-                                                              NULL,                     /* lwp_create */
-                                                              rtThreadCtxHookSolFree);
-        }
-        else
-        {
-            rc = g_rtSolThreadCtx.Remove.pfnSol_removectx(curthread,
-                                                          pThis,
-                                                          rtThreadCtxHookSolOut,        /* save */
-                                                          rtThreadCtxHookSolIn,         /* restore */
-                                                          NULL,                         /* fork */
-                                                          NULL,                         /* lwp_create */
-                                                          NULL,                         /* exit */
-                                                          rtThreadCtxHookSolFree);
-        }
+
+	rc = ctxop_remove(curthread, &vbox_ctxop_tpl, pThis);
         AssertMsg(rc, ("removectx() failed. rc=%d\n", rc));
         NOREF(rc);
 
