Index: /trunk/include/VBox/vmm/cpumctx.h
===================================================================
--- /trunk/include/VBox/vmm/cpumctx.h	(revision 79571)
+++ /trunk/include/VBox/vmm/cpumctx.h	(revision 79572)
@@ -601,13 +601,13 @@
                 uint32_t                uShadowVmcsR3Padding;
 #endif
-                /** 0x328 - Reserved - R0 ptr. */
-                R0PTRTYPE(void *)       pvRsvdR0;
-#if HC_ARCH_BITS == 32
-                uint32_t                uRsvdR0Padding0;
-#endif
-                /** 0x330 - Reserved - R3 ptr. */
-                R3PTRTYPE(void *)       pvRsvdR3;
-#if HC_ARCH_BITS == 32
-                uint32_t                uRsvdR3Padding0;
+                /** 0x328 - The virtual-APIC page - R0 ptr. */
+                R0PTRTYPE(void *)       pvVirtApicPageR0;
+#if HC_ARCH_BITS == 32
+                uint32_t                uVirtApicPageR0Padding;
+#endif
+                /** 0x330 - The virtual-APIC page - R3 ptr. */
+                R3PTRTYPE(void *)       pvVirtApicPageR3;
+#if HC_ARCH_BITS == 32
+                uint32_t                uVirtApicPageR3Padding;
 #endif
                 /** 0x338 - The VMREAD bitmap - R0 ptr. */
@@ -692,6 +692,9 @@
                 /** 0x3c2 - Whether virtual-NMI blocking is in effect. */
                 bool                    fVirtNmiBlocking;
-                /** 0x3c3 - Padding. */
-                uint8_t                 abPadding0[5];
+                /** 0x3c3 - Whether the virtual-APIC may have been modified in VMX non-root
+                 *  operation and we should write to it before VM-exit. */
+                bool                    fVirtApicPageDirty;
+                /** 0x3c4 - Padding. */
+                uint8_t                 abPadding0[4];
                 /** 0x3c8 - Guest VMX MSRs. */
                 VMXMSRS                 Msrs;
@@ -701,5 +704,5 @@
                 RTHCPHYS                HCPhysShadowVmcs;
                 /** 0x4b8 - Host physical address of the virtual-APIC page. */
-                RTHCPHYS                HCPhysRsvd0;
+                RTHCPHYS                HCPhysVirtApicPage;
                 /** 0x4c0 - Host physical address of the VMREAD bitmap. */
                 RTHCPHYS                HCPhysVmreadBitmap;
@@ -814,4 +817,6 @@
 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) vmx.pShadowVmcsR0,               0x318);
 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) vmx.pShadowVmcsR3,               0x320);
+AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) vmx.pvVirtApicPageR0,            0x328);
+AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) vmx.pvVirtApicPageR3,            0x330);
 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) vmx.pvVmreadBitmapR0,            0x338);
 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) vmx.pvVmreadBitmapR3,            0x340);
@@ -833,7 +838,9 @@
 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) vmx.offVirtApicWrite,            0x3c0);
 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) vmx.fVirtNmiBlocking,            0x3c2);
+AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) vmx.fVirtApicPageDirty,          0x3c3);
 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) vmx.Msrs,                        0x3c8);
 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) vmx.HCPhysVmcs,                  0x4a8);
 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) vmx.HCPhysShadowVmcs,            0x4b0);
+AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) vmx.HCPhysVirtApicPage,          0x4b8);
 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) vmx.HCPhysVmreadBitmap,          0x4c0);
 AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) vmx.HCPhysVmwriteBitmap,         0x4c8);
Index: /trunk/src/VBox/VMM/VMMAll/HMVMXAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/HMVMXAll.cpp	(revision 79571)
+++ /trunk/src/VBox/VMM/VMMAll/HMVMXAll.cpp	(revision 79572)
@@ -370,5 +370,6 @@
     VMXV_DIAG_DESC(kVmxVDiag_Vmexit_MsrStorePtrWritePhys      , "MsrStorePtrWritePhys"      ),
     VMXV_DIAG_DESC(kVmxVDiag_Vmexit_MsrStoreRing3             , "MsrStoreRing3"             ),
-    VMXV_DIAG_DESC(kVmxVDiag_Vmexit_MsrStoreRsvd              , "MsrStoreRsvd"              )
+    VMXV_DIAG_DESC(kVmxVDiag_Vmexit_MsrStoreRsvd              , "MsrStoreRsvd"              ),
+    VMXV_DIAG_DESC(kVmxVDiag_Vmexit_VirtApicPagePtrWritePhys  , "VirtApicPagePtrWritePhys"  )
     /* kVmxVDiag_End */
 };
@@ -925,4 +926,5 @@
     LogRel(("offVirtApicWrite           = %#RX16\n",    pCtx->hwvirt.vmx.offVirtApicWrite));
     LogRel(("fVirtNmiBlocking           = %RTbool\n",   pCtx->hwvirt.vmx.fVirtNmiBlocking));
+    LogRel(("fVirtApicPageDirty         = %RTbool\n",   pCtx->hwvirt.vmx.fVirtApicPageDirty));
     LogRel(("VMCS cache:\n"));
 
Index: /trunk/src/VBox/VMM/VMMR3/CPUM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/CPUM.cpp	(revision 79571)
+++ /trunk/src/VBox/VMM/VMMR3/CPUM.cpp	(revision 79572)
@@ -1140,4 +1140,9 @@
             pCtx->hwvirt.vmx.pShadowVmcsR3 = NULL;
         }
+        if (pCtx->hwvirt.vmx.pvVirtApicPageR3)
+        {
+            SUPR3ContFree(pCtx->hwvirt.vmx.pvVirtApicPageR3, VMX_V_VIRT_APIC_PAGES);
+            pCtx->hwvirt.vmx.pvVirtApicPageR3 = NULL;
+        }
         if (pCtx->hwvirt.vmx.pvVmreadBitmapR3)
         {
@@ -1231,4 +1236,19 @@
 
         /*
+         * Allocate the virtual-APIC page.
+         */
+        pCtx->hwvirt.vmx.pvVirtApicPageR3 = SUPR3ContAlloc(VMX_V_VIRT_APIC_PAGES,
+                                                           &pCtx->hwvirt.vmx.pvVirtApicPageR0,
+                                                           &pCtx->hwvirt.vmx.HCPhysVirtApicPage);
+        if (pCtx->hwvirt.vmx.pvVirtApicPageR3)
+        { /* likely */ }
+        else
+        {
+            LogRel(("CPUM%u: Failed to alloc %u pages for the nested-guest's virtual-APIC page\n", pVCpu->idCpu,
+                    VMX_V_VIRT_APIC_PAGES));
+            break;
+        }
+
+        /*
          * Allocate the VMREAD-bitmap.
          */
@@ -1340,4 +1360,5 @@
         memset(pCtx->hwvirt.vmx.CTX_SUFF(pVmcs),               0, VMX_V_VMCS_SIZE);
         memset(pCtx->hwvirt.vmx.CTX_SUFF(pShadowVmcs),         0, VMX_V_SHADOW_VMCS_SIZE);
+        memset(pCtx->hwvirt.vmx.CTX_SUFF(pvVirtApicPage),      0, VMX_V_VIRT_APIC_SIZE);
         memset(pCtx->hwvirt.vmx.CTX_SUFF(pvVmreadBitmap),      0, VMX_V_VMREAD_VMWRITE_BITMAP_SIZE);
         memset(pCtx->hwvirt.vmx.CTX_SUFF(pvVmwriteBitmap),     0, VMX_V_VMREAD_VMWRITE_BITMAP_SIZE);
@@ -2627,4 +2648,5 @@
             SSMR3PutU16(pSSM,      pGstCtx->hwvirt.vmx.offVirtApicWrite);
             SSMR3PutBool(pSSM,     pGstCtx->hwvirt.vmx.fVirtNmiBlocking);
+            SSMR3PutBool(pSSM,     pGstCtx->hwvirt.vmx.fVirtApicPageDirty);
             SSMR3PutU64(pSSM,      pGstCtx->hwvirt.vmx.Msrs.u64FeatCtrl);
             SSMR3PutU64(pSSM,      pGstCtx->hwvirt.vmx.Msrs.u64Basic);
@@ -2918,4 +2940,5 @@
                         SSMR3GetU16(pSSM,      &pGstCtx->hwvirt.vmx.offVirtApicWrite);
                         SSMR3GetBool(pSSM,     &pGstCtx->hwvirt.vmx.fVirtNmiBlocking);
+                        SSMR3GetBool(pSSM,     &pGstCtx->hwvirt.vmx.fVirtApicPageDirty);
                         SSMR3GetU64(pSSM,      &pGstCtx->hwvirt.vmx.Msrs.u64FeatCtrl);
                         SSMR3GetU64(pSSM,      &pGstCtx->hwvirt.vmx.Msrs.u64Basic);
@@ -4109,4 +4132,5 @@
         pHlp->pfnPrintf(pHlp, "  offVirtApicWrite           = %#RX16\n",    pCtx->hwvirt.vmx.offVirtApicWrite);
         pHlp->pfnPrintf(pHlp, "  fVirtNmiBlocking           = %RTbool\n",   pCtx->hwvirt.vmx.fVirtNmiBlocking);
+        pHlp->pfnPrintf(pHlp, "  fVirtApicPageDirty         = %RTbool\n",   pCtx->hwvirt.vmx.fVirtApicPageDirty);
         pHlp->pfnPrintf(pHlp, "  VMCS cache:\n");
         cpumR3InfoVmxVmcs(pHlp, pCtx->hwvirt.vmx.pVmcsR3, "  " /* pszPrefix */);
Index: /trunk/src/VBox/VMM/testcase/tstVMStruct.h
===================================================================
--- /trunk/src/VBox/VMM/testcase/tstVMStruct.h	(revision 79571)
+++ /trunk/src/VBox/VMM/testcase/tstVMStruct.h	(revision 79572)
@@ -159,4 +159,6 @@
     GEN_CHECK_OFF(CPUMCTX, hwvirt.vmx.pShadowVmcsR0);
     GEN_CHECK_OFF(CPUMCTX, hwvirt.vmx.pShadowVmcsR3);
+    GEN_CHECK_OFF(CPUMCTX, hwvirt.vmx.pvVirtApicPageR0);
+    GEN_CHECK_OFF(CPUMCTX, hwvirt.vmx.pvVirtApicPageR3);
     GEN_CHECK_OFF(CPUMCTX, hwvirt.vmx.pvVmreadBitmapR0);
     GEN_CHECK_OFF(CPUMCTX, hwvirt.vmx.pvVmreadBitmapR3);
@@ -178,4 +180,5 @@
     GEN_CHECK_OFF(CPUMCTX, hwvirt.vmx.offVirtApicWrite);
     GEN_CHECK_OFF(CPUMCTX, hwvirt.vmx.fVirtNmiBlocking);
+    GEN_CHECK_OFF(CPUMCTX, hwvirt.vmx.fVirtApicPageDirty);
     GEN_CHECK_OFF(CPUMCTX, hwvirt.vmx.Msrs);
     GEN_CHECK_OFF(CPUMCTX, hwvirt.vmx.HCPhysVmcs);
