Index: /trunk/Config.kmk
===================================================================
--- /trunk/Config.kmk	(revision 92407)
+++ /trunk/Config.kmk	(revision 92408)
@@ -2003,5 +2003,5 @@
  VBOX_LIB_XPCOM_X86     = $(PATH_STAGE_BIN)/VBoxXPCOM-x86.dylib
  LIB_DDU         = $(PATH_STAGE_BIN)/VBoxDDU.dylib
- VBOX_LIB_SUPR0  = $(PATH_STAGE_LIB)/SUPR0$(VBOX_SUFF_LIB)
+ VBOX_LIB_SUPR0 :=
 endif
 if1of ($(KBUILD_TARGET), freebsd haiku linux netbsd openbsd solaris)
Index: /trunk/include/VBox/err.h
===================================================================
--- /trunk/include/VBox/err.h	(revision 92407)
+++ /trunk/include/VBox/err.h	(revision 92408)
@@ -1273,16 +1273,6 @@
  * complete or try with a clean build. */
 #define VERR_VMM_RC_VERSION_MISMATCH        (-2705)
-/** VMM set jump error. */
-#define VERR_VMM_SET_JMP_ERROR              (-2706)
-/** VMM set jump stack overflow error. */
-#define VERR_VMM_SET_JMP_STACK_OVERFLOW     (-2707)
-/** VMM set jump resume error. */
-#define VERR_VMM_SET_JMP_ABORTED_RESUME     (-2708)
 /** VMM long jump error. */
 #define VERR_VMM_LONG_JMP_ERROR             (-2709)
-/** Unknown ring-3 call attempted. */
-#define VERR_VMM_UNKNOWN_RING3_CALL         (-2710)
-/** The ring-3 call didn't set an RC. */
-#define VERR_VMM_RING3_CALL_NO_RC           (-2711)
 /** Reason for leaving RC: Caller the tracer in ring-0. */
 #define VINF_VMM_CALL_TRACER                (2712)
Index: /trunk/include/VBox/err.mac
===================================================================
--- /trunk/include/VBox/err.mac	(revision 92407)
+++ /trunk/include/VBox/err.mac	(revision 92408)
@@ -493,10 +493,5 @@
 %define VERR_VMM_R0_VERSION_MISMATCH    (-2704)
 %define VERR_VMM_RC_VERSION_MISMATCH    (-2705)
-%define VERR_VMM_SET_JMP_ERROR    (-2706)
-%define VERR_VMM_SET_JMP_STACK_OVERFLOW    (-2707)
-%define VERR_VMM_SET_JMP_ABORTED_RESUME    (-2708)
 %define VERR_VMM_LONG_JMP_ERROR    (-2709)
-%define VERR_VMM_UNKNOWN_RING3_CALL    (-2710)
-%define VERR_VMM_RING3_CALL_NO_RC    (-2711)
 %define VINF_VMM_CALL_TRACER    (2712)
 %define VERR_VMM_SWITCHER_IPE_1    (-2713)
Index: /trunk/include/VBox/vmm/gvm.h
===================================================================
--- /trunk/include/VBox/vmm/gvm.h	(revision 92407)
+++ /trunk/include/VBox/vmm/gvm.h	(revision 92408)
@@ -120,5 +120,5 @@
         struct VMMR0PERVCPU s;
 #endif
-        uint8_t             padding[512];
+        uint8_t             padding[896];
     } vmmr0;
 
@@ -133,7 +133,7 @@
     /** Padding the structure size to page boundrary. */
 #ifdef VBOX_WITH_NEM_R0
-    uint8_t                 abPadding3[4096 - 64*2 - 64 - 1024 - 64 - 512 - 64];
+    uint8_t                 abPadding3[4096 - 64*2 - 64 - 1024 - 64 - 896 - 64];
 #else
-    uint8_t                 abPadding3[4096 - 64*2 - 64 - 1024 - 512 - 64];
+    uint8_t                 abPadding3[4096 - 64*2 - 64 - 1024 - 896 - 64];
 #endif
 } GVMCPU;
Index: /trunk/include/VBox/vmm/gvm.mac
===================================================================
--- /trunk/include/VBox/vmm/gvm.mac	(revision 92407)
+++ /trunk/include/VBox/vmm/gvm.mac	(revision 92408)
@@ -51,5 +51,5 @@
 %endif
         alignb 64
-        .vmmr0              resb 512
+        .vmmr0              resb 896
         alignb 64
         .pgmr0              resb 64
Index: /trunk/include/VBox/vmm/vm.h
===================================================================
--- /trunk/include/VBox/vmm/vm.h	(revision 92407)
+++ /trunk/include/VBox/vmm/vm.h	(revision 92408)
@@ -219,5 +219,5 @@
         struct VMMCPU       s;
 #endif
-        uint8_t             padding[1344];       /* multiple of 64 */
+        uint8_t             padding[9536];       /* multiple of 64 */
     } vmm;
 
Index: /trunk/include/VBox/vmm/vm.mac
===================================================================
--- /trunk/include/VBox/vmm/vm.mac	(revision 92407)
+++ /trunk/include/VBox/vmm/vm.mac	(revision 92408)
@@ -69,5 +69,5 @@
     .tm                     resb 5760
     alignb 64
-    .vmm                    resb 1344
+    .vmm                    resb 9536
     alignb 64
     .pdm                    resb 256
Index: /trunk/include/VBox/vmm/vmm.h
===================================================================
--- /trunk/include/VBox/vmm/vmm.h	(revision 92407)
+++ /trunk/include/VBox/vmm/vmm.h	(revision 92408)
@@ -203,5 +203,4 @@
 VMMR3DECL(PVMCPUCC)         VMMR3GetCpuByIdU(PUVM pVM, VMCPUID idCpu);
 VMM_INT_DECL(uint32_t)      VMMGetSvnRev(void);
-VMM_INT_DECL(bool)          VMMIsInRing3Call(PVMCPUCC pVCpu);
 VMM_INT_DECL(void)          VMMTrashVolatileXMMRegs(void);
 
@@ -488,5 +487,4 @@
 VMMR0_INT_DECL(void) VMMR0CleanupVM(PGVM pGVM);
 VMMR0_INT_DECL(bool) VMMR0IsLongJumpArmed(PVMCPUCC pVCpu);
-VMMR0_INT_DECL(bool) VMMR0IsInRing3LongJump(PVMCPUCC pVCpu);
 VMMR0_INT_DECL(int)  VMMR0ThreadCtxHookCreateForEmt(PVMCPUCC pVCpu);
 VMMR0_INT_DECL(void) VMMR0ThreadCtxHookDestroyForEmt(PVMCPUCC pVCpu);
Index: /trunk/src/VBox/HostDrivers/Support/Makefile.kmk
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/Makefile.kmk	(revision 92407)
+++ /trunk/src/VBox/HostDrivers/Support/Makefile.kmk	(revision 92408)
@@ -49,5 +49,5 @@
 endif
 if !defined(VBOX_ONLY_DOCS)
- if1of ($(VBOX_LDR_FMT), pe lx macho)
+ if1of ($(VBOX_LDR_FMT), pe lx)
   LIBRARIES += SUPR0
  endif
@@ -543,35 +543,4 @@
   endif
  endif
-
-else ifeq ($(VBOX_LDR_FMT),macho)
- $(call KB_FN_DO_PASS0_ON_TARGET,SUPR0) # Defines SUPR0_0_OUTDIR so we can use it in SUPR0_VBOX_FILES w/o needing $$.
- SUPR0_VBOX_KMK_FILE = $(SUPR0_0_OUTDIR)/files.kmk
- include $(SUPR0_VBOX_KMK_FILE)
- SUPR0_SOURCES       = $(SUPR0_VBOX_FILES)
- SUPR0_CLEAN         = $(SUPR0_VBOX_FILES) $(SUPR0_0_OUTDIR)/SUPR0.asm $(SUPR0_VBOX_KMK_FILE) $(SUPR0_VBOX_KMK_FILE).ts
-
- # Generate a make include file which lists the wrapper source files.
-# $ (call KB_FN_AUTO_CMD_DEPS,$(SUPR0_VBOX_KMK_FILE).ts)
- $(SUPR0_VBOX_KMK_FILE).ts \
- +| $(SUPR0_VBOX_KMK_FILE): \
-		$(PATH_SUB_CURRENT)/SUPDrv.cpp \
-		$(PATH_SUB_CURRENT)/SUPR0-asm-files.sed
-#	$(call KB_FN_AUTO_CMD_DEPS_COMMANDS)
-	$(call MSG_GENERATE,,$(SUPR0_VBOX_KMK_FILE))
-	$(QUIET)$(RM) -f -- "$@"
-	$(QUIET)$(MKDIR) -p -- "$(@D)"
-	$(QUIET)$(SED) --output "$@" -f "$(VBOX_PATH_SUP_SRC)/SUPR0-asm-files.sed" "$(VBOX_PATH_SUP_SRC)/SUPDrv.cpp"
-	$(QUIET)$(CP) --changed -fv "$@" $(SUPR0_VBOX_KMK_FILE)
-
- $(SUPR0_0_OUTDIR)/SUPR0.asm +| $(SUPR0_VBOX_FILES): \
-		$(PATH_SUB_CURRENT)/SUPDrv.cpp \
-		$(PATH_SUB_CURRENT)/SUPR0-asm.sed \
-               | $$(dir $$@) $(VBOX_FILESPLIT)
-#	$(call KB_FN_AUTO_CMD_DEPS_COMMANDS)
-	$(call MSG_GENERATE,,SUPR0.asm and friends)
-	$(QUIET)$(RM) -f -- "$@"
-	$(QUIET)$(SED) --output "$@" -f "$(VBOX_PATH_SUP_SRC)/SUPR0-asm.sed" "$(VBOX_PATH_SUP_SRC)/SUPDrv.cpp"
-	$(VBOX_FILESPLIT) "$@" "$(dir $@)"
-
 endif
 
Index: /trunk/src/VBox/VMM/Makefile.kmk
===================================================================
--- /trunk/src/VBox/VMM/Makefile.kmk	(revision 92407)
+++ /trunk/src/VBox/VMM/Makefile.kmk	(revision 92408)
@@ -78,11 +78,7 @@
 VBoxVMM_DEFS    += VBOX_WITH_DBGF_FLOW_TRACING
 endif
-ifdef VBOX_WITH_VMM_R0_SWITCH_STACK
-VBoxVMM_DEFS    += VMM_R0_SWITCH_STACK
-endif
 if "$(KBUILD_TYPE)" == "debug" && "$(USERNAME)" == "bird" && 0
 VBoxVMM_DEFS    += RTMEM_WRAP_TO_EF_APIS
 endif
-VBoxVMM_DEFS.darwin = VMM_R0_SWITCH_STACK
 
 VBoxVMM_INCS     = \
@@ -466,11 +462,7 @@
 VMMR0_DEFS     += VBOX_WITH_DBGF_TRACING
  endif
- ifdef VBOX_WITH_VMM_R0_SWITCH_STACK
-VMMR0_DEFS     += VMM_R0_SWITCH_STACK
- endif
  if1of ($(KBUILD_TARGET), darwin linux win)
 VMMR0_DEFS     += VMM_R0_TOUCH_FPU
  endif
-VMMR0_DEFS.darwin = VMM_R0_SWITCH_STACK
 VMMR0_DEFS.win.amd64  = VBOX_WITH_KERNEL_USING_XMM
 
@@ -572,6 +564,4 @@
 VMMR0_SOURCES.x86 = \
 	VMMR0/VMMR0JmpA-x86.asm
-VMMR0_SOURCES.darwin.amd64 = \
-	VMMR0/VMMR0StackBack-darwin.asm
 
 VMMR0_LIBS = \
Index: /trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp	(revision 92407)
+++ /trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp	(revision 92408)
@@ -422,30 +422,4 @@
 
 
-#if defined(VMM_R0_SWITCH_STACK) && defined(IN_RING0)
-/**
- * We must be on kernel stack before disabling preemption, thus this wrapper.
- */
-DECLASM(int) StkBack_pdmR0CritSectEnterContendedOnKrnlStk(PVMCC pVM, PVMCPUCC pVCpu, PPDMCRITSECT pCritSect,
-                                                          RTNATIVETHREAD hNativeSelf, int rcBusy, PCRTLOCKVALSRCPOS pSrcPos)
-{
-    VMMR0EMTBLOCKCTX Ctx;
-    int rc = VMMR0EmtPrepareToBlock(pVCpu, rcBusy, __FUNCTION__, pCritSect, &Ctx);
-    if (rc == VINF_SUCCESS)
-    {
-        Assert(RTThreadPreemptIsEnabled(NIL_RTTHREAD));
-
-        rc = pdmR3R0CritSectEnterContended(pVM, pVCpu, pCritSect, hNativeSelf, pSrcPos, rcBusy);
-
-        VMMR0EmtResumeAfterBlocking(pVCpu, &Ctx);
-    }
-    else
-        STAM_REL_COUNTER_INC(&pCritSect->s.StatContentionRZLockBusy);
-    return rc;
-}
-DECLASM(int) pdmR0CritSectEnterContendedOnKrnlStk(PVMCC pVM, PVMCPUCC pVCpu, PPDMCRITSECT pCritSect,
-                                                  RTNATIVETHREAD hNativeSelf, int rcBusy, PCRTLOCKVALSRCPOS pSrcPos);
-#endif
-
-
 /**
  * Common worker for the debug and normal APIs.
@@ -548,5 +522,4 @@
     if (pVCpu)
     {
-#  ifndef VMM_R0_SWITCH_STACK
         VMMR0EMTBLOCKCTX Ctx;
         int rc = VMMR0EmtPrepareToBlock(pVCpu, rcBusy, __FUNCTION__, pCritSect, &Ctx);
@@ -562,7 +535,4 @@
             STAM_REL_COUNTER_INC(&pCritSect->s.StatContentionRZLockBusy);
         return rc;
-#  else
-        return pdmR0CritSectEnterContendedOnKrnlStk(pVM, pVCpu, pCritSect, hNativeSelf, rcBusy, pSrcPos);
-#  endif
     }
 
@@ -812,65 +782,4 @@
 #endif /* IN_RING3 */
 
-
-#if defined(VMM_R0_SWITCH_STACK) && defined(IN_RING0)
-/**
- * We must be on kernel stack before disabling preemption, thus this wrapper.
- */
-DECLASM(int) StkBack_pdmR0CritSectLeaveSignallingOnKrnlStk(PVMCC pVM, PVMCPUCC pVCpu, PPDMCRITSECT pCritSect,
-                                                           int32_t const cLockers, SUPSEMEVENT const hEventToSignal)
-{
-    VMMR0EMTBLOCKCTX    Ctx;
-    bool                fLeaveCtx = false;
-    if (cLockers < 0)
-        AssertMsg(cLockers == -1, ("cLockers=%d\n", cLockers));
-    else
-    {
-        /* Someone is waiting, wake up one of them. */
-        Assert(cLockers < _8K);
-        SUPSEMEVENT hEvent = (SUPSEMEVENT)pCritSect->s.Core.EventSem;
-        if (!RTSemEventIsSignalSafe() && (pVCpu = VMMGetCpu(pVM)) != NULL)
-        {
-            int rc = VMMR0EmtPrepareToBlock(pVCpu, VINF_SUCCESS, __FUNCTION__, pCritSect, &Ctx);
-            VMM_ASSERT_RELEASE_MSG_RETURN(pVM, RT_SUCCESS(rc), ("rc=%Rrc\n", rc), rc);
-            fLeaveCtx = true;
-        }
-        int rc = SUPSemEventSignal(pVM->pSession, hEvent);
-        AssertRC(rc);
-    }
-
-    /*
-     * Signal exit event.
-     */
-    if (RT_LIKELY(hEventToSignal == NIL_SUPSEMEVENT))
-    { /* likely */ }
-    else
-    {
-        if (!fLeaveCtx && pVCpu != NULL && !RTSemEventIsSignalSafe() && (pVCpu = VMMGetCpu(pVM)) != NULL)
-        {
-            int rc = VMMR0EmtPrepareToBlock(pVCpu, VINF_SUCCESS, __FUNCTION__, pCritSect, &Ctx);
-            VMM_ASSERT_RELEASE_MSG_RETURN(pVM, RT_SUCCESS(rc), ("rc=%Rrc\n", rc), rc);
-            fLeaveCtx = true;
-        }
-        Log8(("Signalling %#p\n", hEventToSignal));
-        int rc = SUPSemEventSignal(pVM->pSession, hEventToSignal);
-        AssertRC(rc);
-    }
-
-    /*
-     * Restore HM context if needed.
-     */
-    if (!fLeaveCtx)
-    { /* contention should be unlikely */ }
-    else
-        VMMR0EmtResumeAfterBlocking(pVCpu, &Ctx);
-
-# ifdef DEBUG_bird
-    VMMTrashVolatileXMMRegs();
-# endif
-    return VINF_SUCCESS;
-}
-DECLASM(int) pdmR0CritSectLeaveSignallingOnKrnlStk(PVMCC pVM, PVMCPUCC pVCpu, PPDMCRITSECT pCritSect,
-                                                   int32_t const cLockers, SUPSEMEVENT const hEventToSignal);
-#endif
 
 /**
@@ -1029,5 +938,4 @@
         if (!fQueueIt)
         {
-# ifndef VMM_R0_SWITCH_STACK
             VMMR0EMTBLOCKCTX    Ctx;
             bool                fLeaveCtx = false;
@@ -1075,11 +983,8 @@
                 VMMR0EmtResumeAfterBlocking(pVCpu, &Ctx);
 
-#  ifdef DEBUG_bird
+# ifdef DEBUG_bird
             VMMTrashVolatileXMMRegs();
-#  endif
+# endif
             return VINF_SUCCESS;
-# else  /* VMM_R0_SWITCH_STACK */
-            return pdmR0CritSectLeaveSignallingOnKrnlStk(pVM, pVCpu, pCritSect, cLockers, hEventToSignal);
-# endif /* VMM_R0_SWITCH_STACK */
         }
 
Index: /trunk/src/VBox/VMM/VMMAll/PDMAllCritSectRw.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PDMAllCritSectRw.cpp	(revision 92407)
+++ /trunk/src/VBox/VMM/VMMAll/PDMAllCritSectRw.cpp	(revision 92408)
@@ -101,10 +101,5 @@
 *   Internal Functions                                                                                                           *
 *********************************************************************************************************************************/
-#if !defined(VMM_R0_SWITCH_STACK) || !defined(IN_RING0)
 static int pdmCritSectRwLeaveSharedWorker(PVMCC pVM, PPDMCRITSECTRW pThis, bool fNoVal);
-#else
-DECLASM(int) pdmCritSectRwLeaveSharedWorker(PVMCC pVM, PPDMCRITSECTRW pThis, bool fNoVal);
-DECLASM(int) StkBack_pdmCritSectRwLeaveSharedWorker(PVMCC pVM, PPDMCRITSECTRW pThis, bool fNoVal);
-#endif
 
 
@@ -556,13 +551,6 @@
  * @param   fNoVal      No validation records.
  */
-#if !defined(VMM_R0_SWITCH_STACK) || !defined(IN_RING0)
 static int pdmCritSectRwEnterShared(PVMCC pVM, PPDMCRITSECTRW pThis, int rcBusy, bool fTryOnly,
                                     PCRTLOCKVALSRCPOS pSrcPos, bool fNoVal)
-#else
-DECLASM(int) pdmCritSectRwEnterShared(PVMCC pVM, PPDMCRITSECTRW pThis, int rcBusy, bool fTryOnly,
-                                      PCRTLOCKVALSRCPOS pSrcPos, bool fNoVal);
-DECLASM(int) StkBack_pdmCritSectRwEnterShared(PVMCC pVM, PPDMCRITSECTRW pThis, int rcBusy, bool fTryOnly,
-                                              PCRTLOCKVALSRCPOS pSrcPos, bool fNoVal)
-#endif
 {
     /*
@@ -899,9 +887,5 @@
  *          PDMCritSectRwLeaveExcl, RTCritSectRwLeaveShared.
  */
-#if !defined(VMM_R0_SWITCH_STACK) || !defined(IN_RING0)
 static int pdmCritSectRwLeaveSharedWorker(PVMCC pVM, PPDMCRITSECTRW pThis, bool fNoVal)
-#else
-DECLASM(int) StkBack_pdmCritSectRwLeaveSharedWorker(PVMCC pVM, PPDMCRITSECTRW pThis, bool fNoVal)
-#endif
 {
     /*
@@ -1321,13 +1305,6 @@
  * @param   fNoVal      No validation records.
  */
-#if !defined(VMM_R0_SWITCH_STACK) || !defined(IN_RING0)
 static int pdmCritSectRwEnterExcl(PVMCC pVM, PPDMCRITSECTRW pThis, int rcBusy, bool fTryOnly,
                                   PCRTLOCKVALSRCPOS pSrcPos, bool fNoVal)
-#else
-DECLASM(int) pdmCritSectRwEnterExcl(PVMCC pVM, PPDMCRITSECTRW pThis, int rcBusy, bool fTryOnly,
-                                    PCRTLOCKVALSRCPOS pSrcPos, bool fNoVal);
-DECLASM(int) StkBack_pdmCritSectRwEnterExcl(PVMCC pVM, PPDMCRITSECTRW pThis, int rcBusy, bool fTryOnly,
-                                            PCRTLOCKVALSRCPOS pSrcPos, bool fNoVal)
-#endif
 {
     /*
@@ -1696,10 +1673,5 @@
  * @sa      PDMCritSectRwLeaveShared, RTCritSectRwLeaveExcl.
  */
-#if !defined(VMM_R0_SWITCH_STACK) || !defined(IN_RING0)
 static int pdmCritSectRwLeaveExclWorker(PVMCC pVM, PPDMCRITSECTRW pThis, bool fNoVal)
-#else
-DECLASM(int) pdmCritSectRwLeaveExclWorker(PVMCC pVM, PPDMCRITSECTRW pThis, bool fNoVal);
-DECLASM(int) StkBack_pdmCritSectRwLeaveExclWorker(PVMCC pVM, PPDMCRITSECTRW pThis, bool fNoVal)
-#endif
 {
     /*
Index: /trunk/src/VBox/VMM/VMMAll/VMMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/VMMAll.cpp	(revision 92407)
+++ /trunk/src/VBox/VMM/VMMAll/VMMAll.cpp	(revision 92408)
@@ -269,21 +269,4 @@
 
 /**
- * Checks whether we're in a ring-3 call or not.
- *
- * @returns true / false.
- * @param   pVCpu   The cross context virtual CPU structure of the calling EMT.
- * @thread  EMT
- */
-VMM_INT_DECL(bool) VMMIsInRing3Call(PVMCPU pVCpu)
-{
-#ifdef RT_ARCH_X86
-    return pVCpu->vmm.s.CallRing3JmpBufR0.fInRing3Call;
-#else
-    return pVCpu->vmm.s.CallRing3JmpBufR0.fInRing3Call;
-#endif
-}
-
-
-/**
  * Returns the build type for matching components.
  *
Index: /trunk/src/VBox/VMM/VMMR0/PGMR0Pool.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/PGMR0Pool.cpp	(revision 92407)
+++ /trunk/src/VBox/VMM/VMMR0/PGMR0Pool.cpp	(revision 92408)
@@ -140,36 +140,4 @@
 
 /**
- * Move this back to PGMR0PoolGrow when VMM_R0_SWITCH_STACK is gonne.
- */
-#ifndef VMM_R0_SWITCH_STACK
-static int pgmR0PoolGrowOnKrnlStk(PGVM pGVM, PGVMCPU pGVCpu, PPGMPOOL pPool)
-#else
-DECLASM(int) pgmR0PoolGrowOnKrnlStk(PGVM pGVM, PGVMCPU pGVCpu, PPGMPOOL pPool);
-DECLASM(int) StkBack_pgmR0PoolGrowOnKrnlStk(PGVM pGVM, PGVMCPU pGVCpu, PPGMPOOL pPool)
-#endif
-{
-    /*
-     * Enter the grow critical section and call worker.
-     */
-    STAM_REL_PROFILE_START(&pPool->StatGrow, a);
-
-    VMMR0EMTBLOCKCTX Ctx;
-    int rc = VMMR0EmtPrepareToBlock(pGVCpu, VINF_SUCCESS, __FUNCTION__, &pGVM->pgmr0.s.PoolGrowCritSect, &Ctx);
-    AssertRCReturn(rc, rc);
-
-    rc = RTCritSectEnter(&pGVM->pgmr0.s.PoolGrowCritSect);
-    AssertRCReturn(rc, rc);
-
-    rc = pgmR0PoolGrowInner(pGVM, pPool);
-
-    STAM_REL_PROFILE_STOP(&pPool->StatGrow, a);
-    RTCritSectLeave(&pGVM->pgmr0.s.PoolGrowCritSect);
-
-    VMMR0EmtResumeAfterBlocking(pGVCpu, &Ctx);
-    return rc;
-}
-
-
-/**
  * Grows the shadow page pool.
  *
@@ -194,5 +162,23 @@
     PGVMCPU const pGVCpu = &pGVM->aCpus[idCpu];
 
-    return pgmR0PoolGrowOnKrnlStk(pGVM, pGVCpu, pPool);
+    /*
+     * Enter the grow critical section and call worker.
+     */
+    STAM_REL_PROFILE_START(&pPool->StatGrow, a);
+
+    VMMR0EMTBLOCKCTX Ctx;
+    int rc = VMMR0EmtPrepareToBlock(pGVCpu, VINF_SUCCESS, __FUNCTION__, &pGVM->pgmr0.s.PoolGrowCritSect, &Ctx);
+    AssertRCReturn(rc, rc);
+
+    rc = RTCritSectEnter(&pGVM->pgmr0.s.PoolGrowCritSect);
+    AssertRCReturn(rc, rc);
+
+    rc = pgmR0PoolGrowInner(pGVM, pPool);
+
+    STAM_REL_PROFILE_STOP(&pPool->StatGrow, a);
+    RTCritSectLeave(&pGVM->pgmr0.s.PoolGrowCritSect);
+
+    VMMR0EmtResumeAfterBlocking(pGVCpu, &Ctx);
+    return rc;
 }
 
Index: /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp	(revision 92407)
+++ /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp	(revision 92408)
@@ -323,4 +323,8 @@
         pGVCpu->vmmr0.s.pPreemptState               = NULL;
         pGVCpu->vmmr0.s.hCtxHook                    = NIL_RTTHREADCTXHOOK;
+        pGVCpu->vmmr0.s.AssertJmpBuf.pMirrorBuf     = &pGVCpu->vmm.s.AssertJmpBuf;
+        pGVCpu->vmmr0.s.AssertJmpBuf.pvStackBuf     = &pGVCpu->vmm.s.abAssertStack[0];
+        pGVCpu->vmmr0.s.AssertJmpBuf.cbStackBuf     = sizeof(pGVCpu->vmm.s.abAssertStack);
+
         for (size_t iLogger = 0; iLogger < RT_ELEMENTS(pGVCpu->vmmr0.s.u.aLoggers); iLogger++)
             pGVCpu->vmmr0.s.u.aLoggers[iLogger].hEventFlushWait = NIL_RTSEMEVENT;
@@ -1441,5 +1445,5 @@
                              * Setup the longjmp machinery and execute guest code (calls HMR0RunGuestCode).
                              */
-                            rc = vmmR0CallRing3SetJmp(&pGVCpu->vmm.s.CallRing3JmpBufR0, HMR0RunGuestCode, pGVM, pGVCpu);
+                            rc = vmmR0CallRing3SetJmp(&pGVCpu->vmmr0.s.AssertJmpBuf, HMR0RunGuestCode, pGVM, pGVCpu);
 
                             /*
@@ -1570,7 +1574,7 @@
              */
 #  ifdef VBOXSTRICTRC_STRICT_ENABLED
-            int rc = vmmR0CallRing3SetJmp2(&pGVCpu->vmm.s.CallRing3JmpBufR0, (PFNVMMR0SETJMP2)NEMR0RunGuestCode, pGVM, idCpu);
+            int rc = vmmR0CallRing3SetJmp2(&pGVCpu->vmmr0.s.AssertJmpBuf, (PFNVMMR0SETJMP2)NEMR0RunGuestCode, pGVM, idCpu);
 #  else
-            int rc = vmmR0CallRing3SetJmp2(&pGVCpu->vmm.s.CallRing3JmpBufR0, NEMR0RunGuestCode, pGVM, idCpu);
+            int rc = vmmR0CallRing3SetJmp2(&pGVCpu->vmmr0.s.AssertJmpBuf, NEMR0RunGuestCode, pGVM, idCpu);
 #  endif
             STAM_COUNTER_INC(&pGVM->vmm.s.StatRunGC);
@@ -2357,5 +2361,5 @@
 }
 
-#ifndef VMM_R0_SWITCH_STACK /* Not safe unless we disable preemption first. */
+
 /**
  * This is just a longjmp wrapper function for VMMR0EntryEx calls.
@@ -2374,5 +2378,4 @@
                               pGVCpu->vmmr0.s.pSession);
 }
-#endif
 
 
@@ -2394,8 +2397,7 @@
                             PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION pSession)
 {
-#ifndef VMM_R0_SWITCH_STACK /* Not safe unless we disable preemption first. */
     /*
      * Requests that should only happen on the EMT thread will be
-     * wrapped in a setjmp so we can assert without causing trouble.
+     * wrapped in a setjmp so we can assert without causing too much trouble.
      */
     if (   pVM  != NULL
@@ -2404,54 +2406,25 @@
         && idCpu < pGVM->cCpus
         && pGVM->pSession == pSession
-        && pGVM->pSelf    == pVM)
-    {
-        switch (enmOperation)
-        {
-            /* These might/will be called before VMMR3Init. */
-            case VMMR0_DO_GMM_INITIAL_RESERVATION:
-            case VMMR0_DO_GMM_UPDATE_RESERVATION:
-            case VMMR0_DO_GMM_ALLOCATE_PAGES:
-            case VMMR0_DO_GMM_FREE_PAGES:
-            case VMMR0_DO_GMM_BALLOONED_PAGES:
-            /* On the mac we might not have a valid jmp buf, so check these as well. */
-            case VMMR0_DO_VMMR0_INIT:
-            case VMMR0_DO_VMMR0_TERM:
-
-            case VMMR0_DO_PDM_DEVICE_CREATE:
-            case VMMR0_DO_PDM_DEVICE_GEN_CALL:
-            case VMMR0_DO_IOM_GROW_IO_PORTS:
-            case VMMR0_DO_IOM_GROW_IO_PORT_STATS:
-            case VMMR0_DO_DBGF_BP_INIT:
-            case VMMR0_DO_DBGF_BP_CHUNK_ALLOC:
-            case VMMR0_DO_DBGF_BP_L2_TBL_CHUNK_ALLOC:
-            {
-                PGVMCPU        pGVCpu        = &pGVM->aCpus[idCpu];
-                RTNATIVETHREAD hNativeThread = RTThreadNativeSelf();
-                if (RT_LIKELY(   pGVCpu->hEMT            == hNativeThread
-                              && pGVCpu->hNativeThreadR0 == hNativeThread))
-                {
-                    if (!pGVCpu->vmm.s.CallRing3JmpBufR0.pvSavedStack)
-                        break;
-
-                    pGVCpu->vmmr0.s.pGVM         = pGVM;
-                    pGVCpu->vmmr0.s.idCpu        = idCpu;
-                    pGVCpu->vmmr0.s.enmOperation = enmOperation;
-                    pGVCpu->vmmr0.s.pReq         = pReq;
-                    pGVCpu->vmmr0.s.u64Arg       = u64Arg;
-                    pGVCpu->vmmr0.s.pSession     = pSession;
-                    return vmmR0CallRing3SetJmpEx(&pGVCpu->vmm.s.CallRing3JmpBufR0, vmmR0EntryExWrapper, pGVCpu,
-                                                  ((uintptr_t)u64Arg << 16) | (uintptr_t)enmOperation);
-                }
-                return VERR_VM_THREAD_NOT_EMT;
-            }
-
-            default:
-            case VMMR0_DO_PGM_POOL_GROW:
-                break;
-        }
-    }
-#else
-    RT_NOREF(pVM);
-#endif
+        && pGVM->pSelf    == pGVM
+        && enmOperation != VMMR0_DO_GVMM_DESTROY_VM
+        && enmOperation != VMMR0_DO_GVMM_SCHED_WAKE_UP /* idCpu is not caller but target. Sigh. */ /** @todo fix*/
+       )
+    {
+        PGVMCPU        pGVCpu        = &pGVM->aCpus[idCpu];
+        RTNATIVETHREAD hNativeThread = RTThreadNativeSelf();
+        if (RT_LIKELY(   pGVCpu->hEMT            == hNativeThread
+                      && pGVCpu->hNativeThreadR0 == hNativeThread))
+        {
+            pGVCpu->vmmr0.s.pGVM         = pGVM;
+            pGVCpu->vmmr0.s.idCpu        = idCpu;
+            pGVCpu->vmmr0.s.enmOperation = enmOperation;
+            pGVCpu->vmmr0.s.pReq         = pReq;
+            pGVCpu->vmmr0.s.u64Arg       = u64Arg;
+            pGVCpu->vmmr0.s.pSession     = pSession;
+            return vmmR0CallRing3SetJmpEx(&pGVCpu->vmmr0.s.AssertJmpBuf, vmmR0EntryExWrapper, pGVCpu,
+                                          ((uintptr_t)u64Arg << 16) | (uintptr_t)enmOperation);
+        }
+        return VERR_VM_THREAD_NOT_EMT;
+    }
     return vmmR0EntryExWorker(pGVM, idCpu, enmOperation, pReq, u64Arg, pSession);
 }
@@ -2473,23 +2446,8 @@
 {
 #ifdef RT_ARCH_X86
-    return pVCpu->vmm.s.CallRing3JmpBufR0.eip
-        && !pVCpu->vmm.s.CallRing3JmpBufR0.fInRing3Call;
+    return pVCpu->vmmr0.s.AssertJmpBuf.eip != 0;
 #else
-    return pVCpu->vmm.s.CallRing3JmpBufR0.rip
-        && !pVCpu->vmm.s.CallRing3JmpBufR0.fInRing3Call;
-#endif
-}
-
-
-/**
- * Checks whether we've done a ring-3 long jump.
- *
- * @returns @c true / @c false
- * @param   pVCpu       The cross context virtual CPU structure.
- * @thread  EMT
- */
-VMMR0_INT_DECL(bool) VMMR0IsInRing3LongJump(PVMCPUCC pVCpu)
-{
-    return pVCpu->vmm.s.CallRing3JmpBufR0.fInRing3Call;
+    return pVCpu->vmmr0.s.AssertJmpBuf.rip != 0;
+#endif
 }
 
@@ -3005,10 +2963,5 @@
  * Inner worker for vmmR0LoggerFlushCommon.
  */
-#ifndef VMM_R0_SWITCH_STACK
 static bool   vmmR0LoggerFlushInner(PGVM pGVM, PGVMCPU pGVCpu, uint32_t idxLogger, size_t idxBuffer, uint32_t cbToFlush)
-#else
-DECLASM(bool) vmmR0LoggerFlushInner(PGVM pGVM, PGVMCPU pGVCpu, uint32_t idxLogger, size_t idxBuffer, uint32_t cbToFlush);
-DECLASM(bool) StkBack_vmmR0LoggerFlushInner(PGVM pGVM, PGVMCPU pGVCpu, uint32_t idxLogger, size_t idxBuffer, uint32_t cbToFlush)
-#endif
 {
     PVMMR0PERVCPULOGGER const pR0Log    = &pGVCpu->vmmr0.s.u.aLoggers[idxLogger];
@@ -3545,8 +3498,8 @@
     AssertPtrReturn(pfnCallback, VERR_INVALID_POINTER);
 
-    if (!pVCpu->vmm.s.pfnRing0AssertCallback)
-    {
-        pVCpu->vmm.s.pfnRing0AssertCallback    = pfnCallback;
-        pVCpu->vmm.s.pvRing0AssertCallbackUser = pvUser;
+    if (!pVCpu->vmmr0.s.pfnAssertCallback)
+    {
+        pVCpu->vmmr0.s.pfnAssertCallback    = pfnCallback;
+        pVCpu->vmmr0.s.pvAssertCallbackUser = pvUser;
         return VINF_SUCCESS;
     }
@@ -3562,6 +3515,6 @@
 VMMR0_INT_DECL(void) VMMR0AssertionRemoveNotification(PVMCPUCC pVCpu)
 {
-    pVCpu->vmm.s.pfnRing0AssertCallback    = NULL;
-    pVCpu->vmm.s.pvRing0AssertCallbackUser = NULL;
+    pVCpu->vmmr0.s.pfnAssertCallback    = NULL;
+    pVCpu->vmmr0.s.pvAssertCallbackUser = NULL;
 }
 
@@ -3575,5 +3528,5 @@
 VMMR0_INT_DECL(bool) VMMR0AssertionIsNotificationSet(PVMCPUCC pVCpu)
 {
-    return pVCpu->vmm.s.pfnRing0AssertCallback != NULL;
+    return pVCpu->vmmr0.s.pfnAssertCallback != NULL;
 }
 
@@ -3597,14 +3550,12 @@
         {
 # ifdef RT_ARCH_X86
-            if (    pVCpu->vmm.s.CallRing3JmpBufR0.eip
-                &&  !pVCpu->vmm.s.CallRing3JmpBufR0.fInRing3Call)
+            if (pVCpu->vmmr0.s.AssertJmpBuf.eip)
 # else
-            if (    pVCpu->vmm.s.CallRing3JmpBufR0.rip
-                &&  !pVCpu->vmm.s.CallRing3JmpBufR0.fInRing3Call)
+            if (pVCpu->vmmr0.s.AssertJmpBuf.rip)
 # endif
             {
-                if (pVCpu->vmm.s.pfnRing0AssertCallback)
-                    pVCpu->vmm.s.pfnRing0AssertCallback(pVCpu, pVCpu->vmm.s.pvRing0AssertCallbackUser);
-                int rc = vmmR0CallRing3LongJmp(&pVCpu->vmm.s.CallRing3JmpBufR0, VERR_VMM_RING0_ASSERTION);
+                if (pVCpu->vmmr0.s.pfnAssertCallback)
+                    pVCpu->vmmr0.s.pfnAssertCallback(pVCpu, pVCpu->vmmr0.s.pvAssertCallbackUser);
+                int rc = vmmR0CallRing3LongJmp(&pVCpu->vmmr0.s.AssertJmpBuf, VERR_VMM_RING0_ASSERTION);
                 return RT_FAILURE_NP(rc);
             }
Index: /trunk/src/VBox/VMM/VMMR0/VMMR0JmpA-amd64.asm
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/VMMR0JmpA-amd64.asm	(revision 92407)
+++ /trunk/src/VBox/VMM/VMMR0/VMMR0JmpA-amd64.asm	(revision 92408)
@@ -16,7 +16,7 @@
 ;
 
-;*******************************************************************************
-;* Header Files                                                                *
-;*******************************************************************************
+;*********************************************************************************************************************************
+;*  Header Files                                                                                                                 *
+;*********************************************************************************************************************************
 %define RT_ASM_WITH_SEH64_ALT
 %include "VBox/asmdefs.mac"
@@ -24,32 +24,7 @@
 %include "VBox/err.mac"
 %include "VBox/param.mac"
-%ifdef VMM_R0_SWITCH_STACK
- %include "VBox/SUPR0StackWrapper.mac"
-%endif
-
-
-;*******************************************************************************
-;*  Defined Constants And Macros                                               *
-;*******************************************************************************
-%define RESUME_MAGIC    07eadf00dh
-%define STACK_PADDING   0eeeeeeeeeeeeeeeeh
-
-;; Workaround for linux 4.6 fast/slow syscall stack depth difference.
-;; Update: This got worse with linux 5.13 and CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT.
-;;         The x86 arch_exit_to_user_mode_prepare code limits the offset to 255,
-;;         while the generic limit is 1023.  See bugref:10064 for details.
-%ifdef VMM_R0_SWITCH_STACK
- %define STACK_FUZZ_SIZE 0
-%else
- %ifdef RT_OS_LINUX
-  %define STACK_FUZZ_SIZE 384
- %else
-  %define STACK_FUZZ_SIZE 128
- %endif
-%endif
 
 
 BEGINCODE
-
 
 ;;
@@ -77,12 +52,12 @@
     SEH64_SET_FRAME_xBP 0
  %ifdef ASM_CALL64_MSC
-    sub     rsp, 30h + STACK_FUZZ_SIZE  ; (10h is used by resume (??), 20h for callee spill area)
-    SEH64_ALLOCATE_STACK 30h + STACK_FUZZ_SIZE
+    sub     rsp, 30h                    ; (10h is used by resume (??), 20h for callee spill area)
+    SEH64_ALLOCATE_STACK 30h
 SEH64_END_PROLOGUE
     mov     r11, rdx                    ; pfn
     mov     rdx, rcx                    ; pJmpBuf;
  %else
-    sub     rsp, 10h + STACK_FUZZ_SIZE  ; (10h is used by resume (??))
-    SEH64_ALLOCATE_STACK 10h + STACK_FUZZ_SIZE
+    sub     rsp, 10h                    ; (10h is used by resume (??))
+    SEH64_ALLOCATE_STACK 10h
 SEH64_END_PROLOGUE
     mov     r8, rdx                     ; pvUser1 (save it like MSC)
@@ -126,51 +101,9 @@
 
     ;
-    ; If we're not in a ring-3 call, call pfn and return.
-    ;
-    test    byte [xDX + VMMR0JMPBUF.fInRing3Call], 1
-    jnz     .resume
-
-.different_call_continue:
+    ; Save the call then make it.
+    ;
     mov     [xDX + VMMR0JMPBUF.pfn], r11
     mov     [xDX + VMMR0JMPBUF.pvUser1], r8
     mov     [xDX + VMMR0JMPBUF.pvUser2], r9
-
- %ifdef VMM_R0_SWITCH_STACK
-    mov     r15, [xDX + VMMR0JMPBUF.pvSavedStack]
-    test    r15, r15
-    jz      .entry_error
-  %ifdef VBOX_STRICT
-    cmp     dword [r15], 0h
-    jne     .entry_error
-    mov     rdi, r15
-    mov     rcx, VMM_STACK_SIZE / 8
-    mov     rax, qword 0eeeeeeeffeeeeeeeh
-    repne stosq
-    mov     [rdi - 10h], rbx
-  %endif
-
-    ; New RSP
-  %ifdef WITHOUT_SUPR0STACKINFO
-    lea     r15, [r15 + VMM_STACK_SIZE]
-  %else
-    lea     r15, [r15 + VMM_STACK_SIZE - SUPR0STACKINFO_size]
-
-    ; Plant SUPR0 stack info.
-    mov     [r15 + SUPR0STACKINFO.pResumeKernelStack], rsp
-    mov     [r15 + SUPR0STACKINFO.pSelf], r15
-    mov     dword [r15 + SUPR0STACKINFO.magic0], SUPR0STACKINFO_MAGIC0
-    mov     dword [r15 + SUPR0STACKINFO.magic1], SUPR0STACKINFO_MAGIC1
-    mov     dword [r15 + SUPR0STACKINFO.magic2], SUPR0STACKINFO_MAGIC2
-    mov     dword [r15 + SUPR0STACKINFO.magic3], SUPR0STACKINFO_MAGIC3
-
-  %endif
-
-    ; Switch stack!
-  %ifdef ASM_CALL64_MSC
-    lea     rsp, [r15 - 20h]
-  %else
-    mov     rsp, r15
-  %endif
- %endif ; VMM_R0_SWITCH_STACK
 
     mov     r12, rdx                    ; Save pJmpBuf.
@@ -184,15 +117,4 @@
     call    r11
     mov     rdx, r12                    ; Restore pJmpBuf
-
- %ifdef VMM_R0_SWITCH_STACK
-    ; Reset the debug mark and the stack info header.
-    mov     r15, [xDX + VMMR0JMPBUF.pvSavedStack]
-  %ifndef WITHOUT_SUPR0STACKINFO
-    mov     qword [r15 + VMM_STACK_SIZE - SUPR0STACKINFO_size + SUPR0STACKINFO.magic0], 0h
-  %endif
-  %ifdef VBOX_STRICT
-    mov     dword [r15], 0h             ; Reset the marker
-  %endif
- %endif
 
     ;
@@ -227,142 +149,4 @@
     popf
     leave
-    ret
-
-.entry_error:
-    mov     eax, VERR_VMM_SET_JMP_ERROR
-    jmp     .proper_return
-
-.stack_overflow:
-    mov     eax, VERR_VMM_SET_JMP_STACK_OVERFLOW
-    jmp     .proper_return
-
-    ;
-    ; Aborting resume.
-    ; Note! No need to restore XMM registers here since we haven't touched them yet.
-    ;
-.bad:
-    and     qword [xDX + VMMR0JMPBUF.rip], byte 0 ; used for valid check.
-    mov     rbx, [xDX + VMMR0JMPBUF.rbx]
- %ifdef ASM_CALL64_MSC
-    mov     rsi, [xDX + VMMR0JMPBUF.rsi]
-    mov     rdi, [xDX + VMMR0JMPBUF.rdi]
- %endif
-    mov     r12, [xDX + VMMR0JMPBUF.r12]
-    mov     r13, [xDX + VMMR0JMPBUF.r13]
-    mov     r14, [xDX + VMMR0JMPBUF.r14]
-    mov     r15, [xDX + VMMR0JMPBUF.r15]
-    mov     eax, VERR_VMM_SET_JMP_ABORTED_RESUME
-    leave
-    ret
-
-    ;
-    ; Not the same call as went to ring-3.
-    ;
-.different_call:
-    mov     byte [xDX + VMMR0JMPBUF.fInRing3Call], 0
-    ;; @todo or should we fail here instead?
-    jmp     .different_call_continue
-
-    ;
-    ; Resume VMMRZCallRing3 the call.
-    ;
-.resume:
-    ; Check if it's actually the same call, if not just continue with it
-    ; as a regular call (ring-0 assert, then VM destroy).
-    cmp     [xDX + VMMR0JMPBUF.pfn], r11
-    jne     .different_call
-    cmp     [xDX + VMMR0JMPBUF.pvUser1], r8
-    jne     .different_call
-    cmp     [xDX + VMMR0JMPBUF.pvUser2], r9
-    jne     .different_call
-
- %ifndef VMM_R0_SWITCH_STACK
-    ; Sanity checks incoming stack, applying fuzz if needed.
-    sub     r10, [xDX + VMMR0JMPBUF.SpCheck]
-    jz      .resume_stack_checked_out
-    add     r10, STACK_FUZZ_SIZE        ; plus/minus STACK_FUZZ_SIZE is fine.
-    cmp     r10, STACK_FUZZ_SIZE * 2
-    ja      .bad
-
-    mov     r10, [xDX + VMMR0JMPBUF.SpCheck]
-    mov     [xDX + VMMR0JMPBUF.rsp], r10 ; Must be update in case of another long jump (used for save calc).
-
-.resume_stack_checked_out:
-    mov     ecx, [xDX + VMMR0JMPBUF.cbSavedStack]
-    cmp     rcx, VMM_STACK_SIZE
-    ja      .bad
-    test    rcx, 7
-    jnz     .bad
-    mov     rdi, [xDX + VMMR0JMPBUF.SpCheck]
-    sub     rdi, [xDX + VMMR0JMPBUF.SpResume]
-    cmp     rcx, rdi
-    jne     .bad
- %endif
-
-%ifdef VMM_R0_SWITCH_STACK
-    ; Update the signature in case the kernel stack moved.
-    mov     r15, [xDX + VMMR0JMPBUF.pvSavedStack]
-    test    r15, r15
-    jz      .entry_error
- %ifndef WITHOUT_SUPR0STACKINFO
-    lea     r15, [r15 + VMM_STACK_SIZE - SUPR0STACKINFO_size]
-
-    mov     [r15 + SUPR0STACKINFO.pResumeKernelStack], rsp
-    mov     [r15 + SUPR0STACKINFO.pSelf], r15
-    mov     dword [r15 + SUPR0STACKINFO.magic0], SUPR0STACKINFO_MAGIC0
-    mov     dword [r15 + SUPR0STACKINFO.magic1], SUPR0STACKINFO_MAGIC1
-    mov     dword [r15 + SUPR0STACKINFO.magic2], SUPR0STACKINFO_MAGIC2
-    mov     dword [r15 + SUPR0STACKINFO.magic3], SUPR0STACKINFO_MAGIC3
- %endif
-
-    ; Switch stack.
-    mov     rsp, [xDX + VMMR0JMPBUF.SpResume]
-%else
-    ; Restore the stack.
-    mov     ecx, [xDX + VMMR0JMPBUF.cbSavedStack]
-    shr     ecx, 3
-    mov     rsi, [xDX + VMMR0JMPBUF.pvSavedStack]
-    mov     rdi, [xDX + VMMR0JMPBUF.SpResume]
-    mov     rsp, rdi
-    rep movsq
-%endif ; !VMM_R0_SWITCH_STACK
-    mov     byte [xDX + VMMR0JMPBUF.fInRing3Call], 0
-
-    ;
-    ; Continue where we left off.
-    ;
-%ifdef VBOX_STRICT
-    pop     rax                         ; magic
-    cmp     rax, RESUME_MAGIC
-    je      .magic_ok
-    mov     ecx, 0123h
-    mov     [ecx], edx
-.magic_ok:
-%endif
-%ifdef RT_OS_WINDOWS
-    movdqa  xmm6,  [rsp + 000h]
-    movdqa  xmm7,  [rsp + 010h]
-    movdqa  xmm8,  [rsp + 020h]
-    movdqa  xmm9,  [rsp + 030h]
-    movdqa  xmm10, [rsp + 040h]
-    movdqa  xmm11, [rsp + 050h]
-    movdqa  xmm12, [rsp + 060h]
-    movdqa  xmm13, [rsp + 070h]
-    movdqa  xmm14, [rsp + 080h]
-    movdqa  xmm15, [rsp + 090h]
-    add     rsp, 0a0h
-%endif
-    popf
-    pop     rbx
-%ifdef ASM_CALL64_MSC
-    pop     rsi
-    pop     rdi
-%endif
-    pop     r12
-    pop     r13
-    pop     r14
-    pop     r15
-    pop     rbp
-    xor     eax, eax                    ; VINF_SUCCESS
     ret
 ENDPROC vmmR0CallRing3SetJmp
@@ -416,8 +200,4 @@
     movdqa  [rsp + 090h], xmm15
 %endif
-%ifdef VBOX_STRICT
-    push    RESUME_MAGIC
-    SEH64_ALLOCATE_STACK 8
-%endif
 SEH64_END_PROLOGUE
 
@@ -440,34 +220,19 @@
 
     ;
-    ; Sanity checks.
-    ;
-    mov     rdi, [xDX + VMMR0JMPBUF.pvSavedStack]
-    test    rdi, rdi                    ; darwin may set this to 0.
-    jz      .nok
-    mov     [xDX + VMMR0JMPBUF.SpResume], rsp
- %ifndef VMM_R0_SWITCH_STACK
+    ; Also check that the stack is in the vicinity of the RSP we entered
+    ; on so the stack mirroring below doesn't go wild.
+    ;
     mov     rsi, rsp
     mov     rcx, [xDX + VMMR0JMPBUF.rsp]
     sub     rcx, rsi
-
-    ; two sanity checks on the size.
-    cmp     rcx, VMM_STACK_SIZE         ; check max size.
+    cmp     rcx, _64K
     jnbe    .nok
 
     ;
-    ; Copy the stack
-    ;
-    test    ecx, 7                      ; check alignment
-    jnz     .nok
-    mov     [xDX + VMMR0JMPBUF.cbSavedStack], ecx
-    shr     ecx, 3
-    rep movsq
-
- %endif ; !VMM_R0_SWITCH_STACK
-
     ; Save a PC and return PC here to assist unwinding.
+    ;
 .unwind_point:
     lea     rcx, [.unwind_point wrt RIP]
-    mov     [xDX + VMMR0JMPBUF.SavedEipForUnwind], rcx
+    mov     [xDX + VMMR0JMPBUF.UnwindPc], rcx
     mov     rcx, [xDX + VMMR0JMPBUF.rbp]
     lea     rcx, [rcx + 8]
@@ -477,13 +242,56 @@
 
     ; Save RSP & RBP to enable stack dumps
+    mov     [xDX + VMMR0JMPBUF.UnwindSp], rsp
     mov     rcx, rbp
-    mov     [xDX + VMMR0JMPBUF.SavedEbp], rcx
+    mov     [xDX + VMMR0JMPBUF.UnwindBp], rcx
     sub     rcx, 8
-    mov     [xDX + VMMR0JMPBUF.SavedEsp], rcx
-
-    ; store the last pieces of info.
+    mov     [xDX + VMMR0JMPBUF.UnwindRetSp], rcx
+
+    ;
+    ; Make sure the direction flag is clear before we do any rep movsb below.
+    ;
+    cld
+
+    ;
+    ; Mirror the stack.
+    ;
+    xor     ebx, ebx
+
+    mov     rdi, [xDX + VMMR0JMPBUF.pvStackBuf]
+    or      rdi, rdi
+    jz      .skip_stack_mirroring
+
+    mov     ebx, [xDX + VMMR0JMPBUF.cbStackBuf]
+    or      ebx, ebx
+    jz      .skip_stack_mirroring
+
     mov     rcx, [xDX + VMMR0JMPBUF.rsp]
-    mov     [xDX + VMMR0JMPBUF.SpCheck], rcx
-    mov     byte [xDX + VMMR0JMPBUF.fInRing3Call], 1
+    sub     rcx, rsp
+    and     rcx, ~0fffh                 ; copy up to the page boundrary
+
+    cmp     rcx, rbx                    ; rbx = rcx = RT_MIN(rbx, rcx);
+    jbe     .do_stack_buffer_big_enough
+    mov     ecx, ebx                    ; too much to copy, limit to ebx
+    jmp     .do_stack_copying
+.do_stack_buffer_big_enough:
+    mov     ebx, ecx                    ; ecx is smaller, update ebx for cbStackValid
+
+.do_stack_copying:
+    mov     rsi, rsp
+    rep movsb
+
+.skip_stack_mirroring:
+    mov     [xDX + VMMR0JMPBUF.cbStackValid], ebx
+
+    ;
+    ; Do buffer mirroring.
+    ;
+    mov     rdi, [xDX + VMMR0JMPBUF.pMirrorBuf]
+    or      rdi, rdi
+    jz      .skip_buffer_mirroring
+    mov     rsi, rdx
+    mov     ecx, VMMR0JMPBUF_size
+    rep movsb
+.skip_buffer_mirroring:
 
     ;
@@ -522,12 +330,4 @@
     ;
 .nok:
-%ifdef VBOX_STRICT
-    pop     rax                         ; magic
-    cmp     rax, RESUME_MAGIC
-    je      .magic_ok
-    mov     ecx, 0123h
-    mov     [rcx], edx
-.magic_ok:
-%endif
     mov     eax, VERR_VMM_LONG_JMP_ERROR
 %ifdef RT_OS_WINDOWS
Index: unk/src/VBox/VMM/VMMR0/VMMR0StackBack-darwin.asm
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/VMMR0StackBack-darwin.asm	(revision 92407)
+++ 	(revision )
@@ -1,34 +1,0 @@
-; $Id$
-;; @file
-; VMM - Temporary hack for darwin stack switching.
-;
-
-;
-; Copyright (C) 2006-2021 Oracle Corporation
-;
-; This file is part of VirtualBox Open Source Edition (OSE), as
-; available from http://www.virtualbox.org. This file is free software;
-; you can redistribute it and/or modify it under the terms of the GNU
-; General Public License (GPL) as published by the Free Software
-; Foundation, in version 2 as it comes in the "COPYING" file of the
-; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
-; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
-;
-
-;*********************************************************************************************************************************
-;*  Header Files                                                                                                                 *
-;*********************************************************************************************************************************
-;%define RT_ASM_WITH_SEH64_ALT
-%include "VBox/asmdefs.mac"
-%include "VBox/SUPR0StackWrapper.mac"
-
-
-SUPR0StackWrapperGeneric vmmR0LoggerFlushInner, 5
-SUPR0StackWrapperGeneric pdmR0CritSectEnterContendedOnKrnlStk, 6
-SUPR0StackWrapperGeneric pdmR0CritSectLeaveSignallingOnKrnlStk, 5
-SUPR0StackWrapperGeneric pdmCritSectRwEnterShared, 6
-SUPR0StackWrapperGeneric pdmCritSectRwLeaveSharedWorker, 3
-SUPR0StackWrapperGeneric pdmCritSectRwEnterExcl, 6
-SUPR0StackWrapperGeneric pdmCritSectRwLeaveExclWorker, 6
-SUPR0StackWrapperGeneric pgmR0PoolGrowOnKrnlStk, 3
-
Index: /trunk/src/VBox/VMM/VMMR3/VMM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/VMM.cpp	(revision 92407)
+++ /trunk/src/VBox/VMM/VMMR3/VMM.cpp	(revision 92408)
@@ -165,5 +165,4 @@
 *   Internal Functions                                                                                                           *
 *********************************************************************************************************************************/
-static int                  vmmR3InitStacks(PVM pVM);
 static void                 vmmR3InitRegisterStats(PVM pVM);
 static DECLCALLBACK(int)    vmmR3Save(PVM pVM, PSSMHANDLE pSSM);
@@ -280,83 +279,32 @@
         return rc;
 
-    /*
-     * Init various sub-components.
-     */
-    rc = vmmR3InitStacks(pVM);
+#ifdef VBOX_WITH_NMI
+    /*
+     * Allocate mapping for the host APIC.
+     */
+    rc = MMR3HyperReserve(pVM, PAGE_SIZE, "Host APIC", &pVM->vmm.s.GCPtrApicBase);
+    AssertRC(rc);
+#endif
     if (RT_SUCCESS(rc))
     {
-#ifdef VBOX_WITH_NMI
         /*
-         * Allocate mapping for the host APIC.
+         * Start the log flusher thread.
          */
-        rc = MMR3HyperReserve(pVM, PAGE_SIZE, "Host APIC", &pVM->vmm.s.GCPtrApicBase);
-        AssertRC(rc);
-#endif
+        rc = RTThreadCreate(&pVM->vmm.s.hLogFlusherThread, vmmR3LogFlusher, pVM, 0 /*cbStack*/,
+                            RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "R0LogWrk");
         if (RT_SUCCESS(rc))
         {
+
             /*
-             * Start the log flusher thread.
+             * Debug info and statistics.
              */
-            rc = RTThreadCreate(&pVM->vmm.s.hLogFlusherThread, vmmR3LogFlusher, pVM, 0 /*cbStack*/,
-                                RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "R0LogWrk");
-            if (RT_SUCCESS(rc))
-            {
-
-                /*
-                 * Debug info and statistics.
-                 */
-                DBGFR3InfoRegisterInternal(pVM, "fflags", "Displays the current Forced actions Flags.", vmmR3InfoFF);
-                vmmR3InitRegisterStats(pVM);
-                vmmInitFormatTypes();
-
-                return VINF_SUCCESS;
-            }
+            DBGFR3InfoRegisterInternal(pVM, "fflags", "Displays the current Forced actions Flags.", vmmR3InfoFF);
+            vmmR3InitRegisterStats(pVM);
+            vmmInitFormatTypes();
+
+            return VINF_SUCCESS;
         }
     }
     /** @todo Need failure cleanup? */
-
-    return rc;
-}
-
-
-/**
- * Allocate & setup the VMM RC stack(s) (for EMTs).
- *
- * The stacks are also used for long jumps in Ring-0.
- *
- * @returns VBox status code.
- * @param   pVM     The cross context VM structure.
- *
- * @remarks The optional guard page gets it protection setup up during R3 init
- *          completion because of init order issues.
- */
-static int vmmR3InitStacks(PVM pVM)
-{
-    int rc = VINF_SUCCESS;
-#ifdef VMM_R0_SWITCH_STACK
-    uint32_t fFlags = MMHYPER_AONR_FLAGS_KERNEL_MAPPING;
-#else
-    uint32_t fFlags = 0;
-#endif
-
-    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
-    {
-        PVMCPU pVCpu = pVM->apCpusR3[idCpu];
-
-#ifdef VBOX_STRICT_VMM_STACK
-        rc = MMR3HyperAllocOnceNoRelEx(pVM, PAGE_SIZE + VMM_STACK_SIZE + PAGE_SIZE,
-#else
-        rc = MMR3HyperAllocOnceNoRelEx(pVM, VMM_STACK_SIZE,
-#endif
-                                       PAGE_SIZE, MM_TAG_VMM, fFlags, (void **)&pVCpu->vmm.s.pbEMTStackR3);
-        if (RT_SUCCESS(rc))
-        {
-#ifdef VBOX_STRICT_VMM_STACK
-            pVCpu->vmm.s.pbEMTStackR3 += PAGE_SIZE;
-#endif
-            pVCpu->vmm.s.CallRing3JmpBufR0.pvSavedStack = MMHyperR3ToR0(pVM, pVCpu->vmm.s.pbEMTStackR3);
-
-        }
-    }
 
     return rc;
@@ -433,13 +381,4 @@
     STAMR3Register(pVM, &pVM->vmm.s.StatLogFlusherNoWakeUp, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, "/VMM/LogFlush/00-NoWakups", STAMUNIT_OCCURENCES, "Times the flusher thread didn't need waking up.");
 
-#ifdef VBOX_WITH_STATISTICS
-    for (VMCPUID i = 0; i < pVM->cCpus; i++)
-    {
-        PVMCPU pVCpu = pVM->apCpusR3[i];
-        STAMR3RegisterF(pVM, &pVCpu->vmm.s.CallRing3JmpBufR0.cbUsedMax,  STAMTYPE_U32_RESET, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,      "Max amount of stack used.", "/VMM/Stack/CPU%u/Max", i);
-        STAMR3RegisterF(pVM, &pVCpu->vmm.s.CallRing3JmpBufR0.cbUsedAvg,  STAMTYPE_U32,       STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,      "Average stack usage.",      "/VMM/Stack/CPU%u/Avg", i);
-        STAMR3RegisterF(pVM, &pVCpu->vmm.s.CallRing3JmpBufR0.cUsedTotal, STAMTYPE_U64,       STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of stack usages.",   "/VMM/Stack/CPU%u/Uses", i);
-    }
-#endif
     for (VMCPUID i = 0; i < pVM->cCpus; i++)
     {
@@ -2265,31 +2204,38 @@
     AssertReturn(cbRead < ~(size_t)0 / 2, VERR_INVALID_PARAMETER);
 
-    int rc;
-#ifdef VMM_R0_SWITCH_STACK
-    RTHCUINTPTR off = R0Addr - MMHyperCCToR0(pVM, pVCpu->vmm.s.pbEMTStackR3);
-#else
-    RTHCUINTPTR off = pVCpu->vmm.s.CallRing3JmpBufR0.cbSavedStack - (pVCpu->vmm.s.CallRing3JmpBufR0.SpCheck - R0Addr);
-#endif
-    if (   off < VMM_STACK_SIZE
-        && off + cbRead <= VMM_STACK_SIZE)
-    {
-        memcpy(pvBuf, &pVCpu->vmm.s.pbEMTStackR3[off], cbRead);
-        rc = VINF_SUCCESS;
+    /*
+     * Hopefully we've got all the requested bits.  If not supply what we
+     * can and zero the remaining stuff.
+     */
+    RTHCUINTPTR off = R0Addr - pVCpu->vmm.s.AssertJmpBuf.UnwindSp;
+    if (off < pVCpu->vmm.s.AssertJmpBuf.cbStackValid)
+    {
+        size_t const cbValid = pVCpu->vmm.s.AssertJmpBuf.cbStackValid - off;
+        if (cbRead <= cbValid)
+        {
+            memcpy(pvBuf, &pVCpu->vmm.s.abAssertStack[off], cbRead);
+            return VINF_SUCCESS;
+        }
+
+        memcpy(pvBuf, &pVCpu->vmm.s.abAssertStack[off], cbValid);
+        RT_BZERO((uint8_t *)pvBuf + cbValid, cbRead - cbValid);
     }
     else
-        rc = VERR_INVALID_POINTER;
-
-    /* Supply the setjmp return RIP/EIP.  */
-    if (   pVCpu->vmm.s.CallRing3JmpBufR0.UnwindRetPcLocation + sizeof(RTR0UINTPTR) > R0Addr
-        && pVCpu->vmm.s.CallRing3JmpBufR0.UnwindRetPcLocation < R0Addr + cbRead)
-    {
-        uint8_t const  *pbSrc  = (uint8_t const *)&pVCpu->vmm.s.CallRing3JmpBufR0.UnwindRetPcValue;
-        size_t          cbSrc  = sizeof(pVCpu->vmm.s.CallRing3JmpBufR0.UnwindRetPcValue);
+        RT_BZERO(pvBuf, cbRead);
+
+    /*
+     * Supply the setjmp return RIP/EIP if requested.
+     */
+    if (   pVCpu->vmm.s.AssertJmpBuf.UnwindRetPcLocation + sizeof(RTR0UINTPTR) > R0Addr
+        && pVCpu->vmm.s.AssertJmpBuf.UnwindRetPcLocation < R0Addr + cbRead)
+    {
+        uint8_t const  *pbSrc  = (uint8_t const *)&pVCpu->vmm.s.AssertJmpBuf.UnwindRetPcValue;
+        size_t          cbSrc  = sizeof(pVCpu->vmm.s.AssertJmpBuf.UnwindRetPcValue);
         size_t          offDst = 0;
-        if (R0Addr < pVCpu->vmm.s.CallRing3JmpBufR0.UnwindRetPcLocation)
-            offDst = pVCpu->vmm.s.CallRing3JmpBufR0.UnwindRetPcLocation - R0Addr;
-        else if (R0Addr > pVCpu->vmm.s.CallRing3JmpBufR0.UnwindRetPcLocation)
-        {
-            size_t offSrc = R0Addr - pVCpu->vmm.s.CallRing3JmpBufR0.UnwindRetPcLocation;
+        if (R0Addr < pVCpu->vmm.s.AssertJmpBuf.UnwindRetPcLocation)
+            offDst = pVCpu->vmm.s.AssertJmpBuf.UnwindRetPcLocation - R0Addr;
+        else if (R0Addr > pVCpu->vmm.s.AssertJmpBuf.UnwindRetPcLocation)
+        {
+            size_t offSrc = R0Addr - pVCpu->vmm.s.AssertJmpBuf.UnwindRetPcLocation;
             Assert(offSrc < cbSrc);
             pbSrc -= offSrc;
@@ -2300,9 +2246,9 @@
         memcpy((uint8_t *)pvBuf + offDst, pbSrc, cbSrc);
 
-        if (cbSrc == cbRead)
-            rc = VINF_SUCCESS;
-    }
-
-    return rc;
+        //if (cbSrc == cbRead)
+        //    rc = VINF_SUCCESS;
+    }
+
+    return VINF_SUCCESS;
 }
 
@@ -2321,77 +2267,64 @@
 
     /*
+     * This is all we really need here if we had proper unwind info (win64 only)...
+     */
+    pState->u.x86.auRegs[X86_GREG_xBP] = pVCpu->vmm.s.AssertJmpBuf.UnwindBp;
+    pState->u.x86.auRegs[X86_GREG_xSP] = pVCpu->vmm.s.AssertJmpBuf.UnwindSp;
+    pState->uPc                        = pVCpu->vmm.s.AssertJmpBuf.UnwindPc;
+
+    /*
      * Locate the resume point on the stack.
      */
-#ifdef VMM_R0_SWITCH_STACK
-    uintptr_t off = pVCpu->vmm.s.CallRing3JmpBufR0.SpResume - MMHyperCCToR0(pVCpu->pVMR3, pVCpu->vmm.s.pbEMTStackR3);
-    AssertReturnVoid(off < VMM_STACK_SIZE);
-#else
     uintptr_t off = 0;
-#endif
 
 #ifdef RT_ARCH_AMD64
     /*
-     * This code must match the .resume stuff in VMMR0JmpA-amd64.asm exactly.
-     */
-# ifdef VBOX_STRICT
-    Assert(*(uint64_t const *)&pVCpu->vmm.s.pbEMTStackR3[off] == UINT32_C(0x7eadf00d));
-    off += 8; /* RESUME_MAGIC */
-# endif
+     * This code must match the vmmR0CallRing3LongJmp stack frame setup in VMMR0JmpA-amd64.asm exactly.
+     */
 # ifdef RT_OS_WINDOWS
     off += 0xa0; /* XMM6 thru XMM15 */
 # endif
-    pState->u.x86.uRFlags              = *(uint64_t const *)&pVCpu->vmm.s.pbEMTStackR3[off];
+    pState->u.x86.uRFlags              = *(uint64_t const *)&pVCpu->vmm.s.abAssertStack[off];
     off += 8;
-    pState->u.x86.auRegs[X86_GREG_xBX] = *(uint64_t const *)&pVCpu->vmm.s.pbEMTStackR3[off];
+    pState->u.x86.auRegs[X86_GREG_xBX] = *(uint64_t const *)&pVCpu->vmm.s.abAssertStack[off];
     off += 8;
 # ifdef RT_OS_WINDOWS
-    pState->u.x86.auRegs[X86_GREG_xSI] = *(uint64_t const *)&pVCpu->vmm.s.pbEMTStackR3[off];
+    pState->u.x86.auRegs[X86_GREG_xSI] = *(uint64_t const *)&pVCpu->vmm.s.abAssertStack[off];
     off += 8;
-    pState->u.x86.auRegs[X86_GREG_xDI] = *(uint64_t const *)&pVCpu->vmm.s.pbEMTStackR3[off];
+    pState->u.x86.auRegs[X86_GREG_xDI] = *(uint64_t const *)&pVCpu->vmm.s.abAssertStack[off];
     off += 8;
 # endif
-    pState->u.x86.auRegs[X86_GREG_x12] = *(uint64_t const *)&pVCpu->vmm.s.pbEMTStackR3[off];
+    pState->u.x86.auRegs[X86_GREG_x12] = *(uint64_t const *)&pVCpu->vmm.s.abAssertStack[off];
     off += 8;
-    pState->u.x86.auRegs[X86_GREG_x13] = *(uint64_t const *)&pVCpu->vmm.s.pbEMTStackR3[off];
+    pState->u.x86.auRegs[X86_GREG_x13] = *(uint64_t const *)&pVCpu->vmm.s.abAssertStack[off];
     off += 8;
-    pState->u.x86.auRegs[X86_GREG_x14] = *(uint64_t const *)&pVCpu->vmm.s.pbEMTStackR3[off];
+    pState->u.x86.auRegs[X86_GREG_x14] = *(uint64_t const *)&pVCpu->vmm.s.abAssertStack[off];
     off += 8;
-    pState->u.x86.auRegs[X86_GREG_x15] = *(uint64_t const *)&pVCpu->vmm.s.pbEMTStackR3[off];
+    pState->u.x86.auRegs[X86_GREG_x15] = *(uint64_t const *)&pVCpu->vmm.s.abAssertStack[off];
     off += 8;
-    pState->u.x86.auRegs[X86_GREG_xBP] = *(uint64_t const *)&pVCpu->vmm.s.pbEMTStackR3[off];
+    pState->u.x86.auRegs[X86_GREG_xBP] = *(uint64_t const *)&pVCpu->vmm.s.abAssertStack[off];
     off += 8;
-    pState->uPc                        = *(uint64_t const *)&pVCpu->vmm.s.pbEMTStackR3[off];
-    off += 8;
+    pState->uPc                        = *(uint64_t const *)&pVCpu->vmm.s.abAssertStack[off];
+    pState->u.x86.auRegs[X86_GREG_xSP] = pVCpu->vmm.s.AssertJmpBuf.UnwindRetSp;
 
 #elif defined(RT_ARCH_X86)
     /*
-     * This code must match the .resume stuff in VMMR0JmpA-x86.asm exactly.
-     */
-# ifdef VBOX_STRICT
-    Assert(*(uint32_t const *)&pVCpu->vmm.s.pbEMTStackR3[off] == UINT32_C(0x7eadf00d));
-    off += 4; /* RESUME_MAGIC */
-# endif
-    pState->u.x86.uRFlags              = *(uint32_t const *)&pVCpu->vmm.s.pbEMTStackR3[off];
+     * This code must match the vmmR0CallRing3LongJmp stack frame setup in VMMR0JmpA-x86.asm exactly.
+     */
+    pState->u.x86.uRFlags              = *(uint32_t const *)&pVCpu->vmm.s.abAssertStack[off];
     off += 4;
-    pState->u.x86.auRegs[X86_GREG_xBX] = *(uint32_t const *)&pVCpu->vmm.s.pbEMTStackR3[off];
+    pState->u.x86.auRegs[X86_GREG_xBX] = *(uint32_t const *)&pVCpu->vmm.s.abAssertStack[off];
     off += 4;
-    pState->u.x86.auRegs[X86_GREG_xSI] = *(uint32_t const *)&pVCpu->vmm.s.pbEMTStackR3[off];
+    pState->u.x86.auRegs[X86_GREG_xSI] = *(uint32_t const *)&pVCpu->vmm.s.abAssertStack[off];
     off += 4;
-    pState->u.x86.auRegs[X86_GREG_xDI] = *(uint32_t const *)&pVCpu->vmm.s.pbEMTStackR3[off];
+    pState->u.x86.auRegs[X86_GREG_xDI] = *(uint32_t const *)&pVCpu->vmm.s.abAssertStack[off];
     off += 4;
-    pState->u.x86.auRegs[X86_GREG_xBP] = *(uint32_t const *)&pVCpu->vmm.s.pbEMTStackR3[off];
+    pState->u.x86.auRegs[X86_GREG_xBP] = *(uint32_t const *)&pVCpu->vmm.s.abAssertStack[off];
     off += 4;
-    pState->uPc                        = *(uint32_t const *)&pVCpu->vmm.s.pbEMTStackR3[off];
-    off += 4;
+    pState->uPc                        = *(uint32_t const *)&pVCpu->vmm.s.abAssertStack[off];
+    pState->u.x86.auRegs[X86_GREG_xSP] = pVCpu->vmm.s.AssertJmpBuf.UnwindRetSp;
 #else
 # error "Port me"
 #endif
-
-    /*
-     * This is all we really need here, though the above helps if the assembly
-     * doesn't contain unwind info (currently only on win/64, so that is useful).
-     */
-    pState->u.x86.auRegs[X86_GREG_xBP] = pVCpu->vmm.s.CallRing3JmpBufR0.SavedEbp;
-    pState->u.x86.auRegs[X86_GREG_xSP] = pVCpu->vmm.s.CallRing3JmpBufR0.SpResume;
 }
 
@@ -2464,17 +2397,5 @@
 static int vmmR3HandleRing0Assert(PVM pVM, PVMCPU pVCpu)
 {
-    /*
-     * Signal a ring 0 hypervisor assertion.
-     * Cancel the longjmp operation that's in progress.
-     */
-    pVCpu->vmm.s.CallRing3JmpBufR0.fInRing3Call = false;
-#ifdef RT_ARCH_X86
-    pVCpu->vmm.s.CallRing3JmpBufR0.eip = 0;
-#else
-    pVCpu->vmm.s.CallRing3JmpBufR0.rip = 0;
-#endif
-#ifdef VMM_R0_SWITCH_STACK
-    *(uint64_t *)pVCpu->vmm.s.pbEMTStackR3 = 0; /* clear marker  */
-#endif
+    RT_NOREF(pVCpu);
     LogRel(("%s", pVM->vmm.s.szRing0AssertMsg1));
     LogRel(("%s", pVM->vmm.s.szRing0AssertMsg2));
Index: /trunk/src/VBox/VMM/VMMR3/VMMGuruMeditation.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/VMMGuruMeditation.cpp	(revision 92407)
+++ /trunk/src/VBox/VMM/VMMR3/VMMGuruMeditation.cpp	(revision 92408)
@@ -362,7 +362,4 @@
         case VINF_EM_TRIPLE_FAULT:
         case VERR_VMM_HYPER_CR3_MISMATCH:
-        case VERR_VMM_SET_JMP_ERROR:
-        case VERR_VMM_SET_JMP_ABORTED_RESUME:
-        case VERR_VMM_SET_JMP_STACK_OVERFLOW:
         case VERR_VMM_LONG_JMP_ERROR:
         {
@@ -398,45 +395,30 @@
              * Dump the relevant hypervisor registers and stack.
              */
-            if (   rcErr == VERR_VMM_RING0_ASSERTION /* fInRing3Call has already been cleared here. */
-                || pVCpu->vmm.s.CallRing3JmpBufR0.fInRing3Call)
+            if (rcErr == VERR_VMM_RING0_ASSERTION)
             {
                 /* Dump the jmpbuf.  */
                 pHlp->pfnPrintf(pHlp,
                                 "!!\n"
-                                "!! CallRing3JmpBuf:\n"
+                                "!! AssertJmpBuf:\n"
                                 "!!\n");
                 pHlp->pfnPrintf(pHlp,
-                                "SavedEsp=%RHv SavedEbp=%RHv SpResume=%RHv SpCheck=%RHv\n",
-                                pVCpu->vmm.s.CallRing3JmpBufR0.SavedEsp,
-                                pVCpu->vmm.s.CallRing3JmpBufR0.SavedEbp,
-                                pVCpu->vmm.s.CallRing3JmpBufR0.SpResume,
-                                pVCpu->vmm.s.CallRing3JmpBufR0.SpCheck);
-                pHlp->pfnPrintf(pHlp,
-                                "pvSavedStack=%RHv cbSavedStack=%#x  fInRing3Call=%RTbool\n",
-                                pVCpu->vmm.s.CallRing3JmpBufR0.pvSavedStack,
-                                pVCpu->vmm.s.CallRing3JmpBufR0.cbSavedStack,
-                                pVCpu->vmm.s.CallRing3JmpBufR0.fInRing3Call);
-                pHlp->pfnPrintf(pHlp,
-                                "cbUsedMax=%#x cbUsedAvg=%#x cbUsedTotal=%#llx cUsedTotal=%#llx\n",
-                                pVCpu->vmm.s.CallRing3JmpBufR0.cbUsedMax,
-                                pVCpu->vmm.s.CallRing3JmpBufR0.cbUsedAvg,
-                                pVCpu->vmm.s.CallRing3JmpBufR0.cbUsedTotal,
-                                pVCpu->vmm.s.CallRing3JmpBufR0.cUsedTotal);
+                                "UnwindSp=%RHv UnwindRetSp=%RHv UnwindBp=%RHv UnwindPc=%RHv\n",
+                                pVCpu->vmm.s.AssertJmpBuf.UnwindSp,
+                                pVCpu->vmm.s.AssertJmpBuf.UnwindRetSp,
+                                pVCpu->vmm.s.AssertJmpBuf.UnwindBp,
+                                pVCpu->vmm.s.AssertJmpBuf.UnwindPc);
+                pHlp->pfnPrintf(pHlp,
+                                "UnwindRetPcValue=%RHv UnwindRetPcLocation=%RHv\n",
+                                pVCpu->vmm.s.AssertJmpBuf.UnwindRetPcValue,
+                                pVCpu->vmm.s.AssertJmpBuf.UnwindRetPcLocation);
                 pHlp->pfnPrintf(pHlp,
                                 "pfn=%RHv pvUser1=%RHv pvUser2=%RHv\n",
-                                pVCpu->vmm.s.CallRing3JmpBufR0.pfn,
-                                pVCpu->vmm.s.CallRing3JmpBufR0.pvUser1,
-                                pVCpu->vmm.s.CallRing3JmpBufR0.pvUser2);
+                                pVCpu->vmm.s.AssertJmpBuf.pfn,
+                                pVCpu->vmm.s.AssertJmpBuf.pvUser1,
+                                pVCpu->vmm.s.AssertJmpBuf.pvUser2);
 
                 /* Dump the resume register frame on the stack. */
-                PRTHCUINTPTR pBP;
-#ifdef VMM_R0_SWITCH_STACK
-                pBP = (PRTHCUINTPTR)&pVCpu->vmm.s.pbEMTStackR3[  pVCpu->vmm.s.CallRing3JmpBufR0.SavedEbp
-                                                               - MMHyperCCToR0(pVM, pVCpu->vmm.s.pbEMTStackR3)];
-#else
-                pBP = (PRTHCUINTPTR)&pVCpu->vmm.s.pbEMTStackR3[  pVCpu->vmm.s.CallRing3JmpBufR0.cbSavedStack
-                                                               - pVCpu->vmm.s.CallRing3JmpBufR0.SpCheck
-                                                               + pVCpu->vmm.s.CallRing3JmpBufR0.SavedEbp];
-#endif
+                PRTHCUINTPTR const pBP = (PRTHCUINTPTR)&pVCpu->vmm.s.abAssertStack[  pVCpu->vmm.s.AssertJmpBuf.UnwindBp
+                                                                                   - pVCpu->vmm.s.AssertJmpBuf.UnwindSp];
 #if HC_ARCH_BITS == 32
                 pHlp->pfnPrintf(pHlp,
@@ -445,5 +427,5 @@
                                 ,
                                 pBP[-3], pBP[-2], pBP[-1],
-                                pBP[1], pVCpu->vmm.s.CallRing3JmpBufR0.SavedEbp - 8, pBP[0], pBP[-4]);
+                                pBP[1], pVCpu->vmm.s.AssertJmpBuf.SavedEbp - 8, pBP[0], pBP[-4]);
 #else
 # ifdef RT_OS_WINDOWS
@@ -459,5 +441,5 @@
                                 pBP[-4], pBP[-3],
                                 pBP[-2], pBP[-1],
-                                pBP[1], pVCpu->vmm.s.CallRing3JmpBufR0.SavedEbp - 16, pBP[0], pBP[-8]);
+                                pBP[1], pVCpu->vmm.s.AssertJmpBuf.UnwindRetSp, pBP[0], pBP[-8]);
 # else
                 pHlp->pfnPrintf(pHlp,
@@ -471,5 +453,5 @@
                                 pBP[-4], pBP[-3],
                                 pBP[-2], pBP[-1],
-                                pBP[1], pVCpu->vmm.s.CallRing3JmpBufR0.SavedEbp - 16, pBP[0], pBP[-6]);
+                                pBP[1], pVCpu->vmm.s.AssertJmpBuf.UnwindRetSp, pBP[0], pBP[-6]);
 # endif
 #endif
@@ -479,7 +461,7 @@
                 PCDBGFSTACKFRAME pFirstFrame;
                 rc2 = DBGFR3StackWalkBeginEx(pVM->pUVM, pVCpu->idCpu, DBGFCODETYPE_RING0,
-                                             DBGFR3AddrFromHostR0(&AddrBp, pVCpu->vmm.s.CallRing3JmpBufR0.SavedEbp),
-                                             DBGFR3AddrFromHostR0(&AddrSp, pVCpu->vmm.s.CallRing3JmpBufR0.SpResume),
-                                             DBGFR3AddrFromHostR0(&AddrPc, pVCpu->vmm.s.CallRing3JmpBufR0.SavedEipForUnwind),
+                                             DBGFR3AddrFromHostR0(&AddrBp, pVCpu->vmm.s.AssertJmpBuf.UnwindBp),
+                                             DBGFR3AddrFromHostR0(&AddrSp, pVCpu->vmm.s.AssertJmpBuf.UnwindSp),
+                                             DBGFR3AddrFromHostR0(&AddrPc, pVCpu->vmm.s.AssertJmpBuf.UnwindPc),
                                              RTDBGRETURNTYPE_INVALID, &pFirstFrame);
                 if (RT_SUCCESS(rc2))
@@ -548,34 +530,27 @@
 
                 /* Symbols on the stack. */
-#ifdef VMM_R0_SWITCH_STACK
-                uint32_t const   iLast   = VMM_STACK_SIZE / sizeof(uintptr_t);
-                uint32_t         iAddr   = (uint32_t)(  pVCpu->vmm.s.CallRing3JmpBufR0.SavedEsp
-                                                      - MMHyperCCToR0(pVM, pVCpu->vmm.s.pbEMTStackR3)) / sizeof(uintptr_t);
-                if (iAddr > iLast)
-                    iAddr = 0;
-#else
-                uint32_t const   iLast   = RT_MIN(pVCpu->vmm.s.CallRing3JmpBufR0.cbSavedStack, VMM_STACK_SIZE)
-                                         / sizeof(uintptr_t);
-                uint32_t         iAddr   = 0;
-#endif
+                uint32_t const          cbRawStack = RT_MIN(pVCpu->vmm.s.AssertJmpBuf.cbStackValid, sizeof(pVCpu->vmm.s.abAssertStack));
+                uintptr_t const * const pauAddr    = (uintptr_t const *)&pVCpu->vmm.s.abAssertStack[0];
+                uint32_t const          iEnd       = cbRawStack / sizeof(uintptr_t);
+                uint32_t                iAddr      = 0;
                 pHlp->pfnPrintf(pHlp,
                                 "!!\n"
-                                "!! Addresses on the stack (iAddr=%#x, iLast=%#x)\n"
+                                "!! Addresses on the stack (iAddr=%#x, iEnd=%#x)\n"
                                 "!!\n",
-                                iAddr, iLast);
-                uintptr_t const *paAddr  = (uintptr_t const *)pVCpu->vmm.s.pbEMTStackR3;
-                while (iAddr < iLast)
+                                iAddr, iEnd);
+                while (iAddr < iEnd)
                 {
-                    uintptr_t const uAddr = paAddr[iAddr];
+                    uintptr_t const uAddr = pauAddr[iAddr];
                     if (uAddr > X86_PAGE_SIZE)
                     {
                         DBGFADDRESS  Addr;
                         DBGFR3AddrFromFlat(pVM->pUVM, &Addr, uAddr);
-                        RTGCINTPTR   offDisp = 0;
-                        PRTDBGSYMBOL pSym  = DBGFR3AsSymbolByAddrA(pVM->pUVM, DBGF_AS_R0, &Addr,
-                                                                   RTDBGSYMADDR_FLAGS_LESS_OR_EQUAL | RTDBGSYMADDR_FLAGS_SKIP_ABS_IN_DEFERRED,
-                                                                   &offDisp, NULL);
-                        RTGCINTPTR   offLineDisp;
-                        PRTDBGLINE   pLine = DBGFR3AsLineByAddrA(pVM->pUVM, DBGF_AS_R0, &Addr, &offLineDisp, NULL);
+                        RTGCINTPTR   offDisp     = 0;
+                        RTGCINTPTR   offLineDisp = 0;
+                        PRTDBGSYMBOL pSym        = DBGFR3AsSymbolByAddrA(pVM->pUVM, DBGF_AS_R0, &Addr,
+                                                                           RTDBGSYMADDR_FLAGS_LESS_OR_EQUAL
+                                                                         | RTDBGSYMADDR_FLAGS_SKIP_ABS_IN_DEFERRED,
+                                                                         &offDisp, NULL);
+                        PRTDBGLINE   pLine       = DBGFR3AsLineByAddrA(pVM->pUVM, DBGF_AS_R0, &Addr, &offLineDisp, NULL);
                         if (pLine || pSym)
                         {
@@ -599,13 +574,11 @@
                                 "!!\n"
                                 "!! Raw stack (mind the direction).\n"
-                                "!! pbEMTStackR0=%RHv pbEMTStackBottomR0=%RHv VMM_STACK_SIZE=%#x\n"
+                                "!! pbEMTStackR0=%RHv cbRawStack=%#x\n"
                                 "!! pbEmtStackR3=%p\n"
                                 "!!\n"
                                 "%.*Rhxd\n",
-                                MMHyperCCToR0(pVM, pVCpu->vmm.s.pbEMTStackR3),
-                                MMHyperCCToR0(pVM, pVCpu->vmm.s.pbEMTStackR3) + VMM_STACK_SIZE,
-                                VMM_STACK_SIZE,
-                                pVCpu->vmm.s.pbEMTStackR3,
-                                VMM_STACK_SIZE, pVCpu->vmm.s.pbEMTStackR3);
+                                pVCpu->vmm.s.AssertJmpBuf.UnwindSp, cbRawStack,
+                                &pVCpu->vmm.s.abAssertStack[0],
+                                cbRawStack, &pVCpu->vmm.s.abAssertStack[0]);
             }
             else
Index: /trunk/src/VBox/VMM/VMMRZ/VMMRZ.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMRZ/VMMRZ.cpp	(revision 92407)
+++ /trunk/src/VBox/VMM/VMMRZ/VMMRZ.cpp	(revision 92408)
@@ -44,6 +44,6 @@
 #endif
 
-    Assert(pVCpu->vmm.s.cCallRing3Disabled < 16);
-    if (ASMAtomicUoIncU32(&pVCpu->vmm.s.cCallRing3Disabled) == 1)
+    Assert(pVCpu->vmmr0.s.cCallRing3Disabled < 16);
+    if (ASMAtomicUoIncU32(&pVCpu->vmmr0.s.cCallRing3Disabled) == 1)
     {
 #ifdef IN_RC
@@ -73,6 +73,6 @@
 #endif
 
-    Assert(pVCpu->vmm.s.cCallRing3Disabled > 0);
-    if (ASMAtomicUoDecU32(&pVCpu->vmm.s.cCallRing3Disabled) == 0)
+    Assert(pVCpu->vmmr0.s.cCallRing3Disabled > 0);
+    if (ASMAtomicUoDecU32(&pVCpu->vmmr0.s.cCallRing3Disabled) == 0)
     {
 #ifdef IN_RC
@@ -98,6 +98,6 @@
 {
     VMCPU_ASSERT_EMT(pVCpu);
-    Assert(pVCpu->vmm.s.cCallRing3Disabled <= 16);
-    return pVCpu->vmm.s.cCallRing3Disabled == 0;
+    Assert(pVCpu->vmmr0.s.cCallRing3Disabled <= 16);
+    return pVCpu->vmmr0.s.cCallRing3Disabled == 0;
 }
 
Index: /trunk/src/VBox/VMM/include/VMMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/VMMInternal.h	(revision 92407)
+++ /trunk/src/VBox/VMM/include/VMMInternal.h	(revision 92408)
@@ -138,4 +138,6 @@
 
 
+/** Pointer to a ring-0 jump buffer. */
+typedef struct VMMR0JMPBUF *PVMMR0JMPBUF;
 /**
  * Jump buffer for the setjmp/longjmp like constructs used to
@@ -184,21 +186,12 @@
     /** @} */
 
-    /** Flag that indicates that we've done a ring-3 call. */
-    bool                        fInRing3Call;
-    /** The number of bytes we've saved. */
-    uint32_t                    cbSavedStack;
-    /** Pointer to the buffer used to save the stack.
-     * This is assumed to be 8KB. */
-    RTR0PTR                     pvSavedStack;
-    /** Esp we we match against esp on resume to make sure the stack wasn't relocated. */
-    RTHCUINTREG                 SpCheck;
-    /** The esp we should resume execution with after the restore. */
-    RTHCUINTREG                 SpResume;
-    /** ESP/RSP at the time of the jump to ring 3. */
-    RTHCUINTREG                 SavedEsp;
-    /** EBP/RBP at the time of the jump to ring 3. */
-    RTHCUINTREG                 SavedEbp;
-    /** EIP/RIP within vmmR0CallRing3LongJmp for assisting unwinding. */
-    RTHCUINTREG                 SavedEipForUnwind;
+    /** RSP/ESP at the time of the stack mirroring (what pvStackBuf starts with). */
+    RTHCUINTREG                 UnwindSp;
+    /** RSP/ESP at the time of the long jump call. */
+    RTHCUINTREG                 UnwindRetSp;
+    /** RBP/EBP inside the vmmR0CallRing3LongJmp frame. */
+    RTHCUINTREG                 UnwindBp;
+    /** RIP/EIP within vmmR0CallRing3LongJmp for assisting unwinding. */
+    RTHCUINTREG                 UnwindPc;
     /** Unwind: The vmmR0CallRing3SetJmp return address value. */
     RTHCUINTREG                 UnwindRetPcValue;
@@ -213,20 +206,14 @@
     RTHCUINTREG                 pvUser2;
 
-#if HC_ARCH_BITS == 32
-    /** Alignment padding. */
-    uint32_t                    uPadding;
-#endif
-
-    /** Stats: Max amount of stack used. */
-    uint32_t                    cbUsedMax;
-    /** Stats: Average stack usage. (Avg = cbUsedTotal / cUsedTotal) */
-    uint32_t                    cbUsedAvg;
-    /** Stats: Total amount of stack used. */
-    uint64_t                    cbUsedTotal;
-    /** Stats: Number of stack usages. */
-    uint64_t                    cUsedTotal;
+    /** Number of valid bytes in pvStackBuf.  */
+    uint32_t                    cbStackValid;
+    /** Size of buffer pvStackBuf points to. */
+    uint32_t                    cbStackBuf;
+    /** Pointer to buffer for mirroring the stack. Optional. */
+    RTR0PTR                     pvStackBuf;
+    /** Pointer to a ring-3 accessible jump buffer structure for automatic
+     *  mirroring on longjmp. Optional. */
+    R0PTRTYPE(PVMMR0JMPBUF)     pMirrorBuf;
 } VMMR0JMPBUF;
-/** Pointer to a ring-0 jump buffer. */
-typedef VMMR0JMPBUF *PVMMR0JMPBUF;
 
 
@@ -429,9 +416,4 @@
     uint32_t                    u32Padding0;
 
-    /** VMM stack, pointer to the top of the stack in R3.
-     * Stack is allocated from the hypervisor heap and is page aligned
-     * and always writable in RC. */
-    R3PTRTYPE(uint8_t *)        pbEMTStackR3;
-
     /** @name Rendezvous
      * @{ */
@@ -465,18 +447,10 @@
     /** @} */
 
-    /** @name Call Ring-3
-     * Formerly known as host calls.
-     * @{ */
-    /** The disable counter. */
-    uint32_t                    cCallRing3Disabled;
-    uint32_t                    u32Padding3;
-    /** Ring-0 assertion notification callback. */
-    R0PTRTYPE(PFNVMMR0ASSERTIONNOTIFICATION) pfnRing0AssertCallback;
-    /** Argument for pfnRing0AssertionNotificationCallback. */
-    R0PTRTYPE(void *)           pvRing0AssertCallbackUser;
-    /** The Ring-0 jmp buffer.
-     * @remarks The size of this type isn't stable in assembly, so don't put
-     *          anything that needs to be accessed from assembly after it. */
-    VMMR0JMPBUF                 CallRing3JmpBufR0;
+    /** @name Ring-0 assertion info for this EMT.
+     * @{ */
+    /** Copy of the ring-0 jmp buffer after an assertion. */
+    VMMR0JMPBUF                 AssertJmpBuf;
+    /** Copy of the assertion stack. */
+    uint8_t                     abAssertStack[8192];
     /** @} */
 
@@ -540,4 +514,6 @@
      * @note Cannot be put on the stack as the location may change and upset the
      *       validation of resume-after-ring-3-call logic.
+     * @todo This no longer needs to be here now that we don't call ring-3 and mess
+     *       around with stack restoring/switching.
      * @{ */
     PGVM                                pGVM;
@@ -547,4 +523,17 @@
     uint64_t                            u64Arg;
     PSUPDRVSESSION                      pSession;
+    /** @} */
+
+    /** @name Ring-0 setjmp / assertion handling.
+     * @{ */
+    /** The ring-0 setjmp buffer. */
+    VMMR0JMPBUF                         AssertJmpBuf;
+    /** The disable counter. */
+    uint32_t                            cCallRing3Disabled;
+    uint32_t                            u32Padding3;
+    /** Ring-0 assertion notification callback. */
+    R0PTRTYPE(PFNVMMR0ASSERTIONNOTIFICATION) pfnAssertCallback;
+    /** Argument for pfnRing0AssertionNotificationCallback. */
+    R0PTRTYPE(void *)                   pvAssertCallbackUser;
     /** @} */
 
@@ -569,4 +558,5 @@
 AssertCompile(RTASSERT_OFFSET_OF(VMMR0PERVCPU, u.s.RelLogger)
               == RTASSERT_OFFSET_OF(VMMR0PERVCPU, u.aLoggers) + sizeof(VMMR0PERVCPULOGGER) * VMMLOGGER_IDX_RELEASE);
+AssertCompileMemberAlignment(VMMR0PERVCPU, AssertJmpBuf, 64);
 /** Pointer to VMM ring-0 VMCPU instance data. */
 typedef VMMR0PERVCPU *PVMMR0PERVCPU;
Index: /trunk/src/VBox/VMM/include/VMMInternal.mac
===================================================================
--- /trunk/src/VBox/VMM/include/VMMInternal.mac	(revision 92407)
+++ /trunk/src/VBox/VMM/include/VMMInternal.mac	(revision 92408)
@@ -19,92 +19,70 @@
 %include "VBox/sup.mac"
 
-;
-; Determine the default stack switching unless specified explicitly.
-;
-%ifndef VMM_R0_SWITCH_STACK
- %ifndef VMM_R0_NO_SWITCH_STACK
-  %ifdef RT_OS_DARWIN
-   %define VMM_R0_SWITCH_STACK
-  %endif
+
+struc VMMR0JMPBUF
+        ;
+        ; traditional jmp_buf
+        ;
+%ifdef RT_ARCH_X86
+        .ebx                    resd 1
+        .esi                    resd 1
+        .edi                    resd 1
+        .ebp                    resd 1
+        .esp                    resd 1
+        .eip                    resd 1
+        .eflags                 resd 1
+%endif
+%ifdef RT_ARCH_AMD64
+        .rbx                    resq 1
+ %ifdef RT_OS_WINDOWS
+        .rsi                    resq 1
+        .rdi                    resq 1
  %endif
+        .rbp                    resq 1
+        .r12                    resq 1
+        .r13                    resq 1
+        .r14                    resq 1
+        .r15                    resq 1
+        .rsp                    resq 1
+        .rip                    resq 1
+ %ifdef RT_OS_WINDOWS
+        .xmm6                   resq 2
+        .xmm7                   resq 2
+        .xmm8                   resq 2
+        .xmm9                   resq 2
+        .xmm10                  resq 2
+        .xmm11                  resq 2
+        .xmm12                  resq 2
+        .xmm13                  resq 2
+        .xmm14                  resq 2
+        .xmm15                  resq 2
+ %endif
+        .rflags                 resq 1
 %endif
 
+        ;
+        ; Additional state and stack info for unwinding.
+        ;
+        .UnwindSp               RTR0PTR_RES 1
+        .UnwindRetSp            RTR0PTR_RES 1
+        .UnwindBp               RTR0PTR_RES 1
+        .UnwindPc               RTR0PTR_RES 1
+        .UnwindRetPcValue       RTR0PTR_RES 1
+        .UnwindRetPcLocation    RTR0PTR_RES 1
 
-struc VMMR0JMPBUF
-%ifdef RT_ARCH_X86
-    ; traditional jmp_buf
-    .ebx            resd 1
-    .esi            resd 1
-    .edi            resd 1
-    .ebp            resd 1
-    .esp            resd 1
-    .eip            resd 1
-    .eflags         resd 1
+        ;
+        ; Info about what we were doing in case it's helpful.
+        ;
+        .pfn                    RTR0PTR_RES 1
+        .pvUser1                RTR0PTR_RES 1
+        .pvUser2                RTR0PTR_RES 1
 
-    ; additional state and stack info.
-    .fInRing3Call   resd 1
-    .cbSavedStack   resd 1
-    .pvSavedStack   resd 1
-    .SpCheck        resd 1
-    .SpResume       resd 1
-    .SavedEsp       resd 1
-    .SavedEbp       resd 1
-    .SavedEipForUnwind      resd 1
-    .UnwindRetPcValue       resd 1
-    .UnwindRetPcLocation    resd 1
-    .pfn            resd 1
-    .pvUser1        resd 1
-    .pvUser2        resd 1
-%endif
-%ifdef RT_ARCH_AMD64
-    ; traditional jmp_buf
-    .rbx            resq 1
- %ifdef RT_OS_WINDOWS
-    .rsi            resq 1
-    .rdi            resq 1
- %endif
-    .rbp            resq 1
-    .r12            resq 1
-    .r13            resq 1
-    .r14            resq 1
-    .r15            resq 1
-    .rsp            resq 1
-    .rip            resq 1
- %ifdef RT_OS_WINDOWS
-    .xmm6           resq 2
-    .xmm7           resq 2
-    .xmm8           resq 2
-    .xmm9           resq 2
-    .xmm10          resq 2
-    .xmm11          resq 2
-    .xmm12          resq 2
-    .xmm13          resq 2
-    .xmm14          resq 2
-    .xmm15          resq 2
- %endif
-    .rflags         resq 1
-
-    ; additional state and stack info.
-    .fInRing3Call   resd 1
-    .cbSavedStack   resd 1
-    .pvSavedStack   resq 1
-    .SpCheck        resq 1
-    .SpResume       resq 1
-    .SavedEsp       resq 1
-    .SavedEbp       resq 1
-    .SavedEipForUnwind      resq 1
-    .UnwindRetPcValue       resq 1
-    .UnwindRetPcLocation    resq 1
-    .pfn            resq 1
-    .pvUser1        resq 1
-    .pvUser2        resq 1
-%endif
-
-    ; Statistics
-    alignb 8
-    .cbUsedMax      resd 1
-    .cbUsedAvg      resd 1
-    .cbUsedTotal    resq 1
-    .cUsedTotal     resq 1
+        ;
+        ; For mirroring the jump buffer and stack to ring-3 for unwinding and analysis.
+        ;
+        .cbStackValid           resd        1
+        .cbStackBuf             resd        1
+        .pvStackBuf             RTR0PTR_RES 1
+        .pMirrorBuf             RTR0PTR_RES 1
 endstruc
 
@@ -114,5 +92,4 @@
         .iLastGZRc              resd 1
         alignb 8
-        .pbEMTStackR3           RTR3PTR_RES 1
 
         .fInRendezvous          resb 1
@@ -127,10 +104,6 @@
         .TracerCtx              resb SUPDRVTRACERUSRCTX64_size
 
-        .cCallRing3Disabled     resd 1
         alignb 8
-        .pfnRing0AssertCallback RTR0PTR_RES 1
-        .pvRing0AssertCallbackUser RTR0PTR_RES 1
-        alignb 16
-        .CallRing3JmpBufR0      resb 1
+        .AssertJmpBuf           resb 1
 endstruc
 
Index: /trunk/src/VBox/VMM/testcase/Makefile.kmk
===================================================================
--- /trunk/src/VBox/VMM/testcase/Makefile.kmk	(revision 92407)
+++ /trunk/src/VBox/VMM/testcase/Makefile.kmk	(revision 92408)
@@ -71,5 +71,4 @@
 	tstSSM \
 	tstVMMR0CallHost-1 \
-	tstVMMR0CallHost-2 \
 	tstX86-FpuSaveRestore
   ifn1of ($(KBUILD_TARGET).$(KBUILD_TARGET_ARCH), solaris.x86 solaris.amd64 win.amd64 ) ## TODO: Fix the code.
@@ -300,8 +299,7 @@
 
 #
-# Two testcases for checking the ring-3 "long jump" code.
+# Two testcases for checking the ring-0 setjmp/longjmp code.
 #
 tstVMMR0CallHost-1_TEMPLATE = VBOXR3TSTEXE
-tstVMMR0CallHost-1_DEFS = VMM_R0_NO_SWITCH_STACK
 tstVMMR0CallHost-1_INCS = $(VBOX_PATH_VMM_SRC)/include
 tstVMMR0CallHost-1_SOURCES = \
@@ -312,9 +310,4 @@
 	$(VBOX_PATH_VMM_SRC)/VMMR0/VMMR0JmpA-x86.asm
 
-tstVMMR0CallHost-2_EXTENDS = tstVMMR0CallHost-1
-tstVMMR0CallHost-2_DEFS = VMM_R0_SWITCH_STACK
-tstVMMR0CallHost-2_SOURCES.amd64 = \
-	$(tstVMMR0CallHost-1_SOURCES.amd64) \
-	tstVMMR0CallHost-2A.asm
 
 #
Index: /trunk/src/VBox/VMM/testcase/tstVMMR0CallHost-1.cpp
===================================================================
--- /trunk/src/VBox/VMM/testcase/tstVMMR0CallHost-1.cpp	(revision 92407)
+++ /trunk/src/VBox/VMM/testcase/tstVMMR0CallHost-1.cpp	(revision 92408)
@@ -36,16 +36,10 @@
 
 /*********************************************************************************************************************************
-*   Defined Constants And Macros                                                                                                 *
-*********************************************************************************************************************************/
-#if !defined(VMM_R0_SWITCH_STACK) && !defined(VMM_R0_NO_SWITCH_STACK)
-# error "VMM_R0_SWITCH_STACK or VMM_R0_NO_SWITCH_STACK has to be defined."
-#endif
-
-
-/*********************************************************************************************************************************
 *   Global Variables                                                                                                             *
 *********************************************************************************************************************************/
 /** The jump buffer. */
 static VMMR0JMPBUF          g_Jmp;
+/** The mirror jump buffer. */
+static VMMR0JMPBUF          g_JmpMirror;
 /** The number of jumps we've done. */
 static unsigned volatile    g_cJmps;
@@ -67,8 +61,5 @@
     char  *pv = (char *)alloca(cb);
     RTStrPrintf(pv, cb, "i=%d%*s\n", i, cb, "");
-#ifdef VMM_R0_SWITCH_STACK
-    g_cbFooUsed = VMM_STACK_SIZE - ((uintptr_t)pv - (uintptr_t)g_Jmp.pvSavedStack);
-    RTTESTI_CHECK_MSG_RET(g_cbFooUsed < (intptr_t)VMM_STACK_SIZE - 128, ("%#x - (%p - %p) -> %#x; cb=%#x i=%d\n", VMM_STACK_SIZE, pv, g_Jmp.pvSavedStack, g_cbFooUsed, cb, i), -15);
-#elif defined(RT_ARCH_AMD64)
+#if defined(RT_ARCH_AMD64)
     g_cbFooUsed = (uintptr_t)g_Jmp.rsp - (uintptr_t)pv;
     RTTESTI_CHECK_MSG_RET(g_cbFooUsed < VMM_STACK_SIZE - 128, ("%p - %p -> %#x; cb=%#x i=%d\n", g_Jmp.rsp, pv, g_cbFooUsed, cb, i), -15);
@@ -122,13 +113,7 @@
 void tst(int iFrom, int iTo, int iInc)
 {
-#ifdef VMM_R0_SWITCH_STACK
-    int const cIterations = iFrom > iTo ? iFrom - iTo : iTo - iFrom;
-    void   *pvPrev = alloca(1);
-#endif
-
-    RTR0PTR R0PtrSaved = g_Jmp.pvSavedStack;
-    RT_ZERO(g_Jmp);
-    g_Jmp.pvSavedStack = R0PtrSaved;
-    memset((void *)g_Jmp.pvSavedStack, '\0', VMM_STACK_SIZE);
+    RT_BZERO(&g_Jmp, RT_UOFFSETOF(VMMR0JMPBUF, cbStackBuf));
+    g_Jmp.cbStackValid = _1M;
+    memset((void *)g_Jmp.pvStackBuf, '\0', g_Jmp.cbStackBuf);
     g_cbFoo = 0;
     g_cJmps = 0;
@@ -136,339 +121,15 @@
     g_fInLongJmp = false;
 
-    int iOrg = iFrom;
     for (int i = iFrom, iItr = 0; i != iTo; i += iInc, iItr++)
     {
-        if (!g_fInLongJmp)
-            iOrg = i;
-        int rc = stackRandom(&g_Jmp, (PFNVMMR0SETJMP)(uintptr_t)tst2, (PVM)(uintptr_t)iOrg, 0);
+        g_fInLongJmp = false;
+        int rc = stackRandom(&g_Jmp, (PFNVMMR0SETJMP)(uintptr_t)tst2, (PVM)(uintptr_t)i, 0);
         RTTESTI_CHECK_MSG_RETV(rc == (g_fInLongJmp ? 42 : 0),
-                               ("i=%d iOrg=%d rc=%d setjmp; cbFoo=%#x cbFooUsed=%#x fInLongJmp=%d\n",
-                                i, iOrg, rc, g_cbFoo, g_cbFooUsed, g_fInLongJmp));
+                               ("i=%d rc=%d setjmp; cbFoo=%#x cbFooUsed=%#x fInLongJmp=%d\n",
+                                i, rc, g_cbFoo, g_cbFooUsed, g_fInLongJmp));
 
-#ifdef VMM_R0_SWITCH_STACK
-        /* Make the stack pointer slide for the second half of the calls. */
-        if (iItr >= cIterations / 2)
-        {
-            /* Note! gcc does funny rounding up of alloca(). */
-# if !defined(VBOX_WITH_GCC_SANITIZER) && !defined(__MSVC_RUNTIME_CHECKS)
-            void  *pv2 = alloca((i % 63) | 1);
-            size_t cb2 = (uintptr_t)pvPrev - (uintptr_t)pv2;
-# else
-            size_t cb2 = ((i % 3) + 1) * 16; /* We get what we ask for here, and it's not at RSP/ESP due to guards. */
-            void  *pv2 = alloca(cb2);
-# endif
-            RTTESTI_CHECK_MSG(cb2 >= 16 && cb2 <= 128, ("cb2=%zu pv2=%p pvPrev=%p iAlloca=%d\n", cb2, pv2, pvPrev, iItr));
-            memset(pv2, 0xff, cb2);
-            memset(pvPrev, 0xee, 1);
-            pvPrev = pv2;
-        }
-#endif
     }
     RTTESTI_CHECK_MSG_RETV(g_cJmps, ("No jumps!"));
-    if (g_Jmp.cbUsedAvg || g_Jmp.cUsedTotal)
-        RTTestIPrintf(RTTESTLVL_ALWAYS, "cbUsedAvg=%#x cbUsedMax=%#x cUsedTotal=%#llx\n",
-                      g_Jmp.cbUsedAvg, g_Jmp.cbUsedMax, g_Jmp.cUsedTotal);
 }
-
-
-#if defined(VMM_R0_SWITCH_STACK) && defined(RT_ARCH_AMD64)
-/*
- * Stack switch back tests.
- */
-RT_C_DECLS_BEGIN
-DECLCALLBACK(int) tstWrapped4(         PVMMR0JMPBUF pJmp, uintptr_t u2, uintptr_t u3,  uintptr_t u4);
-DECLCALLBACK(int) StkBack_tstWrapped4( PVMMR0JMPBUF pJmp, uintptr_t u2, uintptr_t u3,  uintptr_t u4);
-DECLCALLBACK(int) tstWrapped5(         PVMMR0JMPBUF pJmp, uintptr_t u2, uintptr_t u3,  uintptr_t u4, uintptr_t u5);
-DECLCALLBACK(int) StkBack_tstWrapped5( PVMMR0JMPBUF pJmp, uintptr_t u2, uintptr_t u3,  uintptr_t u4, uintptr_t u5);
-DECLCALLBACK(int) tstWrapped6(         PVMMR0JMPBUF pJmp, uintptr_t u2, uintptr_t u3,  uintptr_t u4, uintptr_t u5, uintptr_t u6);
-DECLCALLBACK(int) StkBack_tstWrapped6( PVMMR0JMPBUF pJmp, uintptr_t u2, uintptr_t u3,  uintptr_t u4, uintptr_t u5, uintptr_t u6);
-DECLCALLBACK(int) tstWrapped7(         PVMMR0JMPBUF pJmp, uintptr_t u2, uintptr_t u3,  uintptr_t u4, uintptr_t u5, uintptr_t u6, uintptr_t u7);
-DECLCALLBACK(int) StkBack_tstWrapped7( PVMMR0JMPBUF pJmp, uintptr_t u2, uintptr_t u3,  uintptr_t u4, uintptr_t u5, uintptr_t u6, uintptr_t u7);
-DECLCALLBACK(int) tstWrapped8(         PVMMR0JMPBUF pJmp, uintptr_t u2, uintptr_t u3,  uintptr_t u4, uintptr_t u5, uintptr_t u6, uintptr_t u7, uintptr_t u8);
-DECLCALLBACK(int) StkBack_tstWrapped8( PVMMR0JMPBUF pJmp, uintptr_t u2, uintptr_t u3,  uintptr_t u4, uintptr_t u5, uintptr_t u6, uintptr_t u7, uintptr_t u8);
-DECLCALLBACK(int) tstWrapped9(         PVMMR0JMPBUF pJmp, uintptr_t u2,  uintptr_t u3, uintptr_t u4, uintptr_t u5, uintptr_t u6, uintptr_t u7, uintptr_t u8, uintptr_t u9);
-DECLCALLBACK(int) StkBack_tstWrapped9( PVMMR0JMPBUF pJmp, uintptr_t u2,  uintptr_t u3, uintptr_t u4, uintptr_t u5, uintptr_t u6, uintptr_t u7, uintptr_t u8, uintptr_t u9);
-DECLCALLBACK(int) tstWrapped10(        PVMMR0JMPBUF pJmp, uintptr_t u2,  uintptr_t u3, uintptr_t u4, uintptr_t u5, uintptr_t u6, uintptr_t u7, uintptr_t u8, uintptr_t u9, uintptr_t u10);
-DECLCALLBACK(int) StkBack_tstWrapped10(PVMMR0JMPBUF pJmp, uintptr_t u2,  uintptr_t u3, uintptr_t u4, uintptr_t u5, uintptr_t u6, uintptr_t u7, uintptr_t u8, uintptr_t u9, uintptr_t u10);
-DECLCALLBACK(int) tstWrapped16(        PVMMR0JMPBUF pJmp, uintptr_t u2,  uintptr_t u3, uintptr_t u4, uintptr_t u5, uintptr_t u6, uintptr_t u7, uintptr_t u8, uintptr_t u9, uintptr_t u10, uintptr_t u11, uintptr_t u12, uintptr_t u13, uintptr_t u14, uintptr_t u15, uintptr_t u16);
-DECLCALLBACK(int) StkBack_tstWrapped16(PVMMR0JMPBUF pJmp, uintptr_t u2,  uintptr_t u3, uintptr_t u4, uintptr_t u5, uintptr_t u6, uintptr_t u7, uintptr_t u8, uintptr_t u9, uintptr_t u10, uintptr_t u11, uintptr_t u12, uintptr_t u13, uintptr_t u14, uintptr_t u15, uintptr_t u16);
-DECLCALLBACK(int) tstWrapped20(        PVMMR0JMPBUF pJmp, uintptr_t u2,  uintptr_t u3, uintptr_t u4, uintptr_t u5, uintptr_t u6, uintptr_t u7, uintptr_t u8, uintptr_t u9, uintptr_t u10, uintptr_t u11, uintptr_t u12, uintptr_t u13, uintptr_t u14, uintptr_t u15, uintptr_t u16, uintptr_t u17, uintptr_t u18, uintptr_t u19, uintptr_t u20);
-DECLCALLBACK(int) StkBack_tstWrapped20(PVMMR0JMPBUF pJmp, uintptr_t u2,  uintptr_t u3, uintptr_t u4, uintptr_t u5, uintptr_t u6, uintptr_t u7, uintptr_t u8, uintptr_t u9, uintptr_t u10, uintptr_t u11, uintptr_t u12, uintptr_t u13, uintptr_t u14, uintptr_t u15, uintptr_t u16, uintptr_t u17, uintptr_t u18, uintptr_t u19, uintptr_t u20);
-
-DECLCALLBACK(int) tstWrappedThin(PVMMR0JMPBUF pJmp);
-DECLCALLBACK(int) StkBack_tstWrappedThin(PVMMR0JMPBUF pJmp);
-RT_C_DECLS_END
-
-
-
-DECLCALLBACK(int) StkBack_tstWrapped4(PVMMR0JMPBUF pJmp, uintptr_t u2,  uintptr_t u3, uintptr_t u4)
-{
-    RTTESTI_CHECK_RET(pJmp == &g_Jmp, -1);
-    RTTESTI_CHECK_RET(u2 == (uintptr_t)2U, -2);
-    RTTESTI_CHECK_RET(u3 == (uintptr_t)3U, -3);
-    RTTESTI_CHECK_RET(u4 == (uintptr_t)4U, -4);
-
-    void *pv = alloca(32);
-    memset(pv, 'a', 32);
-    RTTESTI_CHECK_RET((uintptr_t)pv - (uintptr_t)g_Jmp.pvSavedStack > VMM_STACK_SIZE, -11);
-
-    return 42;
-}
-
-
-DECLCALLBACK(int) StkBack_tstWrapped5(PVMMR0JMPBUF pJmp, uintptr_t u2,  uintptr_t u3, uintptr_t u4, uintptr_t u5)
-{
-    RTTESTI_CHECK_RET(pJmp == &g_Jmp, -1);
-    RTTESTI_CHECK_RET(u2 == ~(uintptr_t)2U, -2);
-    RTTESTI_CHECK_RET(u3 == ~(uintptr_t)3U, -3);
-    RTTESTI_CHECK_RET(u4 == ~(uintptr_t)4U, -4);
-    RTTESTI_CHECK_RET(u5 == ~(uintptr_t)5U, -5);
-
-    void *pv = alloca(32);
-    memset(pv, 'a', 32);
-    RTTESTI_CHECK_RET((uintptr_t)pv - (uintptr_t)g_Jmp.pvSavedStack > VMM_STACK_SIZE, -11);
-
-    return 42;
-}
-
-
-DECLCALLBACK(int) StkBack_tstWrapped6(PVMMR0JMPBUF pJmp, uintptr_t u2,  uintptr_t u3, uintptr_t u4, uintptr_t u5, uintptr_t u6)
-{
-    RTTESTI_CHECK_RET(pJmp == &g_Jmp, -1);
-    RTTESTI_CHECK_RET(u2 ==  (uintptr_t)2U, -2);
-    RTTESTI_CHECK_RET(u3 ==  (uintptr_t)3U, -3);
-    RTTESTI_CHECK_RET(u4 ==  (uintptr_t)4U, -4);
-    RTTESTI_CHECK_RET(u5 ==  (uintptr_t)5U, -5);
-    RTTESTI_CHECK_RET(u6 ==  (uintptr_t)6U, -6);
-
-    void *pv = alloca(32);
-    memset(pv, 'a', 32);
-    RTTESTI_CHECK_RET((uintptr_t)pv - (uintptr_t)g_Jmp.pvSavedStack > VMM_STACK_SIZE, -11);
-
-    return 42;
-}
-
-
-DECLCALLBACK(int) StkBack_tstWrapped7(PVMMR0JMPBUF pJmp, uintptr_t u2,  uintptr_t u3, uintptr_t u4, uintptr_t u5, uintptr_t u6, uintptr_t u7)
-{
-    RTTESTI_CHECK_RET(pJmp == &g_Jmp, -1);
-    RTTESTI_CHECK_RET(u2 == ~(uintptr_t)2U, -2);
-    RTTESTI_CHECK_RET(u3 == ~(uintptr_t)3U, -3);
-    RTTESTI_CHECK_RET(u4 == ~(uintptr_t)4U, -4);
-    RTTESTI_CHECK_RET(u5 == ~(uintptr_t)5U, -5);
-    RTTESTI_CHECK_RET(u6 == ~(uintptr_t)6U, -6);
-    RTTESTI_CHECK_RET(u7 == ~(uintptr_t)7U, -7);
-
-    void *pv = alloca(32);
-    memset(pv, 'a', 32);
-    RTTESTI_CHECK_RET((uintptr_t)pv - (uintptr_t)g_Jmp.pvSavedStack > VMM_STACK_SIZE, -11);
-
-    return 42;
-}
-
-
-DECLCALLBACK(int) StkBack_tstWrapped8(PVMMR0JMPBUF pJmp, uintptr_t u2,  uintptr_t u3, uintptr_t u4, uintptr_t u5, uintptr_t u6, uintptr_t u7, uintptr_t u8)
-{
-    RTTESTI_CHECK_RET(pJmp == &g_Jmp, -1);
-    RTTESTI_CHECK_RET(u2 ==  (uintptr_t)2U, -2);
-    RTTESTI_CHECK_RET(u3 ==  (uintptr_t)3U, -3);
-    RTTESTI_CHECK_RET(u4 ==  (uintptr_t)4U, -4);
-    RTTESTI_CHECK_RET(u5 ==  (uintptr_t)5U, -5);
-    RTTESTI_CHECK_RET(u6 ==  (uintptr_t)6U, -6);
-    RTTESTI_CHECK_RET(u7 ==  (uintptr_t)7U, -7);
-    RTTESTI_CHECK_RET(u8 ==  (uintptr_t)8U, -8);
-
-    void *pv = alloca(32);
-    memset(pv, 'a', 32);
-    RTTESTI_CHECK_RET((uintptr_t)pv - (uintptr_t)g_Jmp.pvSavedStack > VMM_STACK_SIZE, -11);
-
-    return 42;
-}
-
-DECLCALLBACK(int) StkBack_tstWrapped9(PVMMR0JMPBUF pJmp, uintptr_t u2,  uintptr_t u3, uintptr_t u4, uintptr_t u5, uintptr_t u6, uintptr_t u7, uintptr_t u8, uintptr_t u9)
-{
-    RTTESTI_CHECK_RET(pJmp == &g_Jmp, -1);
-    RTTESTI_CHECK_RET(u2 == ~(uintptr_t)2U, -2);
-    RTTESTI_CHECK_RET(u3 == ~(uintptr_t)3U, -3);
-    RTTESTI_CHECK_RET(u4 == ~(uintptr_t)4U, -4);
-    RTTESTI_CHECK_RET(u5 == ~(uintptr_t)5U, -5);
-    RTTESTI_CHECK_RET(u6 == ~(uintptr_t)6U, -6);
-    RTTESTI_CHECK_RET(u7 == ~(uintptr_t)7U, -7);
-    RTTESTI_CHECK_RET(u8 == ~(uintptr_t)8U, -8);
-    RTTESTI_CHECK_RET(u9 == ~(uintptr_t)9U, -9);
-
-    void *pv = alloca(32);
-    memset(pv, 'a', 32);
-    RTTESTI_CHECK_RET((uintptr_t)pv - (uintptr_t)g_Jmp.pvSavedStack > VMM_STACK_SIZE, -11);
-
-    return 42;
-}
-
-
-DECLCALLBACK(int) StkBack_tstWrapped10(PVMMR0JMPBUF pJmp, uintptr_t u2,  uintptr_t u3, uintptr_t u4, uintptr_t u5, uintptr_t u6, uintptr_t u7, uintptr_t u8, uintptr_t u9, uintptr_t u10)
-{
-    RTTESTI_CHECK_RET(pJmp == &g_Jmp, -1);
-    RTTESTI_CHECK_RET(u2 ==  (uintptr_t)2U, -2);
-    RTTESTI_CHECK_RET(u3 ==  (uintptr_t)3U, -3);
-    RTTESTI_CHECK_RET(u4 ==  (uintptr_t)4U, -4);
-    RTTESTI_CHECK_RET(u5 ==  (uintptr_t)5U, -5);
-    RTTESTI_CHECK_RET(u6 ==  (uintptr_t)6U, -6);
-    RTTESTI_CHECK_RET(u7 ==  (uintptr_t)7U, -7);
-    RTTESTI_CHECK_RET(u8 ==  (uintptr_t)8U, -8);
-    RTTESTI_CHECK_RET(u9 ==  (uintptr_t)9U, -9);
-    RTTESTI_CHECK_RET(u10 == (uintptr_t)10U, -10);
-
-    void *pv = alloca(32);
-    memset(pv, 'a', 32);
-    RTTESTI_CHECK_RET((uintptr_t)pv - (uintptr_t)g_Jmp.pvSavedStack > VMM_STACK_SIZE, -11);
-
-    return 42;
-}
-
-
-DECLCALLBACK(int) StkBack_tstWrapped16(PVMMR0JMPBUF pJmp, uintptr_t u2,  uintptr_t u3, uintptr_t u4, uintptr_t u5, uintptr_t u6, uintptr_t u7, uintptr_t u8, uintptr_t u9, uintptr_t u10, uintptr_t u11, uintptr_t u12, uintptr_t u13, uintptr_t u14, uintptr_t u15, uintptr_t u16)
-{
-    RTTESTI_CHECK_RET(pJmp == &g_Jmp, -1);
-    RTTESTI_CHECK_RET(u2 ==  (uintptr_t)2U, -2);
-    RTTESTI_CHECK_RET(u3 ==  (uintptr_t)3U, -3);
-    RTTESTI_CHECK_RET(u4 ==  (uintptr_t)4U, -4);
-    RTTESTI_CHECK_RET(u5 ==  (uintptr_t)5U, -5);
-    RTTESTI_CHECK_RET(u6 ==  (uintptr_t)6U, -6);
-    RTTESTI_CHECK_RET(u7 ==  (uintptr_t)7U, -7);
-    RTTESTI_CHECK_RET(u8 ==  (uintptr_t)8U, -8);
-    RTTESTI_CHECK_RET(u9 ==  (uintptr_t)9U, -9);
-    RTTESTI_CHECK_RET(u10 == (uintptr_t)10U, -10);
-    RTTESTI_CHECK_RET(u11 == (uintptr_t)11U, -11);
-    RTTESTI_CHECK_RET(u12 == (uintptr_t)12U, -12);
-    RTTESTI_CHECK_RET(u13 == (uintptr_t)13U, -13);
-    RTTESTI_CHECK_RET(u14 == (uintptr_t)14U, -14);
-    RTTESTI_CHECK_RET(u15 == (uintptr_t)15U, -15);
-    RTTESTI_CHECK_RET(u16 == (uintptr_t)16U, -16);
-
-    void *pv = alloca(32);
-    memset(pv, 'a', 32);
-    RTTESTI_CHECK_RET((uintptr_t)pv - (uintptr_t)g_Jmp.pvSavedStack > VMM_STACK_SIZE, -11);
-
-    return 42;
-}
-
-
-DECLCALLBACK(int) StkBack_tstWrapped20(PVMMR0JMPBUF pJmp, uintptr_t u2,  uintptr_t u3, uintptr_t u4, uintptr_t u5, uintptr_t u6, uintptr_t u7, uintptr_t u8, uintptr_t u9, uintptr_t u10, uintptr_t u11, uintptr_t u12, uintptr_t u13, uintptr_t u14, uintptr_t u15, uintptr_t u16, uintptr_t u17, uintptr_t u18, uintptr_t u19, uintptr_t u20)
-{
-    RTTESTI_CHECK_RET(pJmp == &g_Jmp, -1);
-    RTTESTI_CHECK_RET(u2 ==  (uintptr_t)2U, -2);
-    RTTESTI_CHECK_RET(u3 ==  (uintptr_t)3U, -3);
-    RTTESTI_CHECK_RET(u4 ==  (uintptr_t)4U, -4);
-    RTTESTI_CHECK_RET(u5 ==  (uintptr_t)5U, -5);
-    RTTESTI_CHECK_RET(u6 ==  (uintptr_t)6U, -6);
-    RTTESTI_CHECK_RET(u7 ==  (uintptr_t)7U, -7);
-    RTTESTI_CHECK_RET(u8 ==  (uintptr_t)8U, -8);
-    RTTESTI_CHECK_RET(u9 ==  (uintptr_t)9U, -9);
-    RTTESTI_CHECK_RET(u10 == (uintptr_t)10U, -10);
-    RTTESTI_CHECK_RET(u11 == (uintptr_t)11U, -11);
-    RTTESTI_CHECK_RET(u12 == (uintptr_t)12U, -12);
-    RTTESTI_CHECK_RET(u13 == (uintptr_t)13U, -13);
-    RTTESTI_CHECK_RET(u14 == (uintptr_t)14U, -14);
-    RTTESTI_CHECK_RET(u15 == (uintptr_t)15U, -15);
-    RTTESTI_CHECK_RET(u16 == (uintptr_t)16U, -16);
-    RTTESTI_CHECK_RET(u17 == (uintptr_t)17U, -17);
-    RTTESTI_CHECK_RET(u18 == (uintptr_t)18U, -18);
-    RTTESTI_CHECK_RET(u19 == (uintptr_t)19U, -19);
-    RTTESTI_CHECK_RET(u20 == (uintptr_t)20U, -20);
-
-    void *pv = alloca(32);
-    memset(pv, 'a', 32);
-    RTTESTI_CHECK_RET((uintptr_t)pv - (uintptr_t)g_Jmp.pvSavedStack > VMM_STACK_SIZE, -11);
-
-    return 42;
-}
-
-
-DECLCALLBACK(int) tstSwitchBackInner(intptr_t i1, intptr_t i2)
-{
-    RTTESTI_CHECK_RET(i1 == -42, -20);
-    RTTESTI_CHECK_RET(i2 == (intptr_t)&g_Jmp, -21);
-
-    void *pv = alloca(32);
-    memset(pv, 'b', 32);
-    RTTESTI_CHECK_RET((uintptr_t)pv - (uintptr_t)g_Jmp.pvSavedStack < VMM_STACK_SIZE, -22);
-
-    int rc;
-    rc = tstWrapped4(&g_Jmp,  (uintptr_t)2U,  (uintptr_t)3U,  (uintptr_t)4U);
-    RTTESTI_CHECK_RET(rc == 42, -23);
-
-    rc = tstWrapped5(&g_Jmp, ~(uintptr_t)2U, ~(uintptr_t)3U, ~(uintptr_t)4U, ~(uintptr_t)5U);
-    RTTESTI_CHECK_RET(rc == 42, -23);
-
-    rc = tstWrapped6(&g_Jmp,  (uintptr_t)2U,  (uintptr_t)3U,  (uintptr_t)4U,  (uintptr_t)5U,  (uintptr_t)6U);
-    RTTESTI_CHECK_RET(rc == 42, -23);
-
-    rc = tstWrapped7(&g_Jmp, ~(uintptr_t)2U, ~(uintptr_t)3U, ~(uintptr_t)4U, ~(uintptr_t)5U, ~(uintptr_t)6U, ~(uintptr_t)7U);
-    RTTESTI_CHECK_RET(rc == 42, -23);
-
-    rc = tstWrapped8(&g_Jmp,  (uintptr_t)2U,  (uintptr_t)3U,  (uintptr_t)4U,  (uintptr_t)5U,  (uintptr_t)6U,  (uintptr_t)7U,  (uintptr_t)8U);
-    RTTESTI_CHECK_RET(rc == 42, -23);
-
-    rc = tstWrapped9(&g_Jmp, ~(uintptr_t)2U, ~(uintptr_t)3U, ~(uintptr_t)4U, ~(uintptr_t)5U, ~(uintptr_t)6U, ~(uintptr_t)7U, ~(uintptr_t)8U, ~(uintptr_t)9U);
-    RTTESTI_CHECK_RET(rc == 42, -23);
-
-    rc = tstWrapped10(&g_Jmp, (uintptr_t)2U,  (uintptr_t)3U,  (uintptr_t)4U,  (uintptr_t)5U,  (uintptr_t)6U,  (uintptr_t)7U,  (uintptr_t)8U,  (uintptr_t)9U,  (uintptr_t)10);
-    RTTESTI_CHECK_RET(rc == 42, -23);
-
-    rc = tstWrapped16(&g_Jmp, (uintptr_t)2U,  (uintptr_t)3U,  (uintptr_t)4U,  (uintptr_t)5U,  (uintptr_t)6U,  (uintptr_t)7U,  (uintptr_t)8U,  (uintptr_t)9U,  (uintptr_t)10,  (uintptr_t)11,  (uintptr_t)12,  (uintptr_t)13,  (uintptr_t)14,  (uintptr_t)15,  (uintptr_t)16);
-    RTTESTI_CHECK_RET(rc == 42, -23);
-
-    rc = tstWrapped20(&g_Jmp, (uintptr_t)2U,  (uintptr_t)3U,  (uintptr_t)4U,  (uintptr_t)5U,  (uintptr_t)6U,  (uintptr_t)7U,  (uintptr_t)8U,  (uintptr_t)9U,  (uintptr_t)10,  (uintptr_t)11,  (uintptr_t)12,  (uintptr_t)13,  (uintptr_t)14,  (uintptr_t)15,  (uintptr_t)16,  (uintptr_t)17,  (uintptr_t)18,  (uintptr_t)19,  (uintptr_t)20);
-    RTTESTI_CHECK_RET(rc == 42, -23);
-    return rc;
-}
-
-
-DECLCALLBACK(int) StkBack_tstWrappedThin(PVMMR0JMPBUF pJmp)
-{
-    RTTESTI_CHECK_RET(pJmp == &g_Jmp, -31);
-
-    void *pv = alloca(32);
-    memset(pv, 'c', 32);
-    RTTESTI_CHECK_RET((uintptr_t)pv - (uintptr_t)g_Jmp.pvSavedStack > VMM_STACK_SIZE, -32);
-
-    return 42;
-}
-
-DECLCALLBACK(int) tstSwitchBackInnerThin(intptr_t i1, intptr_t i2)
-{
-    RT_NOREF(i1);
-    return tstWrappedThin((PVMMR0JMPBUF)i2);
-}
-
-
-void tstSwitchBack(void)
-{
-    RTR0PTR R0PtrSaved = g_Jmp.pvSavedStack;
-    RT_ZERO(g_Jmp);
-    g_Jmp.pvSavedStack = R0PtrSaved;
-    memset((void *)g_Jmp.pvSavedStack, '\0', VMM_STACK_SIZE);
-    g_cbFoo = 0;
-    g_cJmps = 0;
-    g_cbFooUsed = 0;
-    g_fInLongJmp = false;
-
-    //for (int i = iFrom, iItr = 0; i != iTo; i += iInc, iItr++)
-    {
-        int rc = stackRandom(&g_Jmp, (PFNVMMR0SETJMP)(uintptr_t)tstSwitchBackInner, (PVM)(intptr_t)-42, (PVMCPU)&g_Jmp);
-        RTTESTI_CHECK_MSG_RETV(rc == 42,
-                               ("i=%d iOrg=%d rc=%d setjmp; cbFoo=%#x cbFooUsed=%#x fInLongJmp=%d\n",
-                                0, 0 /*i, iOrg*/, rc, g_cbFoo, g_cbFooUsed, g_fInLongJmp));
-
-        rc = stackRandom(&g_Jmp, (PFNVMMR0SETJMP)(uintptr_t)tstSwitchBackInnerThin, NULL, (PVMCPU)&g_Jmp);
-        RTTESTI_CHECK_MSG_RETV(rc == 42,
-                               ("i=%d iOrg=%d rc=%d setjmp; cbFoo=%#x cbFooUsed=%#x fInLongJmp=%d\n",
-                                0, 0 /*i, iOrg*/, rc, g_cbFoo, g_cbFooUsed, g_fInLongJmp));
-
-    }
-    //RTTESTI_CHECK_MSG_RETV(g_cJmps, ("No jumps!"));
-}
-
-#endif
 
 
@@ -479,14 +140,12 @@
      */
     RTTEST hTest;
-#ifdef VMM_R0_NO_SWITCH_STACK
     RTEXITCODE rcExit = RTTestInitAndCreate("tstVMMR0CallHost-1", &hTest);
-#else
-    RTEXITCODE rcExit = RTTestInitAndCreate("tstVMMR0CallHost-2", &hTest);
-#endif
     if (rcExit != RTEXITCODE_SUCCESS)
         return rcExit;
     RTTestBanner(hTest);
 
-    g_Jmp.pvSavedStack = (RTR0PTR)RTTestGuardedAllocTail(hTest, VMM_STACK_SIZE);
+    g_Jmp.cbStackBuf = PAGE_SIZE;
+    g_Jmp.pvStackBuf = (uintptr_t)RTTestGuardedAllocTail(hTest, g_Jmp.cbStackBuf);
+    g_Jmp.pMirrorBuf = (uintptr_t)&g_JmpMirror;
 
     /*
@@ -497,8 +156,4 @@
     RTTestSub(hTest, "Decreasing stack usage");
     tst(7599, 0, -1);
-#if defined(VMM_R0_SWITCH_STACK) && defined(RT_ARCH_AMD64)
-    RTTestSub(hTest, "Switch back");
-    tstSwitchBack();
-#endif
 
     return RTTestSummaryAndDestroy(hTest);
Index: unk/src/VBox/VMM/testcase/tstVMMR0CallHost-2A.asm
===================================================================
--- /trunk/src/VBox/VMM/testcase/tstVMMR0CallHost-2A.asm	(revision 92407)
+++ 	(revision )
@@ -1,30 +1,0 @@
-; $Id$
-;; @file
-; VMM - tstVMMR0CallHost-2A.asm - Switch-back wrapper.
-;
-
-;
-; Copyright (C) 2006-2021 Oracle Corporation
-;
-; This file is part of VirtualBox Open Source Edition (OSE), as
-; available from http://www.virtualbox.org. This file is free software;
-; you can redistribute it and/or modify it under the terms of the GNU
-; General Public License (GPL) as published by the Free Software
-; Foundation, in version 2 as it comes in the "COPYING" file of the
-; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
-; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
-;
-
-%include "VBox/SUPR0StackWrapper.mac"
-
-SUPR0StackWrapperGeneric tstWrappedThin, 1
-SUPR0StackWrapperGeneric tstWrapped4,    4
-SUPR0StackWrapperGeneric tstWrapped5,    5
-SUPR0StackWrapperGeneric tstWrapped6,    6
-SUPR0StackWrapperGeneric tstWrapped7,    7
-SUPR0StackWrapperGeneric tstWrapped8,    8
-SUPR0StackWrapperGeneric tstWrapped9,    9
-SUPR0StackWrapperGeneric tstWrapped10,   10
-SUPR0StackWrapperGeneric tstWrapped16,   16
-SUPR0StackWrapperGeneric tstWrapped20,   20
-
Index: /trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp
===================================================================
--- /trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp	(revision 92407)
+++ /trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp	(revision 92408)
@@ -265,9 +265,4 @@
     PVM pVM = NULL; NOREF(pVM);
 
-#if defined(RT_OS_WINDOWS) && defined(RT_ARCH_AMD64)
-    CHECK_MEMBER_ALIGNMENT(VMCPU, vmm.s.CallRing3JmpBufR0, 16);
-    CHECK_MEMBER_ALIGNMENT(VMCPU, vmm.s.CallRing3JmpBufR0.xmm6, 16);
-#endif
-
     /* the VMCPUs are page aligned TLB hit reasons. */
     CHECK_SIZE_ALIGNMENT(VMCPU, 4096);
