Index: trunk/src/VBox/VMM/PGM.cpp
===================================================================
--- trunk/src/VBox/VMM/PGM.cpp	(revision 14876)
+++ trunk/src/VBox/VMM/PGM.cpp	(revision 14877)
@@ -1606,5 +1606,4 @@
     STAM_REG(pVM, &pPGM->StatR0DynMapPageHit1,              STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/Hit1",            STAMUNIT_OCCURENCES,     "Hit at iPage+1");
     STAM_REG(pVM, &pPGM->StatR0DynMapPageHit2,              STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/Hit2",            STAMUNIT_OCCURENCES,     "Hit at iPage+2");
-    STAM_REG(pVM, &pPGM->StatR0DynMapPageHit3,              STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/Hit3",            STAMUNIT_OCCURENCES,     "Hit at iPage+3");
     STAM_REG(pVM, &pPGM->StatR0DynMapPageInvlPg,            STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/InvlPg",          STAMUNIT_OCCURENCES,     "invlpg count in pgmR0DynMapPageSlow.");
     STAM_REG(pVM, &pPGM->StatR0DynMapPageSlow,              STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/Slow",            STAMUNIT_OCCURENCES,     "Calls to pgmR0DynMapPageSlow - subtract this from pgmR0DynMapPage to get 1st level hits.");
Index: trunk/src/VBox/VMM/PGMInternal.h
===================================================================
--- trunk/src/VBox/VMM/PGMInternal.h	(revision 14876)
+++ trunk/src/VBox/VMM/PGMInternal.h	(revision 14877)
@@ -2570,5 +2570,4 @@
     STAMCOUNTER StatR0DynMapPageHit1;               /**< R0: Hit at iPage+1. */
     STAMCOUNTER StatR0DynMapPageHit2;               /**< R0: Hit at iPage+2. */
-    STAMCOUNTER StatR0DynMapPageHit3;               /**< R0: Hit at iPage+3. */
     STAMCOUNTER StatR0DynMapPageInvlPg;             /**< R0: invlpg. */
     STAMCOUNTER StatR0DynMapPageSlow;               /**< R0: Calls to pgmR0DynMapPageSlow. */
Index: trunk/src/VBox/VMM/VMMR0/PGMR0DynMap.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/PGMR0DynMap.cpp	(revision 14876)
+++ trunk/src/VBox/VMM/VMMR0/PGMR0DynMap.cpp	(revision 14877)
@@ -44,10 +44,13 @@
 *******************************************************************************/
 /** The max size of the mapping cache (in pages). */
-#define PGMR0DYNMAP_MAX_PAGES               ((8*_1M) >> PAGE_SHIFT)
+#define PGMR0DYNMAP_MAX_PAGES               ((16*_1M) >> PAGE_SHIFT)
 /** The small segment size that is adopted on out-of-memory conditions with a
  * single big segment. */
 #define PGMR0DYNMAP_SMALL_SEG_PAGES         128
 /** The number of pages we reserve per CPU. */
-#define PGMR0DYNMAP_PAGES_PER_CPU           64
+#define PGMR0DYNMAP_PAGES_PER_CPU           256
+/** The minimum number of pages we reserve per CPU.
+ * This must be equal or larger than the autoset size.  */
+#define PGMR0DYNMAP_PAGES_PER_CPU_MIN       32
 /** The number of guard pages.
  * @remarks Never do tuning of the hashing or whatnot with a strict build!  */
@@ -534,9 +537,9 @@
     Assert(pThis->cPages <= PGMR0DYNMAP_MAX_PAGES);
 
-    /* cCpus * PGMR0DYNMAP_PAGES_PER_CPU (/2). */
+    /* cCpus * PGMR0DYNMAP_PAGES_PER_CPU(_MIN). */
     RTCPUID     cCpus     = RTMpGetCount();
     AssertReturn(cCpus > 0 && cCpus <= RTCPUSET_MAX_CPUS, 0);
-    uint32_t    cPages    = cCpus *  PGMR0DYNMAP_PAGES_PER_CPU;
-    uint32_t    cMinPages = cCpus * (PGMR0DYNMAP_PAGES_PER_CPU / 2);
+    uint32_t    cPages    = cCpus * PGMR0DYNMAP_PAGES_PER_CPU;
+    uint32_t    cMinPages = cCpus * PGMR0DYNMAP_PAGES_PER_CPU_MIN;
 
     /* adjust against cMaxLoad. */
@@ -1174,5 +1177,5 @@
 
     /*
-     * Check if any of the first 4 pages are unreferenced since the caller
+     * Check if any of the first 3 pages are unreferenced since the caller
      * already has made sure they aren't matching.
      */
@@ -1189,6 +1192,4 @@
     else if (!paPages[(iPage + 2) % cPages].cRefs)
         iFreePage   = (iPage + 2) % cPages;
-    else if (!paPages[(iPage + 3) % cPages].cRefs)
-        iFreePage   = (iPage + 3) % cPages;
     else
     {
@@ -1196,5 +1197,5 @@
          * Search for an unused or matching entry.
          */
-        iFreePage = (iPage + 4) % cPages;
+        iFreePage = (iPage + 3) % cPages;
         for (;;)
         {
@@ -1222,5 +1223,5 @@
     /* Check for lost hits. */
     if (!fLooped)
-        for (uint32_t iPage2 = (iPage + 4) % cPages; iPage2 != iPage; iPage2 = (iPage2 + 1) % cPages)
+        for (uint32_t iPage2 = (iPage + 3) % cPages; iPage2 != iPage; iPage2 = (iPage2 + 1) % cPages)
             if (paPages[iPage2].HCPhys == HCPhys)
                 STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPageSlowLostHits);
@@ -1278,6 +1279,6 @@
     /*
      * Find an entry, if possible a matching one. The HCPhys address is hashed
-     * down to a page index, collisions are handled by linear searching. Optimize
-     * for a hit in the first 4 pages.
+     * down to a page index, collisions are handled by linear searching.
+     * Optimized for a hit in the first 3 pages.
      *
      * To the cheap hits here and defer the tedious searching and inserting
@@ -1307,18 +1308,9 @@
             else
             {
-                iPage2 = (iPage + 3) % cPages;
-                if (paPages[iPage2].HCPhys == HCPhys)
+                iPage = pgmR0DynMapPageSlow(pThis, HCPhys, iPage, pVM);
+                if (RT_UNLIKELY(iPage == UINT32_MAX))
                 {
-                    iPage = iPage2;
-                    STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPageHit3);
-                }
-                else
-                {
-                    iPage = pgmR0DynMapPageSlow(pThis, HCPhys, iPage, pVM);
-                    if (RT_UNLIKELY(iPage == UINT32_MAX))
-                    {
-                        RTSpinlockRelease(pThis->hSpinlock, &Tmp);
-                        return iPage;
-                    }
+                    RTSpinlockRelease(pThis->hSpinlock, &Tmp);
+                    return iPage;
                 }
             }
