Index: /trunk/src/VBox/VMM/VMMAll/IEMAllCImplSvmInstr.cpp.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllCImplSvmInstr.cpp.h	(revision 68149)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllCImplSvmInstr.cpp.h	(revision 68150)
@@ -52,27 +52,24 @@
 
 /**
- * Helper for handling a SVM world-switch (VMRUN, \#VMEXIT).
+ * Performs an SVM world-switch (VMRUN, \#VMEXIT) updating PGM and IEM internals.
  *
  * @returns Strict VBox status code.
  * @param   pVCpu       The cross context virtual CPU structure.
- * @param   uOldEfer    EFER MSR prior to the world-switch.
- * @param   uOldCr0     CR0 prior to the world-switch.
- */
-DECLINLINE(VBOXSTRICTRC) iemSvmHandleWorldSwitch(PVMCPU pVCpu, uint64_t uOldEfer, uint64_t uOldCr0)
-{
-    RT_NOREF(uOldEfer); RT_NOREF(uOldCr0);
-
-    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
+ * @param   pCtx        The guest-CPU context.
+ */
+DECLINLINE(VBOXSTRICTRC) iemSvmWorldSwitch(PVMCPU pVCpu, PCPUMCTX pCtx)
+{
+    /* Flush the TLB with new CR3. */
+    PGMFlushTLB(pVCpu, pCtx->cr3, true);
 
     /*
-     * Inform PGM.
+     * Inform PGM about paging mode changes.
      * We include X86_CR0_PE because PGM doesn't handle paged-real mode yet,
      * see comment in iemMemPageTranslateAndCheckAccess().
      */
-    PGMFlushTLB(pVCpu, pCtx->cr3, true);
     int rc = PGMChangeMode(pVCpu, pCtx->cr0 | X86_CR0_PE, pCtx->cr4, pCtx->msrEFER);
     AssertRCReturn(rc, rc);
 
-    /* Inform CPUM (recompiler). */
+    /* Inform CPUM (recompiler), can later be removed. */
     CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_ALL);
 
@@ -227,7 +224,4 @@
                 /** @todo ASID. */
 
-                uint64_t const uOldCr0  = pCtx->cr0;
-                uint64_t const uOldEfer = pCtx->msrEFER;
-
                 /*
                  * Reload the guest's "host state".
@@ -260,10 +254,13 @@
                 /* Restore guest's force-flags. */
                 if (pCtx->hwvirt.fLocalForcedActions)
+                {
                     VMCPU_FF_SET(pVCpu, pCtx->hwvirt.fLocalForcedActions);
+                    pCtx->hwvirt.fLocalForcedActions = 0;
+                }
 
                 /*
-                 * Inform PGM and others of the world-switch.
+                 * Update PGM, IEM and others of a world-switch.
                  */
-                rcStrict = iemSvmHandleWorldSwitch(pVCpu, uOldEfer, uOldCr0);
+                rcStrict = iemSvmWorldSwitch(pVCpu, pCtx);
                 if (rcStrict == VINF_SUCCESS)
                     return VINF_SVM_VMEXIT;
@@ -271,10 +268,10 @@
                 if (RT_SUCCESS(rcStrict))
                 {
-                    LogFlow(("iemSvmVmexit: Setting passup status from iemSvmHandleWorldSwitch %Rrc\n", rcStrict));
+                    LogFlow(("iemSvmVmexit: Setting passup status from iemSvmWorldSwitch %Rrc\n", rcStrict));
                     iemSetPassUpStatus(pVCpu, rcStrict);
                     return VINF_SVM_VMEXIT;
                 }
 
-                LogFlow(("iemSvmVmexit: iemSvmHandleWorldSwitch unexpected failure. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
+                LogFlow(("iemSvmVmexit: iemSvmWorldSwitch unexpected failure. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
             }
             else
@@ -327,4 +324,23 @@
 
     /*
+     * Save the host state.
+     */
+    PSVMHOSTSTATE pHostState = &pCtx->hwvirt.svm.HostState;
+    pHostState->es       = pCtx->es;
+    pHostState->cs       = pCtx->cs;
+    pHostState->ss       = pCtx->ss;
+    pHostState->ds       = pCtx->ds;
+    pHostState->gdtr     = pCtx->gdtr;
+    pHostState->idtr     = pCtx->idtr;
+    pHostState->uEferMsr = pCtx->msrEFER;
+    pHostState->uCr0     = pCtx->cr0;
+    pHostState->uCr3     = pCtx->cr3;
+    pHostState->uCr4     = pCtx->cr4;
+    pHostState->rflags   = pCtx->rflags;
+    pHostState->uRip     = pCtx->rip + cbInstr;
+    pHostState->uRsp     = pCtx->rsp;
+    pHostState->uRax     = pCtx->rax;
+
+    /*
      * Read the guest VMCB state.
      */
@@ -336,26 +352,7 @@
 
         /*
-         * Save the host state.
-         */
-        PSVMHOSTSTATE pHostState = &pCtx->hwvirt.svm.HostState;
-        pHostState->es         = pCtx->es;
-        pHostState->cs         = pCtx->cs;
-        pHostState->ss         = pCtx->ss;
-        pHostState->ds         = pCtx->ds;
-        pHostState->gdtr       = pCtx->gdtr;
-        pHostState->idtr       = pCtx->idtr;
-        pHostState->uEferMsr   = pCtx->msrEFER;
-        pHostState->uCr0       = pCtx->cr0;
-        pHostState->uCr3       = pCtx->cr3;
-        pHostState->uCr4       = pCtx->cr4;
-        pHostState->rflags     = pCtx->rflags;
-        pHostState->uRip       = pCtx->rip + cbInstr;
-        pHostState->uRsp       = pCtx->rsp;
-        pHostState->uRax       = pCtx->rax;
-
-        /*
          * Validate guest-state and controls.
          */
-        /* VMRUN must always be iHMSntercepted. */
+        /* VMRUN must always be intercepted. */
         if (!CPUMIsGuestSvmCtrlInterceptSet(pCtx, SVM_CTRL_INTERCEPT_VMRUN))
         {
@@ -552,5 +549,5 @@
         if (pVmcbCtrl->u64IntShadow & SVM_INTERRUPT_SHADOW_ACTIVE)
         {
-            LogFlow(("iemSvmVmrun: setting inerrupt shadow. inhibit PC=%#RX64\n", pVmcbNstGst->u64RIP));
+            LogFlow(("iemSvmVmrun: setting interrupt shadow. inhibit PC=%#RX64\n", pVmcbNstGst->u64RIP));
             /** @todo will this cause trouble if the nested-guest is 64-bit but the guest is 32-bit? */
             EMSetInhibitInterruptsPC(pVCpu, pVmcbNstGst->u64RIP);
@@ -560,5 +557,5 @@
          * TLB flush control.
          * Currently disabled since it's redundant as we unconditionally flush the TLB
-         * in iemSvmHandleWorldSwitch() below.
+         * in iemSvmWorldSwitch() below.
          */
 #if 0
@@ -571,7 +568,4 @@
 
         /** @todo @bugref{7243}: SVM TSC offset, see tmCpuTickGetInternal. */
-
-        uint64_t const uOldEfer = pCtx->msrEFER;
-        uint64_t const uOldCr0  = pCtx->cr0;
 
         /*
@@ -609,12 +603,7 @@
 
         /*
-         * Clear global interrupt flags to allow interrupts in the guest.
-         */
-        pCtx->hwvirt.svm.fGif = 1;
-
-        /*
-         * Inform PGM and others of the world-switch.
-         */
-        VBOXSTRICTRC rcStrict = iemSvmHandleWorldSwitch(pVCpu, uOldEfer, uOldCr0);
+         * Update PGM, IEM and others of a world-switch.
+         */
+        VBOXSTRICTRC rcStrict = iemSvmWorldSwitch(pVCpu, pCtx);
         if (rcStrict == VINF_SUCCESS)
         { /* likely */ }
@@ -623,7 +612,12 @@
         else
         {
-            LogFlow(("iemSvmVmrun: iemSvmHandleWorldSwitch unexpected failure. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
+            LogFlow(("iemSvmVmrun: iemSvmWorldSwitch unexpected failure. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
             return rcStrict;
         }
+
+        /*
+         * Clear global interrupt flags to allow interrupts in the guest.
+         */
+        pCtx->hwvirt.svm.fGif = 1;
 
         /*
@@ -1128,5 +1122,5 @@
     {
         Assert(!CPUMIsGuestInSvmNestedHwVirtMode(pCtx));
-        rcStrict = iemInitiateCpuShutdown(pVCpu);
+        rcStrict = VINF_EM_TRIPLE_FAULT;
     }
     return rcStrict;
