Index: /trunk/src/VBox/VMM/VMMRZ/PGMRZDynMap.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMRZ/PGMRZDynMap.cpp	(revision 31444)
+++ /trunk/src/VBox/VMM/VMMRZ/PGMRZDynMap.cpp	(revision 31445)
@@ -146,4 +146,12 @@
         (pEntry)->cUnrefs      = 0; \
     } while (0)
+
+
+/** @def PGMRZDYNMAP_STRICT_RELEASE
+ * Define this to force pages to be released and make non-present ASAP after
+ * use.  This should not normally be enabled as it is a bit expensive. */
+#if 0 || defined(DOXYGEN_RUNNING)
+# define PGMRZDYNMAP_STRICT_RELEASE
+#endif
 
 
@@ -1312,5 +1320,12 @@
     AssertMsg(cRefs >= 0, ("%d\n", cRefs));
     if (!cRefs)
+    {
         pThis->cLoad--;
+#ifdef PGMRZDYNMAP_STRICT_RELEASE
+        pThis->paPages[iPage].HCPhys = NIL_RTHCPHYS;
+        ASMAtomicBitClear(pThis->paPages[iPage].uPte.pv, X86_PTE_BIT_P);
+        ASMInvalidatePage(pThis->paPages[iPage].pvPage);
+#endif
+    }
 }
 
@@ -1615,5 +1630,5 @@
                     cLoad++;
             }
-#ifdef IN_RING0
+#if defined(IN_RING0) && !defined(PGMRZDYNMAP_STRICT_RELEASE)
             else
                 CHECK_RET(paPages[iPage].uPte.pLegacy->u == paSavedPTEs[iPage],
@@ -2142,4 +2157,6 @@
      * Find the entry in the usual unrolled fashion.
      */
+    /** @todo add a hint to the set which entry was used last since it's not
+     *        always the last entry? */
 #define IS_MATCHING_ENTRY(pSet, iEntry, pvHint) \
         (   (pSet)->aEntries[(iEntry)].pvPage == (pvHint) \
@@ -2215,4 +2232,12 @@
     else
         Log(("pgmRZDynMapUnusedHint: pvHint=%p ignored because of overflow! %s(%d) %s\n", pvHint, pszFile, iLine, pszFunction));
+
+#ifdef PGMRZDYNMAP_STRICT_RELEASE
+    /*
+     * Optimize the set to trigger the unmapping and invalidation of the page.
+     */
+    if (cUnrefs + 1 == cTotalRefs)
+        pgmDynMapOptimizeAutoSet(pSet);
+#endif
 }
 
