Index: /trunk/src/VBox/VMM/VMMAll/HMSVMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/HMSVMAll.cpp	(revision 73139)
+++ /trunk/src/VBox/VMM/VMMAll/HMSVMAll.cpp	(revision 73140)
@@ -164,11 +164,10 @@
      * However, with nested-guests, the state -can- change on trips to ring-3 for we might
      * try to inject a nested-guest physical interrupt and cause a SVM_EXIT_INTR #VMEXIT for
-     * the nested-guest from ring-3. Hence we signal the required CPU state change here.
+     * the nested-guest from ring-3. Import the complete state here as we will be swapping
+     * to the guest VMCB after the #VMEXIT.
      */
-    /** @todo Figure out why using HM_CHANGED_SVM_VMEXIT_MASK instead of
-     *        HM_CHANGED_ALL_GUEST breaks nested guests (XP Pro, DSL etc.), see also
-     *        hmR0SvmHandleExitNested(). */
-    AssertMsg(!(pVCpu->cpum.GstCtx.fExtrn & IEM_CPUMCTX_EXTRN_SVM_VMEXIT_MASK),
-              ("fExtrn=%#RX64 fExtrnMbz=%#RX64\n", pVCpu->cpum.GstCtx.fExtrn, IEM_CPUMCTX_EXTRN_SVM_VMEXIT_MASK));
+    CPUMImportGuestStateOnDemand(pVCpu, CPUMCTX_EXTRN_ALL);
+    AssertMsg(!(pVCpu->cpum.GstCtx.fExtrn & CPUMCTX_EXTRN_ALL),
+              ("fExtrn=%#RX64 fExtrnMbz=%#RX64\n", pVCpu->cpum.GstCtx.fExtrn, CPUMCTX_EXTRN_ALL));
     ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_ALL_GUEST);
 }
Index: /trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp	(revision 73139)
+++ /trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp	(revision 73140)
@@ -158,5 +158,5 @@
                  &&   CPUMIsGuestSvmCtrlInterceptSet((a_pVCpu), &(a_pVCpu)->cpum.GstCtx, SVM_CTRL_INTERCEPT_SHUTDOWN)) \
         { \
-            HMSVM_CPUMCTX_IMPORT_STATE((a_pVCpu), IEM_CPUMCTX_EXTRN_SVM_VMEXIT_MASK); \
+            HMSVM_CPUMCTX_IMPORT_STATE((a_pVCpu), HMSVM_CPUMCTX_EXTRN_ALL); \
             return VBOXSTRICTRC_TODO(IEMExecSvmVmexit((a_pVCpu), SVM_EXIT_SHUTDOWN, 0, 0)); \
         } \
@@ -3265,6 +3265,7 @@
     pVCpu->hm.s.rcLastExitToR3 = rcExit;
 
-    /* On our way back from ring-3 reload the guest state if there is a possibility of it being changed. */
-    if (rcExit != VINF_EM_RAW_INTERRUPT)
+    /* On our way back from ring-3, reload the guest-CPU state if it may change while in ring-3. */
+    if (   rcExit != VINF_EM_RAW_INTERRUPT
+        || CPUMIsGuestInSvmNestedHwVirtMode(&pVCpu->cpum.GstCtx))
     {
         Assert(!(pVCpu->cpum.GstCtx.fExtrn & HMSVM_CPUMCTX_EXTRN_ALL));
@@ -3755,5 +3756,5 @@
             {
                 Log4(("Intercepting NMI -> #VMEXIT\n"));
-                HMSVM_CPUMCTX_IMPORT_STATE(pVCpu, IEM_CPUMCTX_EXTRN_SVM_VMEXIT_MASK);
+                HMSVM_CPUMCTX_IMPORT_STATE(pVCpu, HMSVM_CPUMCTX_EXTRN_ALL);
                 return IEMExecSvmVmexit(pVCpu, SVM_EXIT_NMI, 0, 0);
             }
@@ -3796,5 +3797,5 @@
             {
                 Log4(("Intercepting INTR -> #VMEXIT\n"));
-                HMSVM_CPUMCTX_IMPORT_STATE(pVCpu, IEM_CPUMCTX_EXTRN_SVM_VMEXIT_MASK);
+                HMSVM_CPUMCTX_IMPORT_STATE(pVCpu, HMSVM_CPUMCTX_EXTRN_ALL);
                 return IEMExecSvmVmexit(pVCpu, SVM_EXIT_INTR, 0, 0);
             }
@@ -5173,7 +5174,9 @@
     Assert(pSvmTransient->u64ExitCode <= SVM_EXIT_MAX);
 
-    /** @todo Figure out why using IEM_CPUMCTX_EXTRN_SVM_VMEXIT_MASK instead of
-     *        HMSVM_CPUMCTX_EXTRN_ALL breaks nested guests (XP Pro, DSL etc.), see
-     *        also HMSvmNstGstVmExitNotify(). */
+    /*
+     * We import the complete state here because we use separate VMCBs for the guest and the
+     * nested-guest, and the guest's VMCB is used after the #VMEXIT. We can only save/restore
+     * the #VMEXIT specific state if we used the same VMCB for both guest and nested-guest.
+     */
 #define NST_GST_VMEXIT_CALL_RET(a_pVCpu, a_uExitCode, a_uExitInfo1, a_uExitInfo2) \
     do { \
@@ -5399,6 +5402,9 @@
              * get an SMI #VMEXIT here so simply ignore rather than causing a corresponding
              * nested-guest #VMEXIT.
+             *
+             * We shall import the complete state here as we may cause #VMEXITs from ring-3
+             * while trying to inject interrupts, see comment at the top of this function.
              */
-            HMSVM_CPUMCTX_IMPORT_STATE(pVCpu, IEM_CPUMCTX_EXTRN_SVM_VMEXIT_MASK);
+            HMSVM_CPUMCTX_IMPORT_STATE(pVCpu, CPUMCTX_EXTRN_ALL);
             return hmR0SvmExitIntr(pVCpu, pSvmTransient);
         }
