Index: /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 48359)
+++ /trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 48360)
@@ -4060,5 +4060,9 @@
 #if HC_ARCH_BITS == 32 && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
         /* 32-bit host. We need to switch to 64-bit before running the 64-bit guest. */
-        pVCpu->hm.s.vmx.pfnStartVM = VMXR0SwitcherStartVM64;
+        if (pVCpu->hm.s.vmx.pfnStartVM != VMXR0SwitcherStartVM64)
+        {
+            pVCpu->hm.s.vmx.pfnStartVM = VMXR0SwitcherStartVM64;
+            pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_HOST_CONTEXT | HM_CHANGED_VMX_EXIT_CTLS | HM_CHANGED_VMX_ENTRY_CTLS;
+        }
 #else
         /* 64-bit host or hybrid host. */
@@ -4073,10 +4077,5 @@
         {
             pVCpu->hm.s.vmx.pfnStartVM = VMXR0StartVM32;
-            /** @todo r=bird: Don't we need to set up the host resume (after
-             *        vmlaunch/vmresume) state here??  I'm forcing a trip to ring-3 now
-             *        in the hope that it will prevent crashing the host.  A better
-             *        fix should be found as the guest may be going back and forth
-             *        between 16/32-bit and long mode frequently at times. */
-            VMCPU_FF_SET(pVCpu, VMCPU_FF_TO_R3);
+            pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_HOST_CONTEXT | HM_CHANGED_VMX_EXIT_CTLS | HM_CHANGED_VMX_ENTRY_CTLS;
         }
 #else
@@ -7171,7 +7170,11 @@
      * Ideally, assert that the cross-dependent bits are up to date at the point of using it.
      */
-    int rc = hmR0VmxLoadGuestEntryCtls(pVCpu, pMixedCtx);
+    int rc = hmR0VmxSetupVMRunHandler(pVCpu, pMixedCtx);
+    AssertLogRelMsgRCReturn(rc, ("hmR0VmxSetupVMRunHandler! rc=%Rrc (pVM=%p pVCpu=%p)\n", rc, pVM, pVCpu), rc);
+
+    rc = hmR0VmxLoadGuestEntryCtls(pVCpu, pMixedCtx);
     AssertLogRelMsgRCReturn(rc, ("hmR0VmxLoadGuestEntryCtls! rc=%Rrc (pVM=%p pVCpu=%p)\n", rc, pVM, pVCpu), rc);
 
+    /* This needs to be done after pfnStartVM is set as it may require exit guest controls changes. */
     rc = hmR0VmxLoadGuestExitCtls(pVCpu, pMixedCtx);
     AssertLogRelMsgRCReturn(rc, ("hmR0VmxSetupExitCtls failed! rc=%Rrc (pVM=%p pVCpu=%p)\n", rc, pVM, pVCpu), rc);
@@ -7199,7 +7202,4 @@
     rc = hmR0VmxLoadGuestRipRspRflags(pVCpu, pMixedCtx);
     AssertLogRelMsgRCReturn(rc, ("hmR0VmxLoadGuestRipRspRflags! rc=%Rrc (pVM=%p pVCpu=%p)\n", rc, pVM, pVCpu), rc);
-
-    rc = hmR0VmxSetupVMRunHandler(pVCpu, pMixedCtx);
-    AssertLogRelMsgRCReturn(rc, ("hmR0VmxSetupVMRunHandler! rc=%Rrc (pVM=%p pVCpu=%p)\n", rc, pVM, pVCpu), rc);
 
     /* Clear any unused and reserved bits. */
@@ -7472,4 +7472,5 @@
     if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_HOST_CONTEXT)
     {
+        /* This ASSUMES that pfnStartVM has been set up already. */
         Assert(VMMR0ThreadCtxHooksAreRegistered(pVCpu));
         int rc = hmR0VmxSaveHostState(pVM, pVCpu);
