Index: trunk/src/VBox/VMM/VMMAll/HMAll.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/HMAll.cpp	(revision 71909)
+++ trunk/src/VBox/VMM/VMMAll/HMAll.cpp	(revision 71910)
@@ -543,5 +543,5 @@
 {
     pVCpu->hm.s.fGIMTrapXcptUD = true;
-    HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
+    HMCPU_CF_SET(pVCpu, HM_CHANGED_VMM_GUEST_XCPT_INTERCEPTS);
 }
 
@@ -555,5 +555,5 @@
 {
     pVCpu->hm.s.fGIMTrapXcptUD = false;
-    HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
+    HMCPU_CF_SET(pVCpu, HM_CHANGED_VMM_GUEST_XCPT_INTERCEPTS);
 }
 
Index: trunk/src/VBox/VMM/VMMAll/HMSVMAll.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/HMSVMAll.cpp	(revision 71909)
+++ trunk/src/VBox/VMM/VMMAll/HMSVMAll.cpp	(revision 71910)
@@ -103,5 +103,5 @@
                 int rc2 = APICSetTpr(pVCpu, u8Tpr);
                 AssertRC(rc2);
-                HMCPU_CF_SET(pVCpu, HM_CHANGED_SVM_GUEST_APIC_STATE);
+                HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_APIC_STATE);
 
                 pCtx->rip += pPatch->cbOp;
Index: trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp	(revision 71909)
+++ trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp	(revision 71910)
@@ -1704,5 +1704,5 @@
  * @param   pVCpu       The cross context virtual CPU structure.
  * @param   pVmcb       Pointer to the VM control block.
- * @param   pCtx        Pointer to the guest-CPU context.
+ * @param   pCtx        Pointer to the guest-CPU or nested-guest-CPU context.
  *
  * @remarks No-long-jump zone!!!
@@ -1818,5 +1818,7 @@
      * While guests can modify and see the modified values throug the shadow values,
      * we shall not honor any guest modifications of this MSR to ensure caching is always
-     * enabled similar to how we always run with CR0.CD and NW bits cleared.
+     * enabled similar to how we always run with CR0.CD and NW bits cleared,
+     *
+     * For nested-guests this needs to always be set as well, see @bugref{7243#c109}.
      */
     pVmcb->guest.u64PAT = MSR_IA32_CR_PAT_INIT_VAL;
@@ -1991,12 +1993,49 @@
 static void hmR0SvmLoadGuestApicStateNested(PVMCPU pVCpu, PSVMVMCB pVmcbNstGst)
 {
-    if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_SVM_GUEST_APIC_STATE))
-    {
-        /* Always enable V_INTR_MASKING as we do not want to allow access to the physical APIC TPR. */
-        pVmcbNstGst->ctrl.IntCtrl.n.u1VIntrMasking = 1;
+    if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_GUEST_APIC_STATE))
+    {
+        Assert(pVmcbNstGst->ctrl.IntCtrl.n.u1VIntrMasking == 1);
         pVCpu->hm.s.svm.fSyncVTpr = false;
-        pVmcbNstGst->ctrl.u32VmcbCleanBits &= ~HMSVM_VMCB_CLEAN_TPR;
-
-        HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_SVM_GUEST_APIC_STATE);
+        HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_GUEST_APIC_STATE);
+    }
+}
+
+
+/**
+ * Loads the nested-guest hardware virtualization state.
+ *
+ * @param   pVCpu         The cross context virtual CPU structure.
+ * @param   pVmcbNstGst   Pointer to the nested-guest VM control block.
+ * @param   pCtx          Pointer to the guest-CPU or nested-guest-CPU context.
+ */
+static void hmR0SvmLoadGuestHwvirtStateNested(PVMCPU pVCpu, PSVMVMCB pVmcbNstGst, PCPUMCTX pCtx)
+{
+    if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_GUEST_HWVIRT))
+    {
+        /*
+         * Ensure the nested-guest pause-filter counters don't exceed the outer guest values esp.
+         * since SVM doesn't have a preemption timer.
+         *
+         * We do this here rather than in hmR0SvmVmRunSetupVmcb() as we may have been executing the
+         * nested-guest in IEM incl. PAUSE instructions which would update the pause-filter counters
+         * and may continue execution in SVM R0 without a nested-guest #VMEXIT in between.
+         */
+        PVM            pVM = pVCpu->CTX_SUFF(pVM);
+        PSVMVMCBCTRL   pVmcbNstGstCtrl = &pVmcbNstGst->ctrl;
+        uint16_t const uGuestPauseFilterCount     = pVM->hm.s.svm.cPauseFilter;
+        uint16_t const uGuestPauseFilterThreshold = pVM->hm.s.svm.cPauseFilterThresholdTicks;
+        if (HMIsGuestSvmCtrlInterceptSet(pVCpu, pCtx, SVM_CTRL_INTERCEPT_PAUSE))
+        {
+            pVmcbNstGstCtrl->u16PauseFilterCount     = RT_MIN(pCtx->hwvirt.svm.cPauseFilter, uGuestPauseFilterCount);
+            pVmcbNstGstCtrl->u16PauseFilterThreshold = RT_MIN(pCtx->hwvirt.svm.cPauseFilterThreshold, uGuestPauseFilterThreshold);
+            pVmcbNstGstCtrl->u32VmcbCleanBits &= ~HMSVM_VMCB_CLEAN_INTERCEPTS;
+        }
+        else
+        {
+            pVmcbNstGstCtrl->u16PauseFilterCount     = uGuestPauseFilterCount;
+            pVmcbNstGstCtrl->u16PauseFilterThreshold = uGuestPauseFilterThreshold;
+        }
+
+        HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_GUEST_HWVIRT);
     }
 }
@@ -2013,5 +2052,5 @@
 static int hmR0SvmLoadGuestApicState(PVMCPU pVCpu, PSVMVMCB pVmcb, PCPUMCTX pCtx)
 {
-    if (!HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_SVM_GUEST_APIC_STATE))
+    if (!HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_GUEST_APIC_STATE))
         return VINF_SUCCESS;
 
@@ -2065,5 +2104,5 @@
     }
 
-    HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_SVM_GUEST_APIC_STATE);
+    HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_GUEST_APIC_STATE);
     return rc;
 }
@@ -2082,5 +2121,5 @@
     /* If we modify intercepts from here, please check & adjust hmR0SvmLoadGuestXcptInterceptsNested()
        if required. */
-    if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS))
+    if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_VMM_GUEST_XCPT_INTERCEPTS))
     {
         /* Trap #UD for GIM provider (e.g. for hypercalls). */
@@ -2097,5 +2136,5 @@
 
         /* The remaining intercepts are handled elsewhere, e.g. in hmR0SvmLoadSharedCR0(). */
-        HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
+        HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_VMM_GUEST_XCPT_INTERCEPTS);
     }
 }
@@ -2104,9 +2143,10 @@
 #ifdef VBOX_WITH_NESTED_HWVIRT
 /**
- * Loads the intercepts required for nested-guest execution in the VMCB.
+ * Merges guest and nested-guest intercepts for executing the nested-guest using
+ * hardware-assisted SVM.
  *
  * This merges the guest and nested-guest intercepts in a way that if the outer
- * guest intercepts an exception we need to intercept it in the nested-guest as
- * well and handle it accordingly.
+ * guest intercept is set we need to intercept it in the nested-guest as
+ * well.
  *
  * @param   pVCpu           The cross context virtual CPU structure.
@@ -2114,110 +2154,67 @@
  * @param   pCtx            Pointer to the guest-CPU context.
  */
-static void hmR0SvmLoadGuestInterceptsNested(PVMCPU pVCpu, PSVMVMCB pVmcbNstGst, PCPUMCTX pCtx)
-{
-    if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS))
-    {
-        PVM          pVM             = pVCpu->CTX_SUFF(pVM);
-        PCSVMVMCB    pVmcb           = pVCpu->hm.s.svm.pVmcb;
-        PSVMVMCBCTRL pVmcbNstGstCtrl = &pVmcbNstGst->ctrl;
-
-        /* Merge the guest's CR intercepts into the nested-guest VMCB. */
-        pVmcbNstGstCtrl->u16InterceptRdCRx |= pVmcb->ctrl.u16InterceptRdCRx;
-        pVmcbNstGstCtrl->u16InterceptWrCRx |= pVmcb->ctrl.u16InterceptWrCRx;
-
-        /* Always intercept CR4 writes for tracking PGM mode changes. */
-        pVmcbNstGstCtrl->u16InterceptWrCRx |= RT_BIT(4);
-
-        /* Without nested paging, intercept CR3 reads and writes as we load shadow page tables. */
-        if (!pVM->hm.s.fNestedPaging)
-        {
-            pVmcbNstGstCtrl->u16InterceptRdCRx |= RT_BIT(3);
-            pVmcbNstGstCtrl->u16InterceptWrCRx |= RT_BIT(3);
-        }
-
-        /** @todo Figure out debugging with nested-guests, till then just intercept
-         *        all DR[0-15] accesses. */
-        pVmcbNstGstCtrl->u16InterceptRdDRx |= 0xffff;
-        pVmcbNstGstCtrl->u16InterceptWrDRx |= 0xffff;
-
-        /*
-         * Merge the guest's exception intercepts into the nested-guest VMCB.
-         *
-         * - \#UD: Exclude these as the outer guest's GIM hypercalls are not applicable
-         * while executing the nested-guest.
-         *
-         * - \#BP: Exclude breakpoints set by the VM debugger for the outer guest. This can
-         * be tweaked later depending on how we wish to implement breakpoints.
-         *
-         * Warning!! This ASSUMES we only intercept \#UD for hypercall purposes and \#BP
-         * for VM debugger breakpoints, see hmR0SvmLoadGuestXcptIntercepts.
-         */
+static void hmR0SvmMergeVmcbCtrlsNested(PVMCPU pVCpu, PSVMVMCB pVmcbNstGst, PCPUMCTX pCtx)
+{
+    PVM          pVM             = pVCpu->CTX_SUFF(pVM);
+    PCSVMVMCB    pVmcb           = pVCpu->hm.s.svm.pVmcb;
+    PSVMVMCBCTRL pVmcbNstGstCtrl = &pVmcbNstGst->ctrl;
+
+    /* Merge the guest's CR intercepts into the nested-guest VMCB. */
+    pVmcbNstGstCtrl->u16InterceptRdCRx |= pVmcb->ctrl.u16InterceptRdCRx;
+    pVmcbNstGstCtrl->u16InterceptWrCRx |= pVmcb->ctrl.u16InterceptWrCRx;
+
+    /* Always intercept CR4 writes for tracking PGM mode changes. */
+    pVmcbNstGstCtrl->u16InterceptWrCRx |= RT_BIT(4);
+
+    /* Without nested paging, intercept CR3 reads and writes as we load shadow page tables. */
+    if (!pVM->hm.s.fNestedPaging)
+    {
+        pVmcbNstGstCtrl->u16InterceptRdCRx |= RT_BIT(3);
+        pVmcbNstGstCtrl->u16InterceptWrCRx |= RT_BIT(3);
+    }
+
+    /** @todo Figure out debugging with nested-guests, till then just intercept
+     *        all DR[0-15] accesses. */
+    pVmcbNstGstCtrl->u16InterceptRdDRx |= 0xffff;
+    pVmcbNstGstCtrl->u16InterceptWrDRx |= 0xffff;
+
+    /*
+     * Merge the guest's exception intercepts into the nested-guest VMCB.
+     *
+     * - \#UD: Exclude these as the outer guest's GIM hypercalls are not applicable
+     * while executing the nested-guest.
+     *
+     * - \#BP: Exclude breakpoints set by the VM debugger for the outer guest. This can
+     * be tweaked later depending on how we wish to implement breakpoints.
+     *
+     * Warning!! This ASSUMES we only intercept \#UD for hypercall purposes and \#BP
+     * for VM debugger breakpoints, see hmR0SvmLoadGuestXcptIntercepts.
+     */
 #ifndef HMSVM_ALWAYS_TRAP_ALL_XCPTS
-        pVmcbNstGstCtrl->u32InterceptXcpt  |= (pVmcb->ctrl.u32InterceptXcpt & ~(  RT_BIT(X86_XCPT_UD)
-                                                                                 | RT_BIT(X86_XCPT_BP)));
+    pVmcbNstGstCtrl->u32InterceptXcpt  |= (pVmcb->ctrl.u32InterceptXcpt & ~(  RT_BIT(X86_XCPT_UD)
+                                                                            | RT_BIT(X86_XCPT_BP)));
 #else
-        pVmcbNstGstCtrl->u32InterceptXcpt  |= pVmcb->ctrl.u32InterceptXcpt;
-#endif
-
-        /*
-         * Adjust intercepts while executing the nested-guest that differ from the
-         * outer guest intercepts.
-         *
-         * - VINTR: Exclude the outer guest intercept as we don't need to cause VINTR #VMEXITs
-         *   that belong to the nested-guest to the outer guest.
-         *
-         * - VMMCALL: Exclude the outer guest intercept as when it's also not intercepted by
-         *   the nested-guest, the physical CPU raises a \#UD exception as expected.
-         */
-        pVmcbNstGstCtrl->u64InterceptCtrl  |= (pVmcb->ctrl.u64InterceptCtrl & ~(  SVM_CTRL_INTERCEPT_VINTR
-                                                                                | SVM_CTRL_INTERCEPT_VMMCALL))
-                                           |  HMSVM_MANDATORY_GUEST_CTRL_INTERCEPTS;
-
-        Assert(   (pVmcbNstGstCtrl->u64InterceptCtrl & HMSVM_MANDATORY_GUEST_CTRL_INTERCEPTS)
-               == HMSVM_MANDATORY_GUEST_CTRL_INTERCEPTS);
-
-        /*
-         * Ensure the nested-guest pause-filter counters don't exceed the outer guest values esp.
-         * since SVM doesn't have a preemption timer.
-         *
-         * We do this here rather than in hmR0SvmVmRunSetupVmcb() as we may have been executing the
-         * nested-guest in IEM incl. PAUSE instructions which would update the pause-filter counters.
-         */
-        if (HMIsGuestSvmCtrlInterceptSet(pVCpu, pCtx, SVM_CTRL_INTERCEPT_PAUSE))
-        {
-            pVmcbNstGstCtrl->u16PauseFilterCount     = RT_MIN(pCtx->hwvirt.svm.cPauseFilter, pVmcb->ctrl.u16PauseFilterCount);
-            pVmcbNstGstCtrl->u16PauseFilterThreshold = RT_MIN(pCtx->hwvirt.svm.cPauseFilterThreshold,
-                                                              pVmcb->ctrl.u16PauseFilterThreshold);
-        }
-        else
-        {
-            pVmcbNstGstCtrl->u16PauseFilterCount     = pVmcb->ctrl.u16PauseFilterCount;
-            pVmcbNstGstCtrl->u16PauseFilterThreshold = pVmcb->ctrl.u16PauseFilterThreshold;
-        }
-
-        /*
-         * If we don't expose Virtualized-VMSAVE/VMLOAD feature to the outer guest, we
-         * need to intercept VMSAVE/VMLOAD instructions executed by the nested-guest.
-         */
-        if (!pVCpu->CTX_SUFF(pVM)->cpum.ro.GuestFeatures.fSvmVirtVmsaveVmload)
-        {
-            pVmcbNstGstCtrl->u64InterceptCtrl |= SVM_CTRL_INTERCEPT_VMSAVE
-                                              |  SVM_CTRL_INTERCEPT_VMLOAD;
-        }
-
-        /*
-         * If we don't expose Virtual GIF feature to the outer guest, we need to intercept
-         * CLGI/STGI instructions executed by the nested-guest.
-         */
-        if (!pVCpu->CTX_SUFF(pVM)->cpum.ro.GuestFeatures.fSvmVGif)
-        {
-            pVmcbNstGstCtrl->u64InterceptCtrl |= SVM_CTRL_INTERCEPT_CLGI
-                                              |  SVM_CTRL_INTERCEPT_STGI;
-        }
-
-        /* Finally, update the VMCB clean bits. */
-        pVmcbNstGstCtrl->u32VmcbCleanBits &= ~HMSVM_VMCB_CLEAN_INTERCEPTS;
-        HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
-    }
+    pVmcbNstGstCtrl->u32InterceptXcpt  |= pVmcb->ctrl.u32InterceptXcpt;
+#endif
+
+    /*
+     * Adjust intercepts while executing the nested-guest that differ from the
+     * outer guest intercepts.
+     *
+     * - VINTR: Exclude the outer guest intercept as we don't need to cause VINTR #VMEXITs
+     *   that belong to the nested-guest to the outer guest.
+     *
+     * - VMMCALL: Exclude the outer guest intercept as when it's also not intercepted by
+     *   the nested-guest, the physical CPU raises a \#UD exception as expected.
+     */
+    pVmcbNstGstCtrl->u64InterceptCtrl  |= (pVmcb->ctrl.u64InterceptCtrl & ~(  SVM_CTRL_INTERCEPT_VINTR
+                                                                            | SVM_CTRL_INTERCEPT_VMMCALL))
+                                       |  HMSVM_MANDATORY_GUEST_CTRL_INTERCEPTS;
+
+    Assert(   (pVmcbNstGstCtrl->u64InterceptCtrl & HMSVM_MANDATORY_GUEST_CTRL_INTERCEPTS)
+           == HMSVM_MANDATORY_GUEST_CTRL_INTERCEPTS);
+
+    /* Finally, update the VMCB clean bits. */
+    pVmcbNstGstCtrl->u32VmcbCleanBits &= ~HMSVM_VMCB_CLEAN_INTERCEPTS;
 }
 #endif
@@ -2426,5 +2423,6 @@
                           | HM_CHANGED_GUEST_SYSENTER_EIP_MSR
                           | HM_CHANGED_GUEST_SYSENTER_ESP_MSR
-                          | HM_CHANGED_GUEST_LAZY_MSRS            /* Unused. */
+                          | HM_CHANGED_GUEST_HWVIRT               /* Unused. */
+                          | HM_CHANGED_VMM_GUEST_LAZY_MSRS
                           | HM_CHANGED_SVM_RESERVED1              /* Reserved. */
                           | HM_CHANGED_SVM_RESERVED2
@@ -2528,4 +2526,8 @@
  * Sets up the nested-guest VMCB for execution using hardware-assisted SVM.
  *
+ * This is done the first time we enter nested-guest execution using SVM R0
+ * until the nested-guest \#VMEXIT (not to be confused with physical CPU
+ * \#VMEXITs which may or may not cause the nested-guest \#VMEXIT).
+ *
  * @param   pVCpu           The cross context virtual CPU structure.
  * @param   pCtx            Pointer to the guest-CPU context.
@@ -2556,13 +2558,33 @@
         pVmcbNstGstCtrl->NestedPagingCtrl.n.u1NestedPaging = pVCpu->CTX_SUFF(pVM)->hm.s.fNestedPaging;
 
-        /* Override nested-guest PAT MSR, see @bugref{7243#c109}. */
-        PSVMVMCBSTATESAVE pVmcbNstGstState = &pVmcbNstGst->guest;
-        pVmcbNstGstState->u64PAT = MSR_IA32_CR_PAT_INIT_VAL;
+        /* Always enable V_INTR_MASKING as we do not want to allow access to the physical APIC TPR. */
+        pVmcbNstGstCtrl->IntCtrl.n.u1VIntrMasking = 1;
 
 #ifdef DEBUG_ramshankar
         /* For debugging purposes - copy the LBR info. from outer guest VMCB. */
         pVmcbNstGstCtrl->LbrVirt.n.u1LbrVirt = pVmcb->ctrl.LbrVirt.n.u1LbrVirt;
-        pVmcbNstGstState->u64DBGCTL = pVmcb->guest.u64DBGCTL;
-#endif
+#endif
+
+        /*
+         * If we don't expose Virtualized-VMSAVE/VMLOAD feature to the outer guest, we
+         * need to intercept VMSAVE/VMLOAD instructions executed by the nested-guest.
+         */
+        if (!pVCpu->CTX_SUFF(pVM)->cpum.ro.GuestFeatures.fSvmVirtVmsaveVmload)
+            pVmcbNstGstCtrl->u64InterceptCtrl |= SVM_CTRL_INTERCEPT_VMSAVE
+                                              |  SVM_CTRL_INTERCEPT_VMLOAD;
+
+        /*
+         * If we don't expose Virtual GIF feature to the outer guest, we need to intercept
+         * CLGI/STGI instructions executed by the nested-guest.
+         */
+        if (!pVCpu->CTX_SUFF(pVM)->cpum.ro.GuestFeatures.fSvmVGif)
+            pVmcbNstGstCtrl->u64InterceptCtrl |= SVM_CTRL_INTERCEPT_CLGI
+                                              |  SVM_CTRL_INTERCEPT_STGI;
+
+        /* Merge the guest and nested-guest intercepts. */
+        hmR0SvmMergeVmcbCtrlsNested(pVCpu, pVmcbNstGst, pCtx);
+
+        /* Update the VMCB clean bits. */
+        pVmcbNstGstCtrl->u32VmcbCleanBits &= ~HMSVM_VMCB_CLEAN_INTERCEPTS;
     }
     else
@@ -2587,8 +2609,5 @@
     STAM_PROFILE_ADV_START(&pVCpu->hm.s.StatLoadGuestState, x);
 
-    PSVMVMCB pVmcbNstGst = pCtx->hwvirt.svm.CTX_SUFF(pVmcb);
-    Assert(pVmcbNstGst);
-
-    hmR0SvmVmRunSetupVmcb(pVCpu, pCtx);
+    PSVMVMCB     pVmcbNstGst     = pCtx->hwvirt.svm.CTX_SUFF(pVmcb); Assert(pVmcbNstGst);
 
     int rc = hmR0SvmLoadGuestControlRegs(pVCpu, pVmcbNstGst, pCtx);
@@ -2604,4 +2623,5 @@
     hmR0SvmLoadGuestMsrs(pVCpu, pVmcbNstGst, pCtx);
     hmR0SvmLoadGuestApicStateNested(pVCpu, pVmcbNstGst);
+    hmR0SvmLoadGuestHwvirtStateNested(pVCpu, pVmcbNstGst, pCtx);
 
     pVmcbNstGst->guest.u64RIP    = pCtx->rip;
@@ -2613,6 +2633,4 @@
     Assert(pVmcbNstGst->ctrl.IntCtrl.n.u1VGifEnable == 0);        /* Nested VGIF not supported yet. */
 #endif
-
-    hmR0SvmLoadGuestInterceptsNested(pVCpu, pVmcbNstGst, pCtx);
 
     rc = hmR0SvmSetupVMRunHandler(pVCpu);
@@ -2626,5 +2644,6 @@
                           | HM_CHANGED_GUEST_SYSENTER_EIP_MSR
                           | HM_CHANGED_GUEST_SYSENTER_ESP_MSR
-                          | HM_CHANGED_GUEST_LAZY_MSRS            /* Unused. */
+                          | HM_CHANGED_VMM_GUEST_XCPT_INTERCEPTS  /* Unused. */
+                          | HM_CHANGED_VMM_GUEST_LAZY_MSRS
                           | HM_CHANGED_SVM_RESERVED1              /* Reserved. */
                           | HM_CHANGED_SVM_RESERVED2
@@ -2682,6 +2701,6 @@
     }
 
-    /* Unused on AMD-V. */
-    HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_GUEST_LAZY_MSRS);
+    /* Unused on AMD-V (no lazy MSRs). */
+    HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_VMM_GUEST_LAZY_MSRS);
 
     AssertMsg(!HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_HOST_GUEST_SHARED_STATE),
@@ -4132,4 +4151,9 @@
 
     /*
+     * Set up the nested-guest VMCB for execution using hardware-assisted SVM.
+     */
+    hmR0SvmVmRunSetupVmcb(pVCpu, pCtx);
+
+    /*
      * Load the nested-guest state.
      */
@@ -4657,5 +4681,5 @@
                 int rc = APICSetTpr(pVCpu, pMixedCtx->msrLSTAR & 0xff);
                 AssertRC(rc);
-                HMCPU_CF_SET(pVCpu, HM_CHANGED_SVM_GUEST_APIC_STATE);
+                HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_APIC_STATE);
             }
             else if (pSvmTransient->u8GuestTpr != pVmcb->ctrl.IntCtrl.n.u8VTPR)
@@ -4663,5 +4687,5 @@
                 int rc = APICSetTpr(pVCpu, pVmcb->ctrl.IntCtrl.n.u8VTPR << 4);
                 AssertRC(rc);
-                HMCPU_CF_SET(pVCpu, HM_CHANGED_SVM_GUEST_APIC_STATE);
+                HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_APIC_STATE);
             }
         }
@@ -6602,5 +6626,5 @@
 
             case 8:     /* CR8 (TPR). */
-                HMCPU_CF_SET(pVCpu, HM_CHANGED_SVM_GUEST_APIC_STATE);
+                HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_APIC_STATE);
                 break;
 
@@ -6643,5 +6667,5 @@
                 int rc2 = APICSetTpr(pVCpu, pCtx->eax & 0xff);
                 AssertRC(rc2);
-                HMCPU_CF_SET(pVCpu, HM_CHANGED_SVM_GUEST_APIC_STATE);
+                HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_APIC_STATE);
             }
             rc = VINF_SUCCESS;
@@ -6685,5 +6709,5 @@
                  * EMInterpretWrmsr() changes it.
                  */
-                HMCPU_CF_SET(pVCpu, HM_CHANGED_SVM_GUEST_APIC_STATE);
+                HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_APIC_STATE);
             }
             else
@@ -7145,5 +7169,5 @@
         {
             /* Successfully handled MMIO operation. */
-            HMCPU_CF_SET(pVCpu, HM_CHANGED_SVM_GUEST_APIC_STATE);
+            HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_APIC_STATE);
             rc = VINF_SUCCESS;
         }
Index: trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 71909)
+++ trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 71910)
@@ -3467,5 +3467,5 @@
 
     int rc = VINF_SUCCESS;
-    if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_VMX_GUEST_APIC_STATE))
+    if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_GUEST_APIC_STATE))
     {
         if (   PDMHasApic(pVCpu->CTX_SUFF(pVM))
@@ -3505,5 +3505,5 @@
             }
         }
-        HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_VMX_GUEST_APIC_STATE);
+        HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_GUEST_APIC_STATE);
     }
 
@@ -3600,5 +3600,5 @@
     NOREF(pMixedCtx);
     int rc = VINF_SUCCESS;
-    if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS))
+    if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_VMM_GUEST_XCPT_INTERCEPTS))
     {
         /* The remaining exception intercepts are handled elsewhere, e.g. in hmR0VmxLoadSharedCR0(). */
@@ -3616,5 +3616,5 @@
         AssertRCReturn(rc, rc);
 
-        HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
+        HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_VMM_GUEST_XCPT_INTERCEPTS);
         Log4(("Load[%RU32]: VMX_VMCS32_CTRL_EXCEPTION_BITMAP=%#RX64 fContextUseFlags=%#RX32\n", pVCpu->idCpu,
               pVCpu->hm.s.vmx.u32XcptBitmap, HMCPU_CF_VALUE(pVCpu)));
@@ -3847,5 +3847,5 @@
             pVCpu->hm.s.vmx.u32XcptBitmap &= ~HMVMX_REAL_MODE_XCPT_MASK;
         }
-        HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
+        HMCPU_CF_SET(pVCpu, HM_CHANGED_VMM_GUEST_XCPT_INTERCEPTS);
 
         if (fInterceptNM)
@@ -6595,5 +6595,5 @@
     if (!HMVMXCPU_GST_IS_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_LAZY_MSRS))
     {
-        Assert(!HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_GUEST_LAZY_MSRS));
+        Assert(!HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_VMM_GUEST_LAZY_MSRS));
         hmR0VmxLazySaveGuestMsrs(pVCpu, pMixedCtx);
         HMVMXCPU_GST_SET_UPDATED(pVCpu, HMVMX_UPDATED_GUEST_LAZY_MSRS);
@@ -7141,15 +7141,19 @@
     /* Note! Since this is only applicable to VT-x, the implementation is placed
              in the VT-x part of the sources instead of the generic stuff. */
+    int rc;
     if (pVCpu->CTX_SUFF(pVM)->hm.s.vmx.fSupported)
-    {
-        int rc = hmR0VmxSaveGuestState(pVCpu, pMixedCtx);
-        /*
-         * For now, imply that the caller might change everything too. Do this after
-         * saving the guest state so as to not trigger assertions.
-         */
-        HMCPU_CF_SET(pVCpu, HM_CHANGED_ALL_GUEST);
-        return rc;
-    }
-    return VINF_SUCCESS;
+        rc = hmR0VmxSaveGuestState(pVCpu, pMixedCtx);
+    else
+        rc= VINF_SUCCESS;
+
+    /*
+     * For now, imply that the caller might change everything too. Do this after
+     * saving the guest state so as to not trigger assertions.
+     *
+     * This is required for AMD-V too as it too only selectively re-loads changed
+     * guest state back in to the VMCB.
+     */
+    HMCPU_CF_SET(pVCpu, HM_CHANGED_ALL_GUEST);
+    return rc;
 }
 
@@ -8739,5 +8743,6 @@
 
     /* Clear any unused and reserved bits. */
-    HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_GUEST_CR2);
+    HMCPU_CF_CLEAR(pVCpu,   HM_CHANGED_GUEST_CR2
+                          | HM_CHANGED_GUEST_HWVIRT);
 
     STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatLoadGuestState, x);
@@ -8781,12 +8786,12 @@
     }
 
-    if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_GUEST_LAZY_MSRS))
+    if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_VMM_GUEST_LAZY_MSRS))
     {
         hmR0VmxLazyLoadGuestMsrs(pVCpu, pCtx);
-        HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_GUEST_LAZY_MSRS);
+        HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_VMM_GUEST_LAZY_MSRS);
     }
 
     /* Loading CR0, debug state might have changed intercepts, update VMCS. */
-    if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS))
+    if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_VMM_GUEST_XCPT_INTERCEPTS))
     {
         Assert(pVCpu->hm.s.vmx.u32XcptBitmap & RT_BIT_32(X86_XCPT_AC));
@@ -8794,5 +8799,5 @@
         int rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_EXCEPTION_BITMAP, pVCpu->hm.s.vmx.u32XcptBitmap);
         AssertRC(rc);
-        HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_GUEST_XCPT_INTERCEPTS);
+        HMCPU_CF_CLEAR(pVCpu, HM_CHANGED_VMM_GUEST_XCPT_INTERCEPTS);
     }
 
@@ -9334,5 +9339,5 @@
                 rc = APICSetTpr(pVCpu, pVCpu->hm.s.vmx.pbVirtApic[XAPIC_OFF_TPR]);
                 AssertRC(rc);
-                HMCPU_CF_SET(pVCpu, HM_CHANGED_VMX_GUEST_APIC_STATE);
+                HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_APIC_STATE);
             }
 
@@ -12466,5 +12471,5 @@
              * EMInterpretWrmsr() changes it.
              */
-            HMCPU_CF_SET(pVCpu, HM_CHANGED_VMX_GUEST_APIC_STATE);
+            HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_APIC_STATE);
         }
         else if (pMixedCtx->ecx == MSR_IA32_TSC)        /* Windows 7 does this during bootup. See @bugref{6398}. */
@@ -12509,5 +12514,5 @@
                         HMCPU_CF_SET(pVCpu, HM_CHANGED_VMX_GUEST_AUTO_MSRS);
                     else if (hmR0VmxIsLazyGuestMsr(pVCpu, pMixedCtx->ecx))
-                        HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_LAZY_MSRS);
+                        HMCPU_CF_SET(pVCpu, HM_CHANGED_VMM_GUEST_LAZY_MSRS);
                     break;
                 }
@@ -12653,5 +12658,5 @@
                     Assert(!(pVCpu->hm.s.vmx.u32ProcCtls & VMX_VMCS_CTRL_PROC_EXEC_USE_TPR_SHADOW));
                     /* CR8 contains the APIC TPR. Was updated by IEMExecDecodedMovCRxWrite(). */
-                    HMCPU_CF_SET(pVCpu, HM_CHANGED_VMX_GUEST_APIC_STATE);
+                    HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_APIC_STATE);
                     break;
                 default:
@@ -13099,5 +13104,5 @@
                                     | HM_CHANGED_GUEST_RSP
                                     | HM_CHANGED_GUEST_RFLAGS
-                                    | HM_CHANGED_VMX_GUEST_APIC_STATE);
+                                    | HM_CHANGED_GUEST_APIC_STATE);
                 rcStrict2 = VINF_SUCCESS;
             }
@@ -13264,5 +13269,5 @@
                             | HM_CHANGED_GUEST_RSP
                             | HM_CHANGED_GUEST_RFLAGS
-                            | HM_CHANGED_VMX_GUEST_APIC_STATE);
+                            | HM_CHANGED_GUEST_APIC_STATE);
         return VINF_SUCCESS;
     }
@@ -13970,5 +13975,5 @@
                             | HM_CHANGED_GUEST_RSP
                             | HM_CHANGED_GUEST_RFLAGS
-                            | HM_CHANGED_VMX_GUEST_APIC_STATE);
+                            | HM_CHANGED_GUEST_APIC_STATE);
 #else
         /*
Index: trunk/src/VBox/VMM/include/HMInternal.h
===================================================================
--- trunk/src/VBox/VMM/include/HMInternal.h	(revision 71909)
+++ trunk/src/VBox/VMM/include/HMInternal.h	(revision 71910)
@@ -173,50 +173,52 @@
 #define HM_CHANGED_GUEST_SYSENTER_ESP_MSR        RT_BIT(15)
 #define HM_CHANGED_GUEST_EFER_MSR                RT_BIT(16)
-#define HM_CHANGED_GUEST_LAZY_MSRS               RT_BIT(17)     /* Shared */ /** @todo Move this to VT-x specific? */
-#define HM_CHANGED_GUEST_XCPT_INTERCEPTS         RT_BIT(18)
+#define HM_CHANGED_GUEST_APIC_STATE              RT_BIT(17)
+#define HM_CHANGED_GUEST_HWVIRT                  RT_BIT(18)
+/* Logically common VMM state. */
+#define HM_CHANGED_VMM_GUEST_XCPT_INTERCEPTS     RT_BIT(19)
+#define HM_CHANGED_VMM_GUEST_LAZY_MSRS           RT_BIT(20)
 /* VT-x specific state. */
-#define HM_CHANGED_VMX_GUEST_AUTO_MSRS           RT_BIT(19)
-#define HM_CHANGED_VMX_GUEST_ACTIVITY_STATE      RT_BIT(20)
-#define HM_CHANGED_VMX_GUEST_APIC_STATE          RT_BIT(21)
-#define HM_CHANGED_VMX_ENTRY_CTLS                RT_BIT(22)
-#define HM_CHANGED_VMX_EXIT_CTLS                 RT_BIT(23)
+#define HM_CHANGED_VMX_GUEST_AUTO_MSRS           RT_BIT(21)
+#define HM_CHANGED_VMX_GUEST_ACTIVITY_STATE      RT_BIT(22)
+#define HM_CHANGED_VMX_ENTRY_CTLS                RT_BIT(23)
+#define HM_CHANGED_VMX_EXIT_CTLS                 RT_BIT(24)
 /* AMD-V specific state. */
-#define HM_CHANGED_SVM_GUEST_APIC_STATE          RT_BIT(19)
-#define HM_CHANGED_SVM_RESERVED1                 RT_BIT(20)
-#define HM_CHANGED_SVM_RESERVED2                 RT_BIT(21)
-#define HM_CHANGED_SVM_RESERVED3                 RT_BIT(22)
-#define HM_CHANGED_SVM_RESERVED4                 RT_BIT(23)
-
-#define HM_CHANGED_ALL_GUEST                     (  HM_CHANGED_GUEST_CR0                \
-                                                  | HM_CHANGED_GUEST_CR3                \
-                                                  | HM_CHANGED_GUEST_CR4                \
-                                                  | HM_CHANGED_GUEST_GDTR               \
-                                                  | HM_CHANGED_GUEST_IDTR               \
-                                                  | HM_CHANGED_GUEST_LDTR               \
-                                                  | HM_CHANGED_GUEST_TR                 \
-                                                  | HM_CHANGED_GUEST_SEGMENT_REGS       \
-                                                  | HM_CHANGED_GUEST_DEBUG              \
-                                                  | HM_CHANGED_GUEST_RIP                \
-                                                  | HM_CHANGED_GUEST_RSP                \
-                                                  | HM_CHANGED_GUEST_RFLAGS             \
-                                                  | HM_CHANGED_GUEST_CR2                \
-                                                  | HM_CHANGED_GUEST_SYSENTER_CS_MSR    \
-                                                  | HM_CHANGED_GUEST_SYSENTER_EIP_MSR   \
-                                                  | HM_CHANGED_GUEST_SYSENTER_ESP_MSR   \
-                                                  | HM_CHANGED_GUEST_EFER_MSR           \
-                                                  | HM_CHANGED_GUEST_LAZY_MSRS          \
-                                                  | HM_CHANGED_GUEST_XCPT_INTERCEPTS    \
-                                                  | HM_CHANGED_VMX_GUEST_AUTO_MSRS      \
-                                                  | HM_CHANGED_VMX_GUEST_ACTIVITY_STATE \
-                                                  | HM_CHANGED_VMX_GUEST_APIC_STATE     \
-                                                  | HM_CHANGED_VMX_ENTRY_CTLS           \
+#define HM_CHANGED_SVM_RESERVED1                 RT_BIT(21)
+#define HM_CHANGED_SVM_RESERVED2                 RT_BIT(22)
+#define HM_CHANGED_SVM_RESERVED3                 RT_BIT(23)
+#define HM_CHANGED_SVM_RESERVED4                 RT_BIT(24)
+
+#define HM_CHANGED_ALL_GUEST                     (  HM_CHANGED_GUEST_CR0                 \
+                                                  | HM_CHANGED_GUEST_CR3                 \
+                                                  | HM_CHANGED_GUEST_CR4                 \
+                                                  | HM_CHANGED_GUEST_GDTR                \
+                                                  | HM_CHANGED_GUEST_IDTR                \
+                                                  | HM_CHANGED_GUEST_LDTR                \
+                                                  | HM_CHANGED_GUEST_TR                  \
+                                                  | HM_CHANGED_GUEST_SEGMENT_REGS        \
+                                                  | HM_CHANGED_GUEST_DEBUG               \
+                                                  | HM_CHANGED_GUEST_RIP                 \
+                                                  | HM_CHANGED_GUEST_RSP                 \
+                                                  | HM_CHANGED_GUEST_RFLAGS              \
+                                                  | HM_CHANGED_GUEST_CR2                 \
+                                                  | HM_CHANGED_GUEST_SYSENTER_CS_MSR     \
+                                                  | HM_CHANGED_GUEST_SYSENTER_EIP_MSR    \
+                                                  | HM_CHANGED_GUEST_SYSENTER_ESP_MSR    \
+                                                  | HM_CHANGED_GUEST_EFER_MSR            \
+                                                  | HM_CHANGED_GUEST_APIC_STATE          \
+                                                  | HM_CHANGED_GUEST_HWVIRT              \
+                                                  | HM_CHANGED_VMM_GUEST_XCPT_INTERCEPTS \
+                                                  | HM_CHANGED_VMM_GUEST_LAZY_MSRS       \
+                                                  | HM_CHANGED_VMX_GUEST_AUTO_MSRS       \
+                                                  | HM_CHANGED_VMX_GUEST_ACTIVITY_STATE  \
+                                                  | HM_CHANGED_VMX_ENTRY_CTLS            \
                                                   | HM_CHANGED_VMX_EXIT_CTLS)
 
-#define HM_CHANGED_HOST_CONTEXT                  RT_BIT(24)
+#define HM_CHANGED_HOST_CONTEXT                  RT_BIT(25)
 
 /* Bits shared between host and guest. */
-#define HM_CHANGED_HOST_GUEST_SHARED_STATE       (  HM_CHANGED_GUEST_CR0                \
-                                                  | HM_CHANGED_GUEST_DEBUG              \
-                                                  | HM_CHANGED_GUEST_LAZY_MSRS)
+#define HM_CHANGED_HOST_GUEST_SHARED_STATE       (  HM_CHANGED_GUEST_CR0           \
+                                                  | HM_CHANGED_GUEST_DEBUG         \
+                                                  | HM_CHANGED_VMM_GUEST_LAZY_MSRS)
 /** @} */
 
