Index: /trunk/src/VBox/VMM/PGMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/PGMInternal.h	(revision 30835)
+++ /trunk/src/VBox/VMM/PGMInternal.h	(revision 30836)
@@ -1401,5 +1401,4 @@
  *
  * The primary tree (Core) uses the chunk id as key.
- * The secondary tree (AgeCore) is used for ageing and uses ageing sequence number as key.
  */
 typedef struct PGMCHUNKR3MAP
@@ -1407,6 +1406,4 @@
     /** The key is the chunk id. */
     AVLU32NODECORE                      Core;
-    /** The key is the ageing sequence number. */
-    AVLLU32NODECORE                     AgeCore;
     /** The current age thingy. */
     uint32_t                            iAge;
@@ -2670,6 +2667,4 @@
         R3R0PTRTYPE(PAVLU32NODECORE) pTree;
 #endif
-        /** The chunk age tree, ordered by ageing sequence number. */
-        R3PTRTYPE(PAVLLU32NODECORE) pAgeTree;
         /** The chunk mapping TLB. */
         PGMCHUNKR3MAPTLB            Tlb;
Index: /trunk/src/VBox/VMM/PGMPhys.cpp
===================================================================
--- /trunk/src/VBox/VMM/PGMPhys.cpp	(revision 30835)
+++ /trunk/src/VBox/VMM/PGMPhys.cpp	(revision 30836)
@@ -3206,10 +3206,4 @@
     else /* iAge = 0 */
         pChunk->iAge = 4;
-
-    /* reinsert */
-    PVM pVM = (PVM)pvUser;
-    RTAvllU32Remove(&pVM->pgm.s.ChunkR3Map.pAgeTree, pChunk->AgeCore.Key);
-    pChunk->AgeCore.Key = pChunk->iAge;
-    RTAvllU32Insert(&pVM->pgm.s.ChunkR3Map.pAgeTree, &pChunk->AgeCore);
     return 0;
 }
@@ -3226,9 +3220,6 @@
     {
         PVM pVM = (PVM)pvUser;
-        RTAvllU32Remove(&pVM->pgm.s.ChunkR3Map.pAgeTree, pChunk->AgeCore.Key);
-        pChunk->AgeCore.Key = pChunk->iAge = pVM->pgm.s.ChunkR3Map.iNow;
-        RTAvllU32Insert(&pVM->pgm.s.ChunkR3Map.pAgeTree, &pChunk->AgeCore);
-    }
-
+        pChunk->iAge = pVM->pgm.s.ChunkR3Map.iNow;
+    }
     return 0;
 }
@@ -3263,4 +3254,5 @@
     PVM                 pVM;            /**< The VM handle. */
     PPGMCHUNKR3MAP      pChunk;         /**< The chunk to unmap. */
+    int32_t             iLastAge;       /**< Highest age found so far. */
 } PGMR3PHYSCHUNKUNMAPCB, *PPGMR3PHYSCHUNKUNMAPCB;
 
@@ -3273,11 +3265,14 @@
 {
     PPGMCHUNKR3MAP pChunk = (PPGMCHUNKR3MAP)((uint8_t *)pNode - RT_OFFSETOF(PGMCHUNKR3MAP, AgeCore));
+    PPGMR3PHYSCHUNKUNMAPCB pArg = (PPGMR3PHYSCHUNKUNMAPCB)pvUser;
+
     if (    pChunk->iAge
-        &&  !pChunk->cRefs)
+        &&  !pChunk->cRefs
+        &&  pArg->iLastAge < pChunk->iAge)
     {
         /*
          * Check that it's not in any of the TLBs.
          */
-        PVM pVM = ((PPGMR3PHYSCHUNKUNMAPCB)pvUser)->pVM;
+        PVM pVM = pArg->pVM;
         for (unsigned i = 0; i < RT_ELEMENTS(pVM->pgm.s.ChunkR3Map.Tlb.aEntries); i++)
             if (pVM->pgm.s.ChunkR3Map.Tlb.aEntries[i].pChunk == pChunk)
@@ -3295,6 +3290,6 @@
         if (pChunk)
         {
-            ((PPGMR3PHYSCHUNKUNMAPCB)pvUser)->pChunk = pChunk;
-            return 1; /* done */
+            pArg->pChunk = pChunk;
+            pArg->iLastAge = pChunk->iAge;
         }
     }
@@ -3326,12 +3321,12 @@
      */
     PGMR3PHYSCHUNKUNMAPCB Args;
-    Args.pVM = pVM;
-    Args.pChunk = NULL;
-    if (RTAvllU32DoWithAll(&pVM->pgm.s.ChunkR3Map.pAgeTree, true /*fFromLeft*/, pgmR3PhysChunkUnmapCandidateCallback, &Args))
-    {
-        Assert(Args.pChunk);
-        if (Args.pChunk)
-            return Args.pChunk->Core.Key;
-    }
+    Args.pVM      = pVM;
+    Args.pChunk   = NULL;
+    Args.iLastAge = 0;
+    RTAvlU32DoWithAll(&pVM->pgm.s.ChunkR3Map.pTree, true /*fFromLeft*/, pgmR3PhysChunkUnmapCandidateCallback, &Args);
+    Assert(Args.pChunk);
+    if (Args.pChunk)
+        return Args.pChunk->Core.Key;
+
     return INT32_MAX;
 }
@@ -3370,48 +3365,51 @@
         Req.idChunkUnmap = pgmR3PhysChunkFindUnmapCandidate(pVM);
 
-        rc = VMMR3CallR0(pVM, VMMR0_DO_GMM_MAP_UNMAP_CHUNK, 0, &Req.Hdr);
-        if (RT_SUCCESS(rc))
-        {
-            /* remove the unmapped one. */
-            PPGMCHUNKR3MAP pUnmappedChunk = (PPGMCHUNKR3MAP)RTAvlU32Remove(&pVM->pgm.s.ChunkR3Map.pTree, Req.idChunkUnmap);
-            AssertRelease(pUnmappedChunk);
-            pUnmappedChunk->pv = NULL;
-            pUnmappedChunk->Core.Key = UINT32_MAX;
+        if (Req.idChunkUnmap != INT32_MAX)
+        {
+            rc = VMMR3CallR0(pVM, VMMR0_DO_GMM_MAP_UNMAP_CHUNK, 0, &Req.Hdr);
+            if (RT_SUCCESS(rc))
+            {
+                /* remove the unmapped one. */
+                PPGMCHUNKR3MAP pUnmappedChunk = (PPGMCHUNKR3MAP)RTAvlU32Remove(&pVM->pgm.s.ChunkR3Map.pTree, Req.idChunkUnmap);
+                AssertRelease(pUnmappedChunk);
+                pUnmappedChunk->pv = NULL;
+                pUnmappedChunk->Core.Key = UINT32_MAX;
 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
-            MMR3HeapFree(pUnmappedChunk);
+                MMR3HeapFree(pUnmappedChunk);
 #else
-            MMR3UkHeapFree(pVM, pUnmappedChunk, MM_TAG_PGM_CHUNK_MAPPING);
+                MMR3UkHeapFree(pVM, pUnmappedChunk, MM_TAG_PGM_CHUNK_MAPPING);
 #endif
-            pVM->pgm.s.ChunkR3Map.c--;
-            pVM->pgm.s.cUnmappedChunks++;
-
-            /* Flush dangling PGM pointers (R3 & R0 ptrs to GC physical addresses) */
-            /* todo: we should not flush chunks which include cr3 mappings. */
-            for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
-            {
-                PPGMCPU pPGM = &pVM->aCpus[idCpu].pgm.s;
-
-                pPGM->pGst32BitPdR3    = NULL;
-                pPGM->pGstPaePdptR3    = NULL;
-                pPGM->pGstAmd64Pml4R3  = NULL;
+                pVM->pgm.s.ChunkR3Map.c--;
+                pVM->pgm.s.cUnmappedChunks++;
+
+                /* Flush dangling PGM pointers (R3 & R0 ptrs to GC physical addresses) */
+                /* todo: we should not flush chunks which include cr3 mappings. */
+                for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
+                {
+                    PPGMCPU pPGM = &pVM->aCpus[idCpu].pgm.s;
+
+                    pPGM->pGst32BitPdR3    = NULL;
+                    pPGM->pGstPaePdptR3    = NULL;
+                    pPGM->pGstAmd64Pml4R3  = NULL;
 #ifndef VBOX_WITH_2X_4GB_ADDR_SPACE
-                pPGM->pGst32BitPdR0    = NIL_RTR0PTR;
-                pPGM->pGstPaePdptR0    = NIL_RTR0PTR;
-                pPGM->pGstAmd64Pml4R0  = NIL_RTR0PTR;
+                    pPGM->pGst32BitPdR0    = NIL_RTR0PTR;
+                    pPGM->pGstPaePdptR0    = NIL_RTR0PTR;
+                    pPGM->pGstAmd64Pml4R0  = NIL_RTR0PTR;
 #endif
-                for (unsigned i = 0; i < RT_ELEMENTS(pPGM->apGstPaePDsR3); i++)
-                {
-                    pPGM->apGstPaePDsR3[i]             = NULL;
+                    for (unsigned i = 0; i < RT_ELEMENTS(pPGM->apGstPaePDsR3); i++)
+                    {
+                        pPGM->apGstPaePDsR3[i]             = NULL;
 #ifndef VBOX_WITH_2X_4GB_ADDR_SPACE
-                    pPGM->apGstPaePDsR0[i]             = NIL_RTR0PTR;
+                        pPGM->apGstPaePDsR0[i]             = NIL_RTR0PTR;
 #endif
+                    }
+
+                    /* Flush REM TLBs. */
+                    CPUMSetChangedFlags(&pVM->aCpus[idCpu], CPUM_CHANGED_GLOBAL_TLB_FLUSH);
                 }
 
-                /* Flush REM TLBs. */
-                CPUMSetChangedFlags(&pVM->aCpus[idCpu], CPUM_CHANGED_GLOBAL_TLB_FLUSH);
+                /* Flush REM translation blocks. */
+                REMFlushTBs(pVM);
             }
-
-            /* Flush REM translation blocks. */
-            REMFlushTBs(pVM);
         }
     }
@@ -3460,5 +3458,5 @@
     AssertReturn(pChunk, VERR_NO_MEMORY);
     pChunk->Core.Key = idChunk;
-    pChunk->AgeCore.Key = pVM->pgm.s.ChunkR3Map.iNow;
+    pChunk->iAge     = pVM->pgm.s.ChunkR3Map.iNow;
 
     /*
@@ -3486,7 +3484,4 @@
         pVM->pgm.s.ChunkR3Map.c++;
         pVM->pgm.s.cMappedChunks++;
-
-        fRc = RTAvllU32Insert(&pVM->pgm.s.ChunkR3Map.pAgeTree, &pChunk->AgeCore);
-        AssertRelease(fRc);
 
         /* If we're running out of virtual address space, then we should unmap another chunk. */
