Index: /trunk/src/VBox/VMM/PGMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/PGMInternal.h	(revision 17508)
+++ /trunk/src/VBox/VMM/PGMInternal.h	(revision 17509)
@@ -146,4 +146,10 @@
 #ifdef VBOX_STRICT
 # define VBOX_STRICT_PGM_HANDLER_VIRTUAL
+#endif
+
+#ifdef VBOX_WITH_NEW_PHYS_CODE
+/** @def VBOX_WITH_NEW_LAZY_PAGE_ALLOC
+ * Enables the experimental lazy page allocation code. */
+/*# define VBOX_WITH_NEW_LAZY_PAGE_ALLOC */
 #endif
 /** @} */
@@ -3077,4 +3083,5 @@
 void            pgmPoolClearAll(PVM pVM);
 int             pgmPoolSyncCR3(PVM pVM);
+int             pgmPoolTrackFlushGCPhys(PVM pVM, PPGMPAGE pPhysPage, bool *pfFlushTLBs);
 void            pgmPoolTrackFlushGCPhysPT(PVM pVM, PPGMPAGE pPhysPage, uint16_t iShw, uint16_t cRefs);
 void            pgmPoolTrackFlushGCPhysPTs(PVM pVM, PPGMPAGE pPhysPage, uint16_t iPhysExt);
Index: /trunk/src/VBox/VMM/PGMPhys.cpp
===================================================================
--- /trunk/src/VBox/VMM/PGMPhys.cpp	(revision 17508)
+++ /trunk/src/VBox/VMM/PGMPhys.cpp	(revision 17509)
@@ -1552,11 +1552,14 @@
                     return rc;
                 }
+                AssertMsg(rc == VINF_SUCCESS || rc == VINF_PGM_SYNC_CR3 /* returned */, ("%Rrc\n", rc));
             }
 
             void *pvDstPage;
             PPGMPAGEMAP pMapIgnored;
-            rc = pgmPhysPageMap(pVM, &pRomPage->Shadow, GCPhys & X86_PTE_PG_MASK, &pMapIgnored, &pvDstPage);
-            if (RT_SUCCESS(rc))
+            int rc2 = pgmPhysPageMap(pVM, &pRomPage->Shadow, GCPhys & X86_PTE_PG_MASK, &pMapIgnored, &pvDstPage);
+            if (RT_SUCCESS(rc2))
                 memcpy((uint8_t *)pvDstPage + (GCPhys & PAGE_OFFSET_MASK), pvBuf, cbBuf);
+            else
+                rc = rc2;
 
             pgmUnlock(pVM);
@@ -2665,4 +2668,6 @@
         if (RT_SUCCESS(rc))
         {
+            int rc2;
+
             /* Make sure what we return is writable. */
             if (fWritable && rc != VINF_PGM_PHYS_TLB_CATCH_WRITE)
@@ -2674,6 +2679,6 @@
                     case PGM_PAGE_STATE_SHARED:
                     case PGM_PAGE_STATE_WRITE_MONITORED:
-                        rc = pgmPhysPageMakeWritable(pVM, pPage, GCPhys & ~(RTGCPHYS)PAGE_OFFSET_MASK);
-                        AssertLogRelRCReturn(rc, rc);
+                        rc2 = pgmPhysPageMakeWritable(pVM, pPage, GCPhys & ~(RTGCPHYS)PAGE_OFFSET_MASK);
+                        AssertLogRelRCReturn(rc2, rc2);
                         break;
                 }
@@ -2681,6 +2686,6 @@
             /* Get a ring-3 mapping of the address. */
             PPGMPAGER3MAPTLBE pTlbe;
-            int rc = pgmPhysPageQueryTlbe(&pVM->pgm.s, GCPhys, &pTlbe);
-            AssertLogRelRCReturn(rc, rc);
+            rc2 = pgmPhysPageQueryTlbe(&pVM->pgm.s, GCPhys, &pTlbe);
+            AssertLogRelRCReturn(rc2, rc2);
             *ppv = (void *)((uintptr_t)pTlbe->pv | (GCPhys & PAGE_OFFSET_MASK));
             /** @todo mapping/locking hell; this isn't horribly efficient since
Index: /trunk/src/VBox/VMM/VMMAll/PGMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PGMAll.cpp	(revision 17508)
+++ /trunk/src/VBox/VMM/VMMAll/PGMAll.cpp	(revision 17509)
@@ -2090,5 +2090,5 @@
         rc = VMMR0CallHost(pVM, VMMCALLHOST_PGM_LOCK, 0);
 #endif
-    AssertRC(rc);
+    AssertMsg(rc == VINF_SUCCESS, ("%Rrc\n", rc));
     return rc;
 }
Index: /trunk/src/VBox/VMM/VMMAll/PGMAllBth.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PGMAllBth.h	(revision 17508)
+++ /trunk/src/VBox/VMM/VMMAll/PGMAllBth.h	(revision 17509)
@@ -399,5 +399,5 @@
             PPGMPAGE pPage;
             rc = pgmPhysGetPageEx(&pVM->pgm.s, GCPhys, &pPage);
-            if (RT_SUCCESS(rc))
+            if (RT_SUCCESS(rc)) /** just handle the failure immediate (it returns) and make things easier to read. */
             {
                 if (   PGM_PAGE_HAS_ACTIVE_PHYSICAL_HANDLERS(pPage)
@@ -641,5 +641,5 @@
             STAM_PROFILE_STOP(&pVM->pgm.s.StatRZTrap0eTimeHandlers, b);
 
-#  ifdef PGM_OUT_OF_SYNC_IN_GC
+#  ifdef PGM_OUT_OF_SYNC_IN_GC /** @todo remove this bugger. */
             /*
              * We are here only if page is present in Guest page tables and
@@ -755,25 +755,31 @@
                 }
             }
-            else
+            else /* uErr & X86_TRAP_PF_P: */
             {
-#   ifdef VBOX_WITH_NEW_PHYS_CODE
                 /*
-                 * Need to deal with these buggers somewhere...
-                 */
-                if (    PGM_PAGE_GET_STATE(pPage) != PGM_PAGE_STATE_ALLOCATED
-                    &&  (uErr & X86_TRAP_PF_RW))
-                {
-                    Log(("PGM #PF: %RGp %R[pgmpage] uErr=%#x\n", GCPhys, pPage, uErr));
-                    AssertMsgFailed(("PGM #PF: %RGp %R[pgmpage] uErr=%#x\n", GCPhys, pPage, uErr));
-                }
-#   endif /* VBOX_WITH_NEW_PHYS_CODE */
-
-                /*
-                 * A side effect of not flushing global PDEs are out of sync pages due
+                 * Write protected pages is make writable when the guest makes the first
+                 * write to it. This happens for pages that are shared, write monitored
+                 * and not yet allocated.
+                 *
+                 * Also, a side effect of not flushing global PDEs are out of sync pages due
                  * to physical monitored regions, that are no longer valid.
-                 * Assume for now it only applies to the read/write flag
+                 * Assume for now it only applies to the read/write flag.
                  */
                 if (RT_SUCCESS(rc) && (uErr & X86_TRAP_PF_RW))
                 {
+#   ifdef VBOX_WITH_NEW_PHYS_CODE
+                    if (PGM_PAGE_GET_STATE(pPage) != PGM_PAGE_STATE_ALLOCATED)
+                    {
+                        Log(("PGM #PF: Make writable: %RGp %R[pgmpage] pvFault=%RGp uErr=%#x\n",
+                             GCPhys, pPage, pvFault, uErr));
+                        rc = pgmPhysPageMakeWritableUnlocked(pVM, pPage, GCPhys);
+                        if (rc != VINF_SUCCESS)
+                        {
+                            AssertMsg(rc == VINF_PGM_SYNC_CR3 || RT_FAILURE(rc), ("%Rrc\n", rc));
+                            return rc;
+                        }
+                    }
+                    /// @todo count the above case; else
+#   endif /* VBOX_WITH_NEW_PHYS_CODE */
                     if (uErr & X86_TRAP_PF_US)
                         STAM_COUNTER_INC(&pVM->pgm.s.CTX_MID_Z(Stat,PageOutOfSyncUser));
@@ -781,7 +787,7 @@
                         STAM_COUNTER_INC(&pVM->pgm.s.CTX_MID_Z(Stat,PageOutOfSyncSupervisor));
 
-
                     /*
-                     * Note: Do NOT use PGM_SYNC_NR_PAGES here. That only works if the page is not present, which is not true in this case.
+                     * Note: Do NOT use PGM_SYNC_NR_PAGES here. That only works if the
+                     *       page is not present, which is not true in this case.
                      */
                     rc = PGM_BTH_NAME(SyncPage)(pVM, PdeSrc, pvFault, 1, uErr);
@@ -862,5 +868,5 @@
 #  endif /* PGM_OUT_OF_SYNC_IN_GC */
         }
-        else
+        else /* GCPhys == NIL_RTGCPHYS */
         {
             /*
@@ -880,4 +886,5 @@
         }
     }
+    /* else: !present (guest) */
 
 
@@ -1482,4 +1489,5 @@
         {
 #ifdef VBOX_WITH_NEW_PHYS_CODE
+# ifndef VBOX_WITH_NEW_LAZY_PAGE_ALLOC
             /* Try make the page writable if necessary. */
             if (    PteSrc.n.u1Write
@@ -1490,4 +1498,5 @@
                 AssertRC(rc);
             }
+# endif
 #endif
 
@@ -1574,5 +1583,5 @@
             {
                 PteDst.n.u1Write = 0;   /** @todo this isn't quite working yet. */
-                Log3(("SyncPageWorker: write-protecting pPage=%R[pgmpage]at iPTDst=%d\n", pPage, iPTDst));
+                Log3(("SyncPageWorker: write-protecting %RGp pPage=%R[pgmpage]at iPTDst=%d\n", (RTGCPHYS)(PteSrc.u & X86_PTE_PAE_PG_MASK), pPage, iPTDst));
             }
 #endif
@@ -1864,4 +1873,5 @@
                 {
 # ifdef VBOX_WITH_NEW_PHYS_CODE
+#  ifndef VBOX_WITH_NEW_LAZY_PAGE_ALLOC
                     /* Try make the page writable if necessary. */
                     if (    PdeSrc.n.u1Write
@@ -1872,4 +1882,5 @@
                         AssertRC(rc);
                     }
+#  endif
 # endif
 
@@ -1899,5 +1910,5 @@
                     {
                         PteDst.n.u1Write = 0;   /** @todo this isn't quite working yet... */
-                        Log3(("SyncPage: write-protecting pPage=%R[pgmpage] at %RGv\n", pPage, GCPtrPage));
+                        Log3(("SyncPage: write-protecting %RGp pPage=%R[pgmpage] at %RGv\n", GCPhys, pPage, GCPtrPage));
                     }
 # endif
@@ -2761,4 +2772,5 @@
 
 # ifdef VBOX_WITH_NEW_PHYS_CODE
+#  ifndef VBOX_WITH_NEW_LAZY_PAGE_ALLOC
                         /* Try make the page writable if necessary. */
                         if (    PteDstBase.n.u1Write
@@ -2769,4 +2781,5 @@
                             AssertRCReturn(rc, rc);
                         }
+#  endif
 # else  /* !VBOX_WITH_NEW_PHYS_CODE */
                         /* Make sure the RAM has already been allocated. */
@@ -2816,5 +2829,5 @@
                         {
                             PteDst.n.u1Write = 0;   /** @todo this isn't quite working yet... */
-                            Log3(("SyncPT: write-protecting pPage=%R[pgmpage] at %RGv\n", pPage, (RTGCPTR)(GCPtr | (iPTDst << SHW_PT_SHIFT))));
+                            Log3(("SyncPT: write-protecting %RGp pPage=%R[pgmpage] at %RGv\n", GCPhys, pPage, (RTGCPTR)(GCPtr | (iPTDst << SHW_PT_SHIFT))));
                         }
 # endif
Index: /trunk/src/VBox/VMM/VMMAll/PGMAllHandler.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PGMAllHandler.cpp	(revision 17508)
+++ /trunk/src/VBox/VMM/VMMAll/PGMAllHandler.cpp	(revision 17509)
@@ -216,9 +216,5 @@
      */
     bool            fFlushTLBs = false;
-#if defined(PGMPOOL_WITH_GCPHYS_TRACKING) || defined(PGMPOOL_WITH_CACHE)
     int             rc = VINF_SUCCESS;
-#else
-    const int       rc = VINF_PGM_GCPHYS_ALIASED;
-#endif
     const unsigned  uState = pgmHandlerPhysicalCalcState(pCur);
     RTUINT          cPages = pCur->cPages;
@@ -248,44 +244,7 @@
             Assert(PGM_PAGE_GET_HCPHYS(pPage));
 
-#ifdef PGMPOOL_WITH_GCPHYS_TRACKING
-            const uint16_t u16 = PGM_PAGE_GET_TRACKING(&pRam->aPages[i]);
-            if (u16)
-            {
-# ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
-                /* Start a subset here because pgmPoolTrackFlushGCPhysPTsSlow and pgmPoolTrackFlushGCPhysPTs
-                   will/may kill the pool otherwise. */
-                PVMCPU pVCpu = VMMGetCpu(pVM);
-                uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pVCpu);
-# endif
-                if (PGMPOOL_TD_GET_CREFS(u16) != PGMPOOL_TD_CREFS_PHYSEXT)
-                    pgmPoolTrackFlushGCPhysPT(pVM,
-                                              pPage,
-                                              PGMPOOL_TD_GET_IDX(u16),
-                                              PGMPOOL_TD_GET_CREFS(u16));
-                else if (u16 != PGMPOOL_TD_MAKE(PGMPOOL_TD_CREFS_PHYSEXT, PGMPOOL_TD_IDX_OVERFLOWED))
-                    pgmPoolTrackFlushGCPhysPTs(pVM, pPage, PGMPOOL_TD_GET_IDX(u16));
-                else
-                    rc = pgmPoolTrackFlushGCPhysPTsSlow(pVM, pPage);
-                fFlushTLBs = true;
-
-#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
-                PGMDynMapPopAutoSubset(pVCpu, iPrevSubset);
-#endif
-            }
-
-#elif defined(PGMPOOL_WITH_CACHE)
-# ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
-            /* Start a subset here because pgmPoolTrackFlushGCPhysPTsSlow kill the pool otherwise. */
-            PVMCPU pVCpu = VMMGetCpu(pVM);
-            uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pVCpu);
-# endif
-
-            rc = pgmPoolTrackFlushGCPhysPTsSlow(pVM, pPage);
-            fFlushTLBs = true;
-
-# ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
-            PGMDynMapPopAutoSubset(pVCpu, iPrevSubset);
-# endif
-#endif
+            int rc2 = pgmPoolTrackFlushGCPhys(pVM, pPage, &fFlushTLBs);
+            if (rc2 != VINF_SUCCESS && rc == VINF_SUCCESS)
+                rc = rc2;
         }
 
@@ -974,5 +933,13 @@
              * need to be copied over. The aliased page would have to be MMIO2 ofc, since
              * RAM or ROM pages would require write sharing which is something we don't
-             * intend to implement just yet... */
+             * intend to implement just yet...
+             */
+
+            /*
+             * Note! This trick does only work reliably if the two pages are never ever
+             *       mapped in the same page table. If they are the page pool code will
+             *       be confused should either of them be flushed. See the special case
+             *       of zero page aliasing mentioned in #3170.
+             */
 
             PPGMPAGE pPageRemap;
Index: /trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp	(revision 17508)
+++ /trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp	(revision 17509)
@@ -345,4 +345,5 @@
  * @returns The following VBox status codes.
  * @retval  VINF_SUCCESS on success, pPage is modified.
+ * @retval  VINF_PGM_SYNC_CR3 on success and a page pool flush is pending.
  * @retval  VERR_EM_NO_MEMORY if we're totally out of memory.
  *
@@ -368,14 +369,45 @@
 
     /*
+     * Prereqs.
+     */
+    Assert(PDMCritSectIsOwner(&pVM->pgm.s.CritSect));
+    AssertMsg(PGM_PAGE_IS_ZERO(pPage) || PGM_PAGE_IS_SHARED(pPage), ("%R[pgmpage] %RGp\n", pPage, GCPhys));
+    Assert(!PGM_PAGE_IS_MMIO(pPage));
+
+
+    /*
+     * Flush any shadow page table mappings of the page.
+     * When VBOX_WITH_NEW_LAZY_PAGE_ALLOC isn't defined, there shouldn't be any.
+     */
+    bool fFlushTLBs = false;
+    int rc = pgmPoolTrackFlushGCPhys(pVM, pPage, &fFlushTLBs);
+    if (rc == VINF_SUCCESS)
+        /* nothing */;
+    else if (rc == VINF_PGM_GCPHYS_ALIASED)
+    {
+        pVM->pgm.s.fSyncFlags |= PGM_SYNC_CLEAR_PGM_POOL;
+        VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3);
+        rc = VINF_PGM_SYNC_CR3;
+    }
+    else
+    {
+        AssertRCReturn(rc, rc);
+        AssertMsgFailedReturn(("%Rrc\n", rc), VERR_INTERNAL_ERROR);
+    }
+
+    /*
      * Ensure that we've got a page handy, take it and use it.
      */
-    int rc = pgmPhysEnsureHandyPage(pVM);
-    if (RT_FAILURE(rc))
-    {
-        Assert(rc == VERR_EM_NO_MEMORY);
-        return rc;
-    }
+    int rc2 = pgmPhysEnsureHandyPage(pVM);
+    if (RT_FAILURE(rc2))
+    {
+        if (fFlushTLBs)
+            PGM_INVL_GUEST_TLBS();
+        Assert(rc2 == VERR_EM_NO_MEMORY);
+        return rc2;
+    }
+    /* re-assert preconditions since pgmPhysEnsureHandyPage may do a context switch. */
     Assert(PDMCritSectIsOwner(&pVM->pgm.s.CritSect));
-    AssertMsg(PGM_PAGE_IS_ZERO(pPage) || PGM_PAGE_IS_SHARED(pPage), ("%d %RGp\n", PGM_PAGE_GET_STATE(pPage), GCPhys));
+    AssertMsg(PGM_PAGE_IS_ZERO(pPage) || PGM_PAGE_IS_SHARED(pPage), ("%R[pgmpage] %RGp\n", pPage, GCPhys));
     Assert(!PGM_PAGE_IS_MMIO(pPage));
 
@@ -424,5 +456,8 @@
     PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_ALLOCATED);
 
-    return VINF_SUCCESS;
+    if (    fFlushTLBs
+        &&  rc != VINF_PGM_GCPHYS_ALIASED)
+        PGM_INVL_GUEST_TLBS();
+    return rc;
 }
 
@@ -433,4 +468,5 @@
  * @returns VBox status code.
  * @retval  VINF_SUCCESS on success.
+ * @retval  VINF_PGM_SYNC_CR3 on success and a page pool flush is pending.
  * @retval  VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical backing.
  *
@@ -473,4 +509,5 @@
  * @returns VBox status code.
  * @retval  VINF_SUCCESS on success.
+ * @retval  VINF_PGM_SYNC_CR3 on success and a page pool flush is pending.
  * @retval  VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical backing.
  *
@@ -824,4 +861,5 @@
         if (RT_FAILURE(rc))
             return rc;
+        AssertMsg(rc == VINF_SUCCESS || rc == VINF_PGM_SYNC_CR3 /* not returned */, ("%Rrc\n", rc));
     }
     Assert(PGM_PAGE_GET_HCPHYS(pPage) != 0);
@@ -929,4 +967,6 @@
             pLock->u32Dummy = UINT32_MAX;
 #endif
+            AssertMsg(rc == VINF_SUCCESS || rc == VINF_PGM_SYNC_CR3 /* not returned */, ("%Rrc\n", rc));
+            rc = VINF_SUCCESS;
         }
     }
@@ -952,5 +992,8 @@
             rc = pgmPhysPageMakeWritable(pVM, pPage, GCPhys);
             if (RT_SUCCESS(rc))
+            {
+                AssertMsg(rc == VINF_SUCCESS || rc == VINF_PGM_SYNC_CR3 /* not returned */, ("%Rrc\n", rc));
                 rc = pgmPhysPageQueryTlbeWithPage(&pVM->pgm.s, pPage, GCPhys, &pTlbe);
+            }
         }
         if (RT_SUCCESS(rc))
Index: /trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp	(revision 17508)
+++ /trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp	(revision 17509)
@@ -2994,4 +2994,93 @@
 
 /**
+ * Flushes all shadow page table mappings of the given guest page.
+ *
+ * This is typically called when the host page backing the guest one has been
+ * replaced or when the page protection was changed due to an access handler.
+ *
+ * @returns VBox status code.
+ * @retval  VINF_SUCCESS if all references has been successfully cleared.
+ * @retval  VINF_PGM_GCPHYS_ALIASED if we're better off with a CR3 sync and
+ *          a page pool cleaning.
+ *
+ * @param   pVM         The VM handle.
+ * @param   pPhysPage   The guest page in question.
+ * @param   pfFlushTLBs This is set to @a true if the shadow TLBs should be
+ *                      flushed, it is NOT touched if this isn't necessary.
+ *                      The caller MUST initialized this to @a false.
+ */
+int pgmPoolTrackFlushGCPhys(PVM pVM, PPGMPAGE pPhysPage, bool *pfFlushTLBs)
+{
+    int rc = VINF_SUCCESS;
+#ifdef PGMPOOL_WITH_GCPHYS_TRACKING
+    const uint16_t u16 = PGM_PAGE_GET_TRACKING(pPhysPage);
+    if (u16)
+    {
+# ifdef VBOX_WITH_NEW_PHYS_CODE
+        /*
+         * The zero page is currently screwing up the tracking and we'll
+         * have to flush the whole shebang. Unless VBOX_WITH_NEW_LAZY_PAGE_ALLOC
+         * is defined, zero pages won't normally be mapped. Some kind of solution
+         * will be needed for this problem of course, but it will have to wait...
+         */
+        if (PGM_PAGE_IS_ZERO(pPhysPage))
+            rc = VINF_PGM_GCPHYS_ALIASED;
+        else
+# endif
+        {
+# ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
+            /* Start a subset here because pgmPoolTrackFlushGCPhysPTsSlow and
+               pgmPoolTrackFlushGCPhysPTs will/may kill the pool otherwise. */
+            PVMCPU pVCpu = VMMGetCpu(pVM);
+            uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pVCpu);
+# endif
+
+            if (PGMPOOL_TD_GET_CREFS(u16) != PGMPOOL_TD_CREFS_PHYSEXT)
+                pgmPoolTrackFlushGCPhysPT(pVM,
+                                          pPhysPage,
+                                          PGMPOOL_TD_GET_IDX(u16),
+                                          PGMPOOL_TD_GET_CREFS(u16));
+            else if (u16 != PGMPOOL_TD_MAKE(PGMPOOL_TD_CREFS_PHYSEXT, PGMPOOL_TD_IDX_OVERFLOWED))
+                pgmPoolTrackFlushGCPhysPTs(pVM, pPhysPage, PGMPOOL_TD_GET_IDX(u16));
+            else
+                rc = pgmPoolTrackFlushGCPhysPTsSlow(pVM, pPhysPage);
+            *pfFlushTLBs = true;
+
+# ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
+            PGMDynMapPopAutoSubset(pVCpu, iPrevSubset);
+# endif
+        }
+    }
+
+#elif defined(PGMPOOL_WITH_CACHE)
+# ifdef VBOX_WITH_NEW_PHYS_CODE
+    if (PGM_PAGE_IS_ZERO(pPhysPage))
+        rc = VINF_PGM_GCPHYS_ALIASED;
+    else
+# endif
+    {
+# ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
+        /* Start a subset here because pgmPoolTrackFlushGCPhysPTsSlow kill the pool otherwise. */
+        PVMCPU pVCpu = VMMGetCpu(pVM);
+        uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pVCpu);
+# endif
+        rc = pgmPoolTrackFlushGCPhysPTsSlow(pVM, pPhysPage);
+        if (rc == VINF_SUCCESS)
+            *pfFlushTLBs = true;
+    }
+
+# ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
+    PGMDynMapPopAutoSubset(pVCpu, iPrevSubset);
+# endif
+
+#else
+    rc = VINF_PGM_GCPHYS_ALIASED;
+#endif
+
+    return rc;
+}
+
+
+/**
  * Scans all shadow page tables for mappings of a physical page.
  *
