Index: trunk/src/VBox/VMM/PGMPhys.cpp
===================================================================
--- trunk/src/VBox/VMM/PGMPhys.cpp	(revision 26344)
+++ trunk/src/VBox/VMM/PGMPhys.cpp	(revision 26348)
@@ -741,4 +741,5 @@
 static int pgmR3PhysFreePageRange(PVM pVM, PPGMRAMRANGE pRam, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast, uint8_t uType)
 {
+    Assert(PGMIsLockOwner(pVM));
     uint32_t            cPendingPages = 0;
     PGMMFREEPAGESREQ    pReq;
@@ -746,5 +747,5 @@
     AssertLogRelRCReturn(rc, rc);
 
-    /* Itegerate the pages. */
+    /* Iterate the pages. */
     PPGMPAGE pPageDst   = &pRam->aPages[(GCPhys - pRam->GCPhys) >> PAGE_SHIFT];
     uint32_t cPagesLeft = ((GCPhysLast - GCPhys) >> PAGE_SHIFT) + 1;
@@ -767,4 +768,68 @@
     GMMR3FreePagesCleanup(pReq);
 
+    return rc;
+}
+
+/**
+ * Rendezvous callback used by PGMR3PhysFreeRamPages that frees a range of guest physical pages
+ *
+ * This is only called on one of the EMTs while the other ones are waiting for
+ * it to complete this function.
+ *
+ * @returns VINF_SUCCESS (VBox strict status code).
+ * @param   pVM         The VM handle.
+ * @param   pVCpu       The VMCPU for the EMT we're being called on. Unused.
+ * @param   pvUser      User parameter
+ */
+static DECLCALLBACK(VBOXSTRICTRC) pgmR3PhysFreeRamPagesRendezvous(PVM pVM, PVMCPU pVCpu, void *pvUser)
+{
+    uintptr_t          *paUser          = (uintptr_t *)pvUser;
+    unsigned            cPages          = paUser[0];
+    RTGCPHYS           *paPhysPage      = (RTGCPHYS *)paUser[1];
+    uint32_t            cPendingPages   = 0;
+    PGMMFREEPAGESREQ    pReq;
+
+    pgmLock(pVM);
+    int rc = GMMR3FreePagesPrepare(pVM, &pReq, PGMPHYS_FREE_PAGE_BATCH_SIZE, GMMACCOUNT_BASE);
+    if (RT_FAILURE(rc))
+    {
+        pgmUnlock(pVM);
+        AssertLogRelRC(rc);
+        return rc;
+    }
+
+    /* Iterate the pages. */
+    for (unsigned i = 0; i < cPages; i++)
+    {
+        PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, paPhysPage[i]);
+        if (    pPage == NULL
+            ||  pPage->uTypeY != PGMPAGETYPE_RAM)
+        {
+            Log(("PGMR3PhysFreePageRange: invalid physical page %RGp pPage->u3Type=%d\n", paPhysPage[i], (pPage) ? pPage->uTypeY : 0));
+            break;
+        }
+
+        rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, paPhysPage[i]);
+        if (RT_FAILURE(rc))
+        {
+            pgmUnlock(pVM);
+            AssertLogRelRC(rc);
+            return rc;
+        }
+    }
+
+    if (cPendingPages)
+    {
+        rc = GMMR3FreePagesPerform(pVM, pReq, cPendingPages);
+        if (RT_FAILURE(rc))
+        {
+            pgmUnlock(pVM);
+            AssertLogRelRC(rc);
+            return rc;
+        }
+    }
+    GMMR3FreePagesCleanup(pReq);
+
+    pgmUnlock(pVM);
     return rc;
 }
@@ -780,34 +845,12 @@
 VMMR3DECL(int) PGMR3PhysFreeRamPages(PVM pVM, unsigned cPages, RTGCPHYS *paPhysPage)
 {
-    uint32_t            cPendingPages = 0;
-    PGMMFREEPAGESREQ    pReq;
-    int rc = GMMR3FreePagesPrepare(pVM, &pReq, PGMPHYS_FREE_PAGE_BATCH_SIZE, GMMACCOUNT_BASE);
-    AssertLogRelRCReturn(rc, rc);
-
-    /* Itegerate the pages. */
-    for (unsigned i = 0; i < cPages; i++)
-    {
-        PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, paPhysPage[i]);
-        if (    pPage == NULL
-            ||  pPage->uTypeY != PGMPAGETYPE_RAM)
-        {
-            Log(("PGMR3PhysFreePageRange: invalid physical page %RGp pPage->u3Type=%d\n", paPhysPage[i], (pPage) ? pPage->uTypeY : 0));
-            break;
-        }
-
-        rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, paPhysPage[i]);
-        AssertLogRelRCReturn(rc, rc); /* We're done for if this goes wrong. */
-    }
-
-    if (cPendingPages)
-    {
-        rc = GMMR3FreePagesPerform(pVM, pReq, cPendingPages);
-        AssertLogRelRCReturn(rc, rc);
-    }
-    GMMR3FreePagesCleanup(pReq);
-
+    uintptr_t paUser[2];
+
+    paUser[0] = cPages;
+    paUser[1] = (uintptr_t)paPhysPage;
+    int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, pgmR3PhysFreeRamPagesRendezvous, (void *)paUser);
+    AssertRC(rc);
     return rc;
 }
-
 
 /**
