Index: trunk/src/VBox/VMM/PGMInternal.h
===================================================================
--- trunk/src/VBox/VMM/PGMInternal.h	(revision 31445)
+++ trunk/src/VBox/VMM/PGMInternal.h	(revision 31446)
@@ -319,4 +319,6 @@
  * is no longer used.
  *
+ * For best effect only apply this to the page that was mapped most recently.
+ *
  * @param   pVCpu   The current CPU.
  * @param   pPage   The pool page.
@@ -335,4 +337,6 @@
  * Hints to the dynamic mapping code in RC and R0/darwin that the specified page
  * is no longer used.
+ *
+ * For best effect only apply this to the page that was mapped most recently.
  *
  * @param   pVM     The VM handle.
Index: trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp	(revision 31445)
+++ trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp	(revision 31446)
@@ -1070,4 +1070,6 @@
         int rc = PGM_GCPHYS_2_PTR(pPool->CTX_SUFF(pVM), pPage->GCPhys, &pvGst); AssertReleaseRC(rc);
         pgmPoolTrackCheckPTPaePae(pPool, pPage, (PX86PTPAE)pvShw, (PCX86PTPAE)pvGst);
+        PGM_DYNMAP_UNUSED_HINT_VM(pVM, pvGst);
+        PGM_DYNMAP_UNUSED_HINT_VM(pVM, pvShw);
     }
 #endif
@@ -1344,4 +1346,5 @@
     unsigned LastPTE    = ~0U;          /* initialized to shut up gcc */
     RTHCPHYS LastHCPhys = NIL_RTHCPHYS; /* initialized to shut up gcc */
+    PVM      pVM        = pPool->CTX_SUFF(pVM);
 
 #ifdef VBOX_STRICT
@@ -1354,5 +1357,5 @@
         {
             RTHCPHYS HCPhys = NIL_RTHCPHYS;
-            int rc = PGMPhysGCPhys2HCPhys(pPool->CTX_SUFF(pVM), pGstPT->a[i].u & X86_PTE_PAE_PG_MASK, &HCPhys);
+            int rc = PGMPhysGCPhys2HCPhys(pVM, pGstPT->a[i].u & X86_PTE_PAE_PG_MASK, &HCPhys);
             if (    rc != VINF_SUCCESS
                 ||  (pShwPT->a[i].u & X86_PTE_PAE_PG_MASK) != HCPhys)
@@ -1365,5 +1368,5 @@
 
                 RTHCPHYS HCPhysPT = NIL_RTHCPHYS;
-                rc = PGMPhysGCPhys2HCPhys(pPool->CTX_SUFF(pVM), pPage->GCPhys, &HCPhysPT);
+                rc = PGMPhysGCPhys2HCPhys(pVM, pPage->GCPhys, &HCPhysPT);
                 AssertRC(rc);
 
@@ -1374,5 +1377,5 @@
                     if (pTempPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_PAE_PT)
                     {
-                        PX86PTPAE pShwPT2 = (PX86PTPAE)PGMPOOL_PAGE_2_PTR(pPool->CTX_SUFF(pVM), pTempPage);
+                        PX86PTPAE pShwPT2 = (PX86PTPAE)PGMPOOL_PAGE_2_PTR(pVM, pTempPage);
 
                         for (unsigned j = 0; j < RT_ELEMENTS(pShwPT->a); j++)
@@ -1385,4 +1388,6 @@
                             }
                         }
+
+                        PGM_DYNMAP_UNUSED_HINT_VM(pVM, pShwPT2);
                     }
                 }
@@ -1406,5 +1411,6 @@
  * @param   pfFlush         Flush reused page table (out)
  */
-DECLINLINE(unsigned) pgmPoolTrackFlushPTPaePae(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PX86PTPAE pShwPT, PCX86PTPAE pGstPT, PCX86PTPAE pOldGstPT, bool fAllowRemoval, bool *pfFlush)
+DECLINLINE(unsigned) pgmPoolTrackFlushPTPaePae(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PX86PTPAE pShwPT, PCX86PTPAE pGstPT,
+                                               PCX86PTPAE pOldGstPT, bool fAllowRemoval, bool *pfFlush)
 {
     unsigned cChanged = 0;
@@ -1511,11 +1517,14 @@
     /* Flush those PTEs that have changed. */
     STAM_PROFILE_START(&pPool->StatTrackDeref,a);
-    void *pvShw = PGMPOOL_PAGE_2_PTR(pPool->CTX_SUFF(pVM), pPage);
+    void *pvShw = PGMPOOL_PAGE_2_PTR(pVM, pPage);
     void *pvGst;
+    rc = PGM_GCPHYS_2_PTR(pVM, pPage->GCPhys, &pvGst); AssertReleaseRC(rc);
     bool  fFlush;
-    rc = PGM_GCPHYS_2_PTR(pPool->CTX_SUFF(pVM), pPage->GCPhys, &pvGst); AssertReleaseRC(rc);
-    unsigned cChanges = pgmPoolTrackFlushPTPaePae(pPool, pPage, (PX86PTPAE)pvShw, (PCX86PTPAE)pvGst, (PCX86PTPAE)&pPool->aDirtyPages[idxSlot][0], fAllowRemoval, &fFlush);
+    unsigned cChanges = pgmPoolTrackFlushPTPaePae(pPool, pPage, (PX86PTPAE)pvShw, (PCX86PTPAE)pvGst,
+                                                  (PCX86PTPAE)&pPool->aDirtyPages[idxSlot][0], fAllowRemoval, &fFlush);
+    PGM_DYNMAP_UNUSED_HINT_VM(pVM, pvGst);
+    PGM_DYNMAP_UNUSED_HINT_VM(pVM, pvShw);
     STAM_PROFILE_STOP(&pPool->StatTrackDeref,a);
-    /** Note: we might want to consider keeping the dirty page active in case there were many changes. */
+    /* Note: we might want to consider keeping the dirty page active in case there were many changes. */
 
     /* This page is likely to be modified again, so reduce the nr of modifications just a bit here. */
@@ -1578,14 +1587,18 @@
     Log(("Add dirty page %RGp (slot=%d)\n", pPage->GCPhys, idxFree));
 
-    /* Make a copy of the guest page table as we require valid GCPhys addresses when removing
-     * references to physical pages. (the HCPhys linear lookup is *extremely* expensive!)
-     */
-    void *pvShw = PGMPOOL_PAGE_2_PTR(pPool->CTX_SUFF(pVM), pPage);
+    /*
+     * Make a copy of the guest page table as we require valid GCPhys addresses
+     * when removing references to physical pages.
+     * (The HCPhys linear lookup is *extremely* expensive!)
+     */
     void *pvGst;
-    int rc = PGM_GCPHYS_2_PTR(pPool->CTX_SUFF(pVM), pPage->GCPhys, &pvGst); AssertReleaseRC(rc);
+    int   rc  = PGM_GCPHYS_2_PTR(pVM, pPage->GCPhys, &pvGst); AssertReleaseRC(rc);
     memcpy(&pPool->aDirtyPages[idxFree][0], pvGst, PAGE_SIZE);
 #ifdef VBOX_STRICT
+    void *pvShw = PGMPOOL_PAGE_2_PTR(pVM, pPage);
     pgmPoolTrackCheckPTPaePae(pPool, pPage, (PX86PTPAE)pvShw, (PCX86PTPAE)pvGst);
+    PGM_DYNMAP_UNUSED_HINT_VM(pVM, pvShw);
 #endif
+    PGM_DYNMAP_UNUSED_HINT_VM(pVM, pvGst);
 
     STAM_COUNTER_INC(&pPool->StatDirtyPage);
@@ -2915,5 +2928,5 @@
     LogFlow(("pgmPoolTrackFlushGCPhysPT: pPhysPage=%RHp iShw=%d iPte=%d cRefs=%d\n", PGM_PAGE_GET_HCPHYS(pPhysPage), iShw, iPte, cRefs));
     PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
-    bool bRet = false;
+    bool     fRet  = false;
 
     /*
@@ -2936,8 +2949,6 @@
             const uint32_t  u32 = PGM_PAGE_GET_HCPHYS(pPhysPage) | X86_PTE_P;
             PX86PT          pPT = (PX86PT)PGMPOOL_PAGE_2_PTR(pVM, pPage);
-            uint32_t        u32AndMask, u32OrMask;
-
-            u32AndMask = 0;
-            u32OrMask  = 0;
+            uint32_t        u32AndMask = 0;
+            uint32_t        u32OrMask  = 0;
 
             if (!fFlushPTEs)
@@ -2945,21 +2956,21 @@
                 switch (PGM_PAGE_GET_HNDL_PHYS_STATE(pPhysPage))
                 {
-                case PGM_PAGE_HNDL_PHYS_STATE_NONE:         /** No handler installed. */
-                case PGM_PAGE_HNDL_PHYS_STATE_DISABLED:     /** Monitoring is temporarily disabled. */
-                    u32OrMask = X86_PTE_RW;
-                    u32AndMask = UINT32_MAX;
-                    bRet = true;
-                    STAM_COUNTER_INC(&pPool->StatTrackFlushEntryKeep);
-                    break;
-
-                case PGM_PAGE_HNDL_PHYS_STATE_WRITE:        /** Write access is monitored. */
-                    u32OrMask = 0;
-                    u32AndMask = ~X86_PTE_RW;
-                    bRet = true;
-                    STAM_COUNTER_INC(&pPool->StatTrackFlushEntryKeep);
-                    break;
-                default:
-                    STAM_COUNTER_INC(&pPool->StatTrackFlushEntry);
-                    break;
+                    case PGM_PAGE_HNDL_PHYS_STATE_NONE:         /** No handler installed. */
+                    case PGM_PAGE_HNDL_PHYS_STATE_DISABLED:     /** Monitoring is temporarily disabled. */
+                        u32OrMask = X86_PTE_RW;
+                        u32AndMask = UINT32_MAX;
+                        fRet = true;
+                        STAM_COUNTER_INC(&pPool->StatTrackFlushEntryKeep);
+                        break;
+
+                    case PGM_PAGE_HNDL_PHYS_STATE_WRITE:        /** Write access is monitored. */
+                        u32OrMask = 0;
+                        u32AndMask = ~X86_PTE_RW;
+                        fRet = true;
+                        STAM_COUNTER_INC(&pPool->StatTrackFlushEntryKeep);
+                        break;
+                    default:
+                        STAM_COUNTER_INC(&pPool->StatTrackFlushEntry);
+                        break;
                 }
             }
@@ -2986,5 +2997,6 @@
 
                 ASMAtomicWriteSize(&pPT->a[iPte].u, Pte.u);
-                return bRet;
+                PGM_DYNMAP_UNUSED_HINT_VM(pVM, pPT);
+                return fRet;
             }
 #ifdef LOG_ENABLED
@@ -2997,4 +3009,5 @@
 #endif
             AssertFatalMsgFailed(("cRefs=%d iFirstPresent=%d cPresent=%d u32=%RX32 poolkind=%x\n", cRefs, pPage->iFirstPresent, pPage->cPresent, u32, pPage->enmKind));
+            PGM_DYNMAP_UNUSED_HINT_VM(pVM, pPT);
             break;
         }
@@ -3009,30 +3022,29 @@
             const uint64_t  u64 = PGM_PAGE_GET_HCPHYS(pPhysPage) | X86_PTE_P;
             PX86PTPAE       pPT = (PX86PTPAE)PGMPOOL_PAGE_2_PTR(pVM, pPage);
-            uint64_t        u64AndMask, u64OrMask;
-
-            u64OrMask = 0;
-            u64AndMask = 0;
+            uint64_t        u64OrMask  = 0;
+            uint64_t        u64AndMask = 0;
+
             if (!fFlushPTEs)
             {
                 switch (PGM_PAGE_GET_HNDL_PHYS_STATE(pPhysPage))
                 {
-                case PGM_PAGE_HNDL_PHYS_STATE_NONE:         /** No handler installed. */
-                case PGM_PAGE_HNDL_PHYS_STATE_DISABLED:     /** Monitoring is temporarily disabled. */
-                    u64OrMask = X86_PTE_RW;
-                    u64AndMask = UINT64_MAX;
-                    bRet = true;
-                    STAM_COUNTER_INC(&pPool->StatTrackFlushEntryKeep);
-                    break;
-
-                case PGM_PAGE_HNDL_PHYS_STATE_WRITE:        /** Write access is monitored. */
-                    u64OrMask = 0;
-                    u64AndMask = ~((uint64_t)X86_PTE_RW);
-                    bRet = true;
-                    STAM_COUNTER_INC(&pPool->StatTrackFlushEntryKeep);
-                    break;
-
-                default:
-                    STAM_COUNTER_INC(&pPool->StatTrackFlushEntry);
-                    break;
+                    case PGM_PAGE_HNDL_PHYS_STATE_NONE:         /** No handler installed. */
+                    case PGM_PAGE_HNDL_PHYS_STATE_DISABLED:     /** Monitoring is temporarily disabled. */
+                        u64OrMask = X86_PTE_RW;
+                        u64AndMask = UINT64_MAX;
+                        fRet = true;
+                        STAM_COUNTER_INC(&pPool->StatTrackFlushEntryKeep);
+                        break;
+
+                    case PGM_PAGE_HNDL_PHYS_STATE_WRITE:        /** Write access is monitored. */
+                        u64OrMask = 0;
+                        u64AndMask = ~((uint64_t)X86_PTE_RW);
+                        fRet = true;
+                        STAM_COUNTER_INC(&pPool->StatTrackFlushEntryKeep);
+                        break;
+
+                    default:
+                        STAM_COUNTER_INC(&pPool->StatTrackFlushEntry);
+                        break;
                 }
             }
@@ -3059,5 +3071,6 @@
 
                 ASMAtomicWriteSize(&pPT->a[iPte].u, Pte.u);
-                return bRet;
+                PGM_DYNMAP_UNUSED_HINT_VM(pVM, pPT);
+                return fRet;
             }
 #ifdef LOG_ENABLED
@@ -3071,4 +3084,5 @@
 #endif
             AssertFatalMsgFailed(("cRefs=%d iFirstPresent=%d cPresent=%d u64=%RX64 poolkind=%x\n", cRefs, pPage->iFirstPresent, pPage->cPresent, u64, pPage->enmKind));
+            PGM_DYNMAP_UNUSED_HINT_VM(pVM, pPT);
             break;
         }
@@ -3088,4 +3102,5 @@
                 STAM_COUNTER_INC(&pPool->StatTrackFlushEntry);
                 pPD->a[iPte].u = 0;
+                PGM_DYNMAP_UNUSED_HINT_VM(pVM, pPD);
 
                 /* Update the counter as we're removing references. */
@@ -3095,5 +3110,5 @@
                 pPool->cPresent--;
 
-                return bRet;
+                return fRet;
             }
 # ifdef LOG_ENABLED
@@ -3106,4 +3121,5 @@
 # endif
             AssertFatalMsgFailed(("cRefs=%d iFirstPresent=%d cPresent=%d\n", cRefs, pPage->iFirstPresent, pPage->cPresent));
+            PGM_DYNMAP_UNUSED_HINT_VM(pVM, pPD);
             break;
         }
@@ -3122,4 +3138,5 @@
                 STAM_COUNTER_INC(&pPool->StatTrackFlushEntry);
                 pPD->a[iPte].u = 0;
+                PGM_DYNMAP_UNUSED_HINT_VM(pVM, pPD);
 
                 /* Update the counter as we're removing references. */
@@ -3128,5 +3145,5 @@
                 pPage->cPresent--;
                 pPool->cPresent--;
-                return bRet;
+                return fRet;
             }
 # ifdef LOG_ENABLED
@@ -3139,4 +3156,5 @@
 # endif
             AssertFatalMsgFailed(("cRefs=%d iFirstPresent=%d cPresent=%d\n", cRefs, pPage->iFirstPresent, pPage->cPresent));
+            PGM_DYNMAP_UNUSED_HINT_VM(pVM, pPD);
             break;
         }
@@ -3146,5 +3164,5 @@
             AssertFatalMsgFailed(("enmKind=%d iShw=%d\n", pPage->enmKind, iShw));
     }
-    return bRet;
+    return fRet;
 }
 
@@ -3306,5 +3324,5 @@
         else
         {
-# if defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) || defined(IN_RC)
+# if defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) || defined(IN_RC) /** @todo we can drop this now. */
             /* Start a subset here because pgmPoolTrackFlushGCPhysPTsSlow and
                pgmPoolTrackFlushGCPhysPTs will/may kill the pool otherwise. */
@@ -3415,4 +3433,5 @@
                                 break;
                         }
+                    PGM_DYNMAP_UNUSED_HINT_VM(pVM, pPT);
                     break;
                 }
@@ -3443,4 +3462,5 @@
                                 break;
                         }
+                    PGM_DYNMAP_UNUSED_HINT_VM(pVM, pPT);
                     break;
                 }
@@ -3467,4 +3487,5 @@
                                 break;
                         }
+                    PGM_DYNMAP_UNUSED_HINT_VM(pVM, pPT);
                     break;
                 }
@@ -3593,10 +3614,12 @@
         case PGMPOOLKIND_PAE_PD_FOR_PAE_PD:
 #if defined(IN_RC)
-            /* In 32 bits PAE mode we *must* invalidate the TLB when changing a PDPT entry; the CPU fetches them only during cr3 load, so any
+            /*
+             * In 32 bits PAE mode we *must* invalidate the TLB when changing a
+             * PDPT entry; the CPU fetches them only during cr3 load, so any
              * non-present PDPT will continue to cause page faults.
              */
             ASMReloadCR3();
+            /* no break */
 #endif
-            /* no break */
         case PGMPOOLKIND_PAE_PD_PHYS:
         case PGMPOOLKIND_PAE_PDPT_PHYS:
@@ -4390,5 +4413,6 @@
      * Map the shadow page and take action according to the page kind.
      */
-    void *pvShw = PGMPOOL_PAGE_2_PTR(pPool->CTX_SUFF(pVM), pPage);
+    PVM   pVM   = pPool->CTX_SUFF(pVM);
+    void *pvShw = PGMPOOL_PAGE_2_PTR(pVM, pPage);
     switch (pPage->enmKind)
     {
@@ -4397,6 +4421,7 @@
             STAM_PROFILE_START(&pPool->StatTrackDerefGCPhys, g);
             void *pvGst;
-            int rc = PGM_GCPHYS_2_PTR(pPool->CTX_SUFF(pVM), pPage->GCPhys, &pvGst); AssertReleaseRC(rc);
+            int rc = PGM_GCPHYS_2_PTR(pVM, pPage->GCPhys, &pvGst); AssertReleaseRC(rc);
             pgmPoolTrackDerefPT32Bit32Bit(pPool, pPage, (PX86PT)pvShw, (PCX86PT)pvGst);
+            PGM_DYNMAP_UNUSED_HINT_VM(pVM, pvGst);
             STAM_PROFILE_STOP(&pPool->StatTrackDerefGCPhys, g);
             break;
@@ -4407,6 +4432,7 @@
             STAM_PROFILE_START(&pPool->StatTrackDerefGCPhys, g);
             void *pvGst;
-            int rc = PGM_GCPHYS_2_PTR_EX(pPool->CTX_SUFF(pVM), pPage->GCPhys, &pvGst); AssertReleaseRC(rc);
+            int rc = PGM_GCPHYS_2_PTR_EX(pVM, pPage->GCPhys, &pvGst); AssertReleaseRC(rc);
             pgmPoolTrackDerefPTPae32Bit(pPool, pPage, (PX86PTPAE)pvShw, (PCX86PT)pvGst);
+            PGM_DYNMAP_UNUSED_HINT_VM(pVM, pvGst);
             STAM_PROFILE_STOP(&pPool->StatTrackDerefGCPhys, g);
             break;
@@ -4417,6 +4443,7 @@
             STAM_PROFILE_START(&pPool->StatTrackDerefGCPhys, g);
             void *pvGst;
-            int rc = PGM_GCPHYS_2_PTR(pPool->CTX_SUFF(pVM), pPage->GCPhys, &pvGst); AssertReleaseRC(rc);
+            int rc = PGM_GCPHYS_2_PTR(pVM, pPage->GCPhys, &pvGst); AssertReleaseRC(rc);
             pgmPoolTrackDerefPTPaePae(pPool, pPage, (PX86PTPAE)pvShw, (PCX86PTPAE)pvGst);
+            PGM_DYNMAP_UNUSED_HINT_VM(pVM, pvGst);
             STAM_PROFILE_STOP(&pPool->StatTrackDerefGCPhys, g);
             break;
@@ -4494,6 +4521,6 @@
     STAM_PROFILE_STOP(&pPool->StatZeroPage, z);
     pPage->fZeroed = true;
-    PGM_DYNMAP_UNUSED_HINT_VM(pPool->CTX_SUFF(pVM), pvShw);
     Assert(!pPage->cPresent);
+    PGM_DYNMAP_UNUSED_HINT_VM(pVM, pvShw);
 }
 
