Index: trunk/src/VBox/VMM/include/PGMGstDefs.h
===================================================================
--- trunk/src/VBox/VMM/include/PGMGstDefs.h	(revision 36857)
+++ trunk/src/VBox/VMM/include/PGMGstDefs.h	(revision 36891)
@@ -140,5 +140,5 @@
 # define GST_GET_PTE_GCPHYS(Pte)                ((Pte).u & GST_PDE_PG_MASK)
 # define GST_GET_PDE_GCPHYS(Pde)                ((Pde).u & GST_PDE_PG_MASK)
-# define GST_GET_BIG_PDE_GCPHYS(pVM, Pde)       pgmGstGet4MBPhysPage(&(pVM)->pgm.s, Pde)
+# define GST_GET_BIG_PDE_GCPHYS(pVM, Pde)       pgmGstGet4MBPhysPage((pVM), Pde)
 # define GST_GET_PDE_SHW_FLAGS(pVCpu, Pde)      ((Pde).u & (X86_PDE_P | X86_PDE_RW | X86_PDE_US | X86_PDE_A))
 # define GST_GET_BIG_PDE_SHW_FLAGS(pVCpu, Pde) \
Index: trunk/src/VBox/VMM/include/PGMInline.h
===================================================================
--- trunk/src/VBox/VMM/include/PGMInline.h	(revision 36857)
+++ trunk/src/VBox/VMM/include/PGMInline.h	(revision 36891)
@@ -46,9 +46,4 @@
  */
 
-/** @todo Split out all the inline stuff into a separate file.  Then we can
- *        include it later when VM and VMCPU are defined and so avoid all that
- *        &pVM->pgm.s and &pVCpu->pgm.s stuff.  It also chops ~1600 lines off
- *        this file and will make it somewhat easier to navigate... */
-
 /**
  * Gets the PGMRAMRANGE structure for a guest page.
@@ -57,13 +52,21 @@
  * @returns NULL on a VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS condition.
  *
- * @param   pPGM        PGM handle.
+ * @param   pVM         The VM handle.
  * @param   GCPhys      The GC physical address.
  */
-DECLINLINE(PPGMRAMRANGE) pgmPhysGetRange(PPGM pPGM, RTGCPHYS GCPhys)
-{
+DECLINLINE(PPGMRAMRANGE) pgmPhysGetRange(PVM pVM, RTGCPHYS GCPhys)
+{
+#ifdef PGM_USE_RAMRANGE_TLB
+    PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)];
+    if (!pRam || GCPhys - pRam->GCPhys >= pRam->cb)
+        pRam = pgmPhysGetRangeSlow(pVM, GCPhys);
+    STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,RamRangeTlbHits));
+    return pRam;
+
+#else
     /*
      * Optimize for the first range.
      */
-    PPGMRAMRANGE pRam = pPGM->CTX_SUFF(pRamRanges);
+    PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangesX);
     RTGCPHYS off = GCPhys - pRam->GCPhys;
     if (RT_UNLIKELY(off >= pRam->cb))
@@ -78,5 +81,36 @@
     }
     return pRam;
-}
+#endif
+}
+
+
+/**
+ * Gets the PGMRAMRANGE structure for a guest page, if unassigned get the ram
+ * range above it.
+ *
+ * @returns Pointer to the RAM range on success.
+ * @returns NULL if the address is located after the last range.
+ *
+ * @param   pVM         The VM handle.
+ * @param   GCPhys      The GC physical address.
+ */
+DECLINLINE(PPGMRAMRANGE) pgmPhysGetRangeAtOrAbove(PVM pVM, RTGCPHYS GCPhys)
+{
+#ifdef PGM_USE_RAMRANGE_TLB
+    PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)];
+    if (   !pRam
+        || (GCPhys - pRam->GCPhys) >= pRam->cb)
+        return pgmPhysGetRangeAtOrAboveSlow(pVM, GCPhys);
+    STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,RamRangeTlbHits));
+    return pRam;
+
+#else
+    PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangesX);
+    while (pRam && GCPhys > pRam->GCPhysLast)
+        pRam = pRam->CTX_SUFF(pNext);
+    return pRam;
+#endif
+}
+
 
 
@@ -87,13 +121,23 @@
  * @returns NULL on a VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS condition.
  *
- * @param   pPGM        PGM handle.
+ * @param   pVM         The VM handle.
  * @param   GCPhys      The GC physical address.
  */
-DECLINLINE(PPGMPAGE) pgmPhysGetPage(PPGM pPGM, RTGCPHYS GCPhys)
-{
+DECLINLINE(PPGMPAGE) pgmPhysGetPage(PVM pVM, RTGCPHYS GCPhys)
+{
+#ifdef PGM_USE_RAMRANGE_TLB
+    PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)];
+    RTGCPHYS off;
+    if (   !pRam
+        || (off = GCPhys - pRam->GCPhys) >= pRam->cb)
+        return pgmPhysGetPageSlow(pVM, GCPhys);
+    STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,RamRangeTlbHits));
+    return &pRam->aPages[off >> PAGE_SHIFT];
+
+#else
     /*
      * Optimize for the first range.
      */
-    PPGMRAMRANGE pRam = pPGM->CTX_SUFF(pRamRanges);
+    PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangesX);
     RTGCPHYS off = GCPhys - pRam->GCPhys;
     if (RT_UNLIKELY(off >= pRam->cb))
@@ -108,4 +152,5 @@
     }
     return &pRam->aPages[off >> PAGE_SHIFT];
+#endif
 }
 
@@ -120,14 +165,25 @@
  * @retval  VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if the address isn't valid.
  *
- * @param   pPGM        PGM handle.
+ * @param   pVM         The VM handle.
  * @param   GCPhys      The GC physical address.
  * @param   ppPage      Where to store the page pointer on success.
  */
-DECLINLINE(int) pgmPhysGetPageEx(PPGM pPGM, RTGCPHYS GCPhys, PPPGMPAGE ppPage)
-{
+DECLINLINE(int) pgmPhysGetPageEx(PVM pVM, RTGCPHYS GCPhys, PPPGMPAGE ppPage)
+{
+#ifdef PGM_USE_RAMRANGE_TLB
+    PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)];
+    RTGCPHYS off;
+    if (   !pRam
+        || (off = GCPhys - pRam->GCPhys) >= pRam->cb)
+        return pgmPhysGetPageExSlow(pVM, GCPhys, ppPage);
+    *ppPage = &pRam->aPages[(GCPhys - pRam->GCPhys) >> PAGE_SHIFT];
+    STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,RamRangeTlbHits));
+    return VINF_SUCCESS;
+
+#else
     /*
      * Optimize for the first range.
      */
-    PPGMRAMRANGE pRam = pPGM->CTX_SUFF(pRamRanges);
+    PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangesX);
     RTGCPHYS off = GCPhys - pRam->GCPhys;
     if (RT_UNLIKELY(off >= pRam->cb))
@@ -146,4 +202,5 @@
     *ppPage = &pRam->aPages[off >> PAGE_SHIFT];
     return VINF_SUCCESS;
+#endif
 }
 
@@ -160,5 +217,5 @@
  * @retval  VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if the address isn't valid.
  *
- * @param   pPGM        PGM handle.
+ * @param   pVM         The VM handle.
  * @param   GCPhys      The GC physical address.
  * @param   ppPage      Where to store the page pointer on success.
@@ -166,5 +223,5 @@
  *                      The caller initializes this to NULL before the call.
  */
-DECLINLINE(int) pgmPhysGetPageWithHintEx(PPGM pPGM, RTGCPHYS GCPhys, PPPGMPAGE ppPage, PPGMRAMRANGE *ppRamHint)
+DECLINLINE(int) pgmPhysGetPageWithHintEx(PVM pVM, RTGCPHYS GCPhys, PPPGMPAGE ppPage, PPGMRAMRANGE *ppRamHint)
 {
     RTGCPHYS off;
@@ -173,5 +230,13 @@
         ||  RT_UNLIKELY((off = GCPhys - pRam->GCPhys) >= pRam->cb))
     {
-        pRam = pPGM->CTX_SUFF(pRamRanges);
+#ifdef PGM_USE_RAMRANGE_TLB
+        pRam = pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)];
+        if (   !pRam
+            || (off = GCPhys - pRam->GCPhys) >= pRam->cb)
+            return pgmPhysGetPageAndRangeExSlow(pVM, GCPhys, ppPage, ppRamHint);
+        STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,RamRangeTlbHits));
+
+#else
+        pRam = pVM->pgm.s.CTX_SUFF(pRamRangesX);
         off = GCPhys - pRam->GCPhys;
         if (RT_UNLIKELY(off >= pRam->cb))
@@ -188,4 +253,5 @@
             } while (off >= pRam->cb);
         }
+#endif
         *ppRamHint = pRam;
     }
@@ -201,47 +267,24 @@
  * @returns NULL on a VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS condition.
  *
- * @param   pPGM        PGM handle.
+ * @param   pVM         The VM handle.
  * @param   GCPhys      The GC physical address.
- * @param   ppRam       Where to store the pointer to the PGMRAMRANGE.
- */
-DECLINLINE(PPGMPAGE) pgmPhysGetPageAndRange(PPGM pPGM, RTGCPHYS GCPhys, PPGMRAMRANGE *ppRam)
-{
+ * @param   ppPage      Where to store the pointer to the PGMPAGE structure.
+ * @param   ppRam       Where to store the pointer to the PGMRAMRANGE structure.
+ */
+DECLINLINE(int) pgmPhysGetPageAndRangeEx(PVM pVM, RTGCPHYS GCPhys, PPPGMPAGE ppPage, PPGMRAMRANGE *ppRam)
+{
+#ifdef PGM_USE_RAMRANGE_TLB
+    PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)];
+    RTGCPHYS off;
+    if (   !pRam
+        || (off = GCPhys - pRam->GCPhys) >= pRam->cb)
+        return pgmPhysGetPageAndRangeExSlow(pVM, GCPhys, ppPage, ppRam);
+    STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,RamRangeTlbHits));
+
+#else
     /*
      * Optimize for the first range.
      */
-    PPGMRAMRANGE pRam = pPGM->CTX_SUFF(pRamRanges);
-    RTGCPHYS off = GCPhys - pRam->GCPhys;
-    if (RT_UNLIKELY(off >= pRam->cb))
-    {
-        do
-        {
-            pRam = pRam->CTX_SUFF(pNext);
-            if (RT_UNLIKELY(!pRam))
-                return NULL;
-            off = GCPhys - pRam->GCPhys;
-        } while (off >= pRam->cb);
-    }
-    *ppRam = pRam;
-    return &pRam->aPages[off >> PAGE_SHIFT];
-}
-
-
-/**
- * Gets the PGMPAGE structure for a guest page together with the PGMRAMRANGE.
- *
- * @returns Pointer to the page on success.
- * @returns NULL on a VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS condition.
- *
- * @param   pPGM        PGM handle.
- * @param   GCPhys      The GC physical address.
- * @param   ppPage      Where to store the pointer to the PGMPAGE structure.
- * @param   ppRam       Where to store the pointer to the PGMRAMRANGE structure.
- */
-DECLINLINE(int) pgmPhysGetPageAndRangeEx(PPGM pPGM, RTGCPHYS GCPhys, PPPGMPAGE ppPage, PPGMRAMRANGE *ppRam)
-{
-    /*
-     * Optimize for the first range.
-     */
-    PPGMRAMRANGE pRam = pPGM->CTX_SUFF(pRamRanges);
+    PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRangesX);
     RTGCPHYS off = GCPhys - pRam->GCPhys;
     if (RT_UNLIKELY(off >= pRam->cb))
@@ -259,4 +302,5 @@
         } while (off >= pRam->cb);
     }
+#endif
     *ppRam = pRam;
     *ppPage = &pRam->aPages[off >> PAGE_SHIFT];
@@ -269,5 +313,5 @@
  *
  * @returns VBox status.
- * @param   pPGM        PGM handle.
+ * @param   pVM         The VM handle.
  * @param   GCPhys      The GC physical address.
  * @param   pHCPhys     Where to store the corresponding HC physical address.
@@ -276,8 +320,8 @@
  *              Avoid when writing new code!
  */
-DECLINLINE(int) pgmRamGCPhys2HCPhys(PPGM pPGM, RTGCPHYS GCPhys, PRTHCPHYS pHCPhys)
+DECLINLINE(int) pgmRamGCPhys2HCPhys(PVM pVM, RTGCPHYS GCPhys, PRTHCPHYS pHCPhys)
 {
     PPGMPAGE pPage;
-    int rc = pgmPhysGetPageEx(pPGM, GCPhys, &pPage);
+    int rc = pgmPhysGetPageEx(pVM, GCPhys, &pPage);
     if (RT_FAILURE(rc))
         return rc;
@@ -344,8 +388,17 @@
      * Get the ram range.
      */
-    PPGMRAMRANGE    pRam = pVM->pgm.s.CTX_SUFF(pRamRanges);
+#ifdef PGM_USE_RAMRANGE_TLB
+    PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)];
+    RTGCPHYS off;
+    if (   !pRam
+        || (off = GCPhys - pRam->GCPhys) >= pRam->cb
+        /** @todo   || page state stuff */
+       )
+#else
+    PPGMRAMRANGE    pRam = pVM->pgm.s.CTX_SUFF(pRamRangesX);
     RTGCPHYS        off  = GCPhys - pRam->GCPhys;
     if (RT_UNLIKELY(off >= pRam->cb
         /** @todo   || page state stuff */))
+#endif
     {
         /* This case is not counted into StatRZDynMapGCPageInl. */
@@ -418,8 +471,17 @@
      */
     PVM             pVM  = pVCpu->CTX_SUFF(pVM);
-    PPGMRAMRANGE    pRam = pVM->pgm.s.CTX_SUFF(pRamRanges);
+#ifdef PGM_USE_RAMRANGE_TLB
+    PPGMRAMRANGE    pRam = pVM->pgm.s.CTX_SUFF(apRamRangesTlb)[PGM_RAMRANGE_TLB_IDX(GCPhys)];
+    RTGCPHYS        off;
+    if (   !pRam
+        || (off = GCPhys - pRam->GCPhys) >= pRam->cb
+        /** @todo   || page state stuff */
+       )
+#else
+    PPGMRAMRANGE    pRam = pVM->pgm.s.CTX_SUFF(pRamRangesX);
     RTGCPHYS        off  = GCPhys - pRam->GCPhys;
     if (RT_UNLIKELY(off >= pRam->cb
         /** @todo   || page state stuff */))
+#endif
     {
         /* This case is not counted into StatRZDynMapGCPageInl. */
@@ -513,19 +575,19 @@
  * @retval  VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if it's not a valid physical address.
  *
- * @param   pPGM        The PGM instance handle.
+ * @param   pVM         The VM handle.
  * @param   GCPhys      The address of the guest page.
  * @param   ppTlbe      Where to store the pointer to the TLB entry.
  */
-DECLINLINE(int) pgmPhysPageQueryTlbe(PPGM pPGM, RTGCPHYS GCPhys, PPPGMPAGEMAPTLBE ppTlbe)
+DECLINLINE(int) pgmPhysPageQueryTlbe(PVM pVM, RTGCPHYS GCPhys, PPPGMPAGEMAPTLBE ppTlbe)
 {
     int rc;
-    PPGMPAGEMAPTLBE pTlbe = &pPGM->CTXSUFF(PhysTlb).aEntries[PGM_PAGEMAPTLB_IDX(GCPhys)];
+    PPGMPAGEMAPTLBE pTlbe = &pVM->pgm.s.CTXSUFF(PhysTlb).aEntries[PGM_PAGEMAPTLB_IDX(GCPhys)];
     if (pTlbe->GCPhys == (GCPhys & X86_PTE_PAE_PG_MASK))
     {
-        STAM_COUNTER_INC(&pPGM->CTX_SUFF(pStats)->CTX_MID_Z(Stat,PageMapTlbHits));
+        STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,PageMapTlbHits));
         rc = VINF_SUCCESS;
     }
     else
-        rc = pgmPhysPageLoadIntoTlb(pPGM, GCPhys);
+        rc = pgmPhysPageLoadIntoTlb(pVM, GCPhys);
     *ppTlbe = pTlbe;
     return rc;
@@ -541,5 +603,5 @@
  * @retval  VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if it's not a valid physical address.
  *
- * @param   pPGM        The PGM instance handle.
+ * @param   pVM         The VM handle.
  * @param   pPage       Pointer to the PGMPAGE structure corresponding to
  *                      GCPhys.
@@ -547,15 +609,15 @@
  * @param   ppTlbe      Where to store the pointer to the TLB entry.
  */
-DECLINLINE(int) pgmPhysPageQueryTlbeWithPage(PPGM pPGM, PPGMPAGE pPage, RTGCPHYS GCPhys, PPPGMPAGEMAPTLBE ppTlbe)
+DECLINLINE(int) pgmPhysPageQueryTlbeWithPage(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, PPPGMPAGEMAPTLBE ppTlbe)
 {
     int rc;
-    PPGMPAGEMAPTLBE pTlbe = &pPGM->CTXSUFF(PhysTlb).aEntries[PGM_PAGEMAPTLB_IDX(GCPhys)];
+    PPGMPAGEMAPTLBE pTlbe = &pVM->pgm.s.CTXSUFF(PhysTlb).aEntries[PGM_PAGEMAPTLB_IDX(GCPhys)];
     if (pTlbe->GCPhys == (GCPhys & X86_PTE_PAE_PG_MASK))
     {
-        STAM_COUNTER_INC(&pPGM->CTX_SUFF(pStats)->CTX_MID_Z(Stat,PageMapTlbHits));
+        STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,PageMapTlbHits));
         rc = VINF_SUCCESS;
     }
     else
-        rc = pgmPhysPageLoadIntoTlbWithPage(pPGM, pPage, GCPhys);
+        rc = pgmPhysPageLoadIntoTlbWithPage(pVM, pPage, GCPhys);
     *ppTlbe = pTlbe;
     return rc;
@@ -567,9 +629,9 @@
 /**
  * Enables write monitoring for an allocated page.
- *  
- * The caller is responsible for updating the shadow page tables. 
- *  
+ *
+ * The caller is responsible for updating the shadow page tables.
+ *
  * @param   pVM         The VM handle.
- * @param   pPage       The page to write monitor. 
+ * @param   pPage       The page to write monitor.
  * @param   GCPhysPage  The address of the page.
  */
@@ -585,5 +647,5 @@
     if (PGM_PAGE_GET_PDE_TYPE(pPage) == PGM_PAGE_PDE_TYPE_PDE)
     {
-        PPGMPAGE pFirstPage = pgmPhysGetPage(&pVM->pgm.s, GCPhysPage & X86_PDE2M_PAE_PG_MASK);
+        PPGMPAGE pFirstPage = pgmPhysGetPage(pVM, GCPhysPage & X86_PDE2M_PAE_PG_MASK);
         AssertFatal(pFirstPage);
         if (PGM_PAGE_GET_PDE_TYPE(pFirstPage) == PGM_PAGE_PDE_TYPE_PDE)
@@ -638,13 +700,13 @@
  *
  * @returns guest physical address
- * @param   pPGM        Pointer to the PGM instance data.
+ * @param   pVM         The VM handle.
  * @param   Pde         Guest Pde
  */
-DECLINLINE(RTGCPHYS) pgmGstGet4MBPhysPage(PPGM pPGM, X86PDE Pde)
+DECLINLINE(RTGCPHYS) pgmGstGet4MBPhysPage(PVM pVM, X86PDE Pde)
 {
     RTGCPHYS GCPhys = Pde.u & X86_PDE4M_PG_MASK;
     GCPhys |= (RTGCPHYS)Pde.b.u8PageNoHigh << 32;
 
-    return GCPhys & pPGM->GCPhys4MBPSEMask;
+    return GCPhys & pVM->pgm.s.GCPhys4MBPSEMask;
 }
 
@@ -1307,14 +1369,14 @@
 
 /**
- * Clears one physical page of a virtual handler
- *
- * @param   pPGM    Pointer to the PGM instance.
- * @param   pCur    Virtual handler structure
- * @param   iPage   Physical page index
+ * Clears one physical page of a virtual handler.
+ *
+ * @param   pVM         The VM handle.
+ * @param   pCur        Virtual handler structure.
+ * @param   iPage       Physical page index.
  *
  * @remark  Only used when PGM_SYNC_UPDATE_PAGE_BIT_VIRTUAL is being set, so no
  *          need to care about other handlers in the same page.
  */
-DECLINLINE(void) pgmHandlerVirtualClearPage(PPGM pPGM, PPGMVIRTHANDLER pCur, unsigned iPage)
+DECLINLINE(void) pgmHandlerVirtualClearPage(PVM pVM, PPGMVIRTHANDLER pCur, unsigned iPage)
 {
     const PPGMPHYS2VIRTHANDLER pPhys2Virt = &pCur->aPhysToVirt[iPage];
@@ -1331,5 +1393,5 @@
     {
         /* We're the head of the alias chain. */
-        PPGMPHYS2VIRTHANDLER pRemove = (PPGMPHYS2VIRTHANDLER)RTAvlroGCPhysRemove(&pPGM->CTX_SUFF(pTrees)->PhysToVirtHandlers, pPhys2Virt->Core.Key); NOREF(pRemove);
+        PPGMPHYS2VIRTHANDLER pRemove = (PPGMPHYS2VIRTHANDLER)RTAvlroGCPhysRemove(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysToVirtHandlers, pPhys2Virt->Core.Key); NOREF(pRemove);
 #ifdef VBOX_STRICT_PGM_HANDLER_VIRTUAL
         AssertReleaseMsg(pRemove != NULL,
@@ -1352,5 +1414,5 @@
 #endif
             pNext->offNextAlias |= PGMPHYS2VIRTHANDLER_IS_HEAD;
-            bool fRc = RTAvlroGCPhysInsert(&pPGM->CTX_SUFF(pTrees)->PhysToVirtHandlers, &pNext->Core);
+            bool fRc = RTAvlroGCPhysInsert(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysToVirtHandlers, &pNext->Core);
             AssertRelease(fRc);
         }
@@ -1359,5 +1421,5 @@
     {
         /* Locate the previous node in the alias chain. */
-        PPGMPHYS2VIRTHANDLER pPrev = (PPGMPHYS2VIRTHANDLER)RTAvlroGCPhysGet(&pPGM->CTX_SUFF(pTrees)->PhysToVirtHandlers, pPhys2Virt->Core.Key);
+        PPGMPHYS2VIRTHANDLER pPrev = (PPGMPHYS2VIRTHANDLER)RTAvlroGCPhysGet(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysToVirtHandlers, pPhys2Virt->Core.Key);
 #ifdef VBOX_STRICT_PGM_HANDLER_VIRTUAL
         AssertReleaseMsg(pPrev != pPhys2Virt,
@@ -1405,5 +1467,5 @@
      * Clear the ram flags for this page.
      */
-    PPGMPAGE pPage = pgmPhysGetPage(pPGM, pPhys2Virt->Core.Key);
+    PPGMPAGE pPage = pgmPhysGetPage(pVM, pPhys2Virt->Core.Key);
     AssertReturnVoid(pPage);
     PGM_PAGE_SET_HNDL_VIRT_STATE(pPage, PGM_PAGE_HNDL_VIRT_STATE_NONE);
@@ -1521,5 +1583,5 @@
  * @param   pPage       PGM pool page
  */
-DECLINLINE(bool) pgmPoolIsPageLocked(PPGM pPGM, PPGMPOOLPAGE pPage)
+DECLINLINE(bool) pgmPoolIsPageLocked(PPGMPOOLPAGE pPage)
 {
     if (pPage->cLocked)
@@ -1540,12 +1602,12 @@
  * @param   pVM         VM handle.
  */
-DECL_FORCE_INLINE(bool) pgmMapAreMappingsEnabled(PPGM pPGM)
+DECL_FORCE_INLINE(bool) pgmMapAreMappingsEnabled(PVM pVM)
 {
 #ifdef PGM_WITHOUT_MAPPINGS
     /* There are no mappings in VT-x and AMD-V mode. */
-    Assert(pPGM->fMappingsDisabled);
+    Assert(pVM->pgm.s.fMappingsDisabled);
     return false;
 #else
-    return !pPGM->fMappingsDisabled;
+    return !pVM->pgm.s.fMappingsDisabled;
 #endif
 }
@@ -1558,13 +1620,13 @@
  * @param   pVM         The VM handle.
  */
-DECL_FORCE_INLINE(bool) pgmMapAreMappingsFloating(PPGM pPGM)
+DECL_FORCE_INLINE(bool) pgmMapAreMappingsFloating(PVM pVM)
 {
 #ifdef PGM_WITHOUT_MAPPINGS
     /* There are no mappings in VT-x and AMD-V mode. */
-    Assert(pPGM->fMappingsDisabled);
+    Assert(pVM->pgm.s.fMappingsDisabled);
     return false;
 #else
-    return !pPGM->fMappingsDisabled
-        && !pPGM->fMappingsFixed;
+    return !pVM->pgm.s.fMappingsDisabled
+        && !pVM->pgm.s.fMappingsFixed;
 #endif
 }
Index: trunk/src/VBox/VMM/include/PGMInternal.h
===================================================================
--- trunk/src/VBox/VMM/include/PGMInternal.h	(revision 36857)
+++ trunk/src/VBox/VMM/include/PGMInternal.h	(revision 36891)
@@ -1326,4 +1326,19 @@
 #define PGM_RAM_RANGE_IS_AD_HOC(pRam) \
     (!!( (pRam)->fFlags & (PGM_RAM_RANGE_FLAGS_AD_HOC_ROM | PGM_RAM_RANGE_FLAGS_AD_HOC_MMIO | PGM_RAM_RANGE_FLAGS_AD_HOC_MMIO2) ) )
+
+/* enable the tlbs. */
+//#define PGM_USE_RAMRANGE_TLB
+/** The number of entries in the RAM range TLBs (there is one for each
+ *  context).  Must be a power of two. */
+#define PGM_RAMRANGE_TLB_ENTRIES            8
+
+/**
+ * Calculates the RAM range TLB index for the physical address.
+ *
+ * @returns RAM range TLB index.
+ * @param   GCPhys      The guest physical address.
+ */
+#define PGM_RAMRANGE_TLB_IDX(a_GCPhys)      ( ((a_GCPhys) >> 20) & (PGM_RAMRANGE_TLB_ENTRIES - 1) )
+
 
 
@@ -2792,4 +2807,8 @@
     STAMCOUNTER StatR3PageMapTlbHits;               /**< R3: Ring-3/0 page mapper TLB hits. */
     STAMCOUNTER StatR3PageMapTlbMisses;             /**< R3: Ring-3/0 page mapper TLB misses. */
+    STAMCOUNTER StatRZRamRangeTlbHits;              /**< RC/R0: RAM range TLB hits. */
+    STAMCOUNTER StatRZRamRangeTlbMisses;            /**< RC/R0: RAM range TLB misses. */
+    STAMCOUNTER StatR3RamRangeTlbHits;              /**< R3: RAM range TLB hits. */
+    STAMCOUNTER StatR3RamRangeTlbMisses;            /**< R3: RAM range TLB misses. */
     STAMPROFILE StatRZSyncCR3HandlerVirtualReset;   /**< RC/R0: Profiling of the virtual handler resets. */
     STAMPROFILE StatRZSyncCR3HandlerVirtualUpdate;  /**< RC/R0: Profiling of the virtual handler updates. */
@@ -2946,5 +2965,9 @@
     /** Pointer to the list of RAM ranges (Phys GC -> Phys HC conversion) - for R3.
      * This is sorted by physical address and contains no overlapping ranges. */
-    R3PTRTYPE(PPGMRAMRANGE)         pRamRangesR3;
+    R3PTRTYPE(PPGMRAMRANGE)         pRamRangesXR3;
+#ifdef PGM_USE_RAMRANGE_TLB
+    /** Ram range TLB for R3. */
+    R3PTRTYPE(PPGMRAMRANGE)         apRamRangesTlbR3[PGM_RAMRANGE_TLB_ENTRIES];
+#endif
     /** PGM offset based trees - R3 Ptr. */
     R3PTRTYPE(PPGMTREES)            pTreesR3;
@@ -2967,7 +2990,10 @@
     /*RTR3PTR                         R3PtrAlignment0;*/
 
-
-    /** R0 pointer corresponding to PGM::pRamRangesR3. */
-    R0PTRTYPE(PPGMRAMRANGE)         pRamRangesR0;
+    /** R0 pointer corresponding to PGM::pRamRangesXR3. */
+    R0PTRTYPE(PPGMRAMRANGE)         pRamRangesXR0;
+#ifdef PGM_USE_RAMRANGE_TLB
+    /** Ram range TLB for R0. */
+    R0PTRTYPE(PPGMRAMRANGE)         apRamRangesTlbR0[PGM_RAMRANGE_TLB_ENTRIES];
+#endif
     /** PGM offset based trees - R0 Ptr. */
     R0PTRTYPE(PPGMTREES)            pTreesR0;
@@ -2984,6 +3010,10 @@
 
 
-    /** RC pointer corresponding to PGM::pRamRangesR3. */
-    RCPTRTYPE(PPGMRAMRANGE)         pRamRangesRC;
+    /** RC pointer corresponding to PGM::pRamRangesXR3. */
+    RCPTRTYPE(PPGMRAMRANGE)         pRamRangesXRC;
+#ifdef PGM_USE_RAMRANGE_TLB
+    /** Ram range TLB for RC. */
+    RCPTRTYPE(PPGMRAMRANGE)         apRamRangesTlbRC[PGM_RAMRANGE_TLB_ENTRIES];
+#endif
     /** PGM offset based trees - RC Ptr. */
     RCPTRTYPE(PPGMTREES)            pTreesRC;
@@ -3771,6 +3801,6 @@
 int             pgmPhysAllocLargePage(PVM pVM, RTGCPHYS GCPhys);
 int             pgmPhysRecheckLargePage(PVM pVM, RTGCPHYS GCPhys, PPGMPAGE pLargePage);
-int             pgmPhysPageLoadIntoTlb(PPGM pPGM, RTGCPHYS GCPhys);
-int             pgmPhysPageLoadIntoTlbWithPage(PPGM pPGM, PPGMPAGE pPage, RTGCPHYS GCPhys);
+int             pgmPhysPageLoadIntoTlb(PVM pVM, RTGCPHYS GCPhys);
+int             pgmPhysPageLoadIntoTlbWithPage(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys);
 void            pgmPhysPageMakeWriteMonitoredWritable(PVM pVM, PPGMPAGE pPage);
 int             pgmPhysPageMakeWritable(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys);
@@ -3784,4 +3814,10 @@
 VMMDECL(int)    pgmPhysRomWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
 int             pgmPhysFreePage(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t *pcPendingPages, PPGMPAGE pPage, RTGCPHYS GCPhys);
+void            pgmPhysInvalidRamRangeTlbs(PVM pVM);
+PPGMRAMRANGE    pgmPhysGetRangeSlow(PVM pVM, RTGCPHYS GCPhys);
+PPGMRAMRANGE    pgmPhysGetRangeAtOrAboveSlow(PVM pVM, RTGCPHYS GCPhys);
+PPGMPAGE        pgmPhysGetPageSlow(PVM pVM, RTGCPHYS GCPhys);
+int             pgmPhysGetPageExSlow(PVM pVM, RTGCPHYS GCPhys, PPPGMPAGE ppPage);
+int             pgmPhysGetPageAndRangeExSlow(PVM pVM, RTGCPHYS GCPhys, PPPGMPAGE ppPage, PPGMRAMRANGE *ppRam);
 
 #ifdef IN_RING3
