Index: /trunk/src/VBox/VMM/PGM.cpp
===================================================================
--- /trunk/src/VBox/VMM/PGM.cpp	(revision 27542)
+++ /trunk/src/VBox/VMM/PGM.cpp	(revision 27543)
@@ -4268,5 +4268,6 @@
         while (GCPhys < pRam->GCPhysLast && RT_SUCCESS(rc))
         {
-            if (PGM_PAGE_IS_ZERO(pPage))
+            if (    PGM_PAGE_IS_ZERO(pPage)
+                ||  PGM_PAGE_IS_BALLOONED(pPage))
             {
                 if (fIncZeroPgs)
Index: /trunk/src/VBox/VMM/PGMDbg.cpp
===================================================================
--- /trunk/src/VBox/VMM/PGMDbg.cpp	(revision 27542)
+++ /trunk/src/VBox/VMM/PGMDbg.cpp	(revision 27543)
@@ -607,4 +607,5 @@
                 if (    (   !PGM_PAGE_IS_ZERO(pPage)
                          || fAllZero)
+                    &&  !PGM_PAGE_IS_BALLOONED(pPage)
                     &&  !PGM_PAGE_IS_MMIO(pPage))
                 {
@@ -747,4 +748,5 @@
                 &&  (   !PGM_PAGE_IS_ZERO(pPage)
                      || fAllZero)
+                &&  !PGM_PAGE_IS_BALLOONED(pPage)
                 &&  !PGM_PAGE_IS_MMIO(pPage))
             {
Index: /trunk/src/VBox/VMM/PGMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/PGMInternal.h	(revision 27542)
+++ /trunk/src/VBox/VMM/PGMInternal.h	(revision 27543)
@@ -826,5 +826,5 @@
  * @param   pPage       Pointer to the physical guest page tracking structure.
  */
-#define PGM_PAGE_IS_BALLOONED(pPage)            ( (pPage)->uStateY == PGM_PAGE_STATE_BALLOONED )
+#define PGM_PAGE_IS_BALLOONED(pPage)        ( (pPage)->uStateY == PGM_PAGE_STATE_BALLOONED )
 
 /**
Index: /trunk/src/VBox/VMM/PGMPhys.cpp
===================================================================
--- /trunk/src/VBox/VMM/PGMPhys.cpp	(revision 27542)
+++ /trunk/src/VBox/VMM/PGMPhys.cpp	(revision 27543)
@@ -824,4 +824,6 @@
                 return rc;
             }
+            Assert(PGM_PAGE_IS_ZERO(pPage));
+            PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_BALLOONED);
         }
 
@@ -1263,4 +1265,5 @@
                     }
 
+                    case PGM_PAGE_STATE_BALLOONED:
                     case PGM_PAGE_STATE_ALLOCATED:
                     case PGM_PAGE_STATE_WRITE_MONITORED:
@@ -1336,5 +1339,6 @@
                         }
                         else
-                        if (!PGM_PAGE_IS_ZERO(pPage))
+                        if (    !PGM_PAGE_IS_ZERO(pPage)
+                            &&  !PGM_PAGE_IS_BALLOONED(pPage))
                         {
                             rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, pRam->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT));
@@ -1370,8 +1374,16 @@
                             case PGM_PAGE_STATE_ZERO:
                                 break;
+
+                            case PGM_PAGE_STATE_BALLOONED:
+                                /* Turn into a zero page; the balloon status is lost when the VM reboots. */
+                                PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_ZERO);
+                                break;
+
                             case PGM_PAGE_STATE_SHARED:
                             case PGM_PAGE_STATE_WRITE_MONITORED:
                                 rc = pgmPhysPageMakeWritable(pVM, pPage, pRam->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT));
                                 AssertLogRelRCReturn(rc, rc);
+                                /* no break */
+
                             case PGM_PAGE_STATE_ALLOCATED:
                             {
@@ -2781,5 +2793,6 @@
 
                 for (uint32_t iPage = 0; iPage < cPages; iPage++)
-                    if (PGM_PAGE_GET_STATE(&pRom->aPages[iPage].Shadow) != PGM_PAGE_STATE_ZERO)
+                    if (    !PGM_PAGE_IS_ZERO(&pRom->aPages[iPage].Shadow)
+                        &&  !PGM_PAGE_IS_BALLOONED(&pRom->aPages[iPage].Shadow))
                     {
                         Assert(PGM_PAGE_GET_STATE(&pRom->aPages[iPage].Shadow) == PGM_PAGE_STATE_ALLOCATED);
@@ -2800,5 +2813,5 @@
                 for (uint32_t iPage = 0; iPage < cPages; iPage++)
                 {
-                    Assert(PGM_PAGE_GET_STATE(&pRom->aPages[iPage].Shadow) != PGM_PAGE_STATE_ZERO);
+                    Assert(!PGM_PAGE_IS_ZERO(&pRom->aPages[iPage].Shadow) && !PGM_PAGE_IS_BALLOONED(&pRom->aPages[iPage].Shadow));
                     void *pvDstPage;
                     const RTGCPHYS GCPhys = pRom->GCPhys + (iPage << PAGE_SHIFT);
@@ -3480,5 +3493,6 @@
     }
 
-    if (PGM_PAGE_GET_STATE(pPage) == PGM_PAGE_STATE_ZERO)
+    if (    PGM_PAGE_IS_ZERO(pPage)
+        ||  PGM_PAGE_IS_BALLOONED(pPage))
         return VINF_SUCCESS;
 
@@ -3621,4 +3635,7 @@
                     case PGM_PAGE_STATE_ALLOCATED:
                         break;
+                    case PGM_PAGE_STATE_BALLOONED:
+                        AssertFailed();
+                        break;
                     case PGM_PAGE_STATE_ZERO:
                     case PGM_PAGE_STATE_SHARED:
Index: /trunk/src/VBox/VMM/PGMSavedState.cpp
===================================================================
--- /trunk/src/VBox/VMM/PGMSavedState.cpp	(revision 27542)
+++ /trunk/src/VBox/VMM/PGMSavedState.cpp	(revision 27543)
@@ -216,5 +216,5 @@
             {
                 if (PGMROMPROT_IS_ROM(pRom->aPages[iPage].enmProt))
-                    pRom->aPages[iPage].LiveSave.fWrittenTo = !PGM_PAGE_IS_ZERO(&pRom->aPages[iPage].Shadow);
+                    pRom->aPages[iPage].LiveSave.fWrittenTo = !PGM_PAGE_IS_ZERO(&pRom->aPages[iPage].Shadow) && !PGM_PAGE_IS_BALLOONED(&pRom->aPages[iPage].Shadow);
                 else
                 {
@@ -224,7 +224,7 @@
                     AssertLogRelMsgRC(rc, ("%Rrc GCPhys=%RGp\n", rc, GCPhys));
                     if (RT_SUCCESS(rc))
-                        pRom->aPages[iPage].LiveSave.fWrittenTo = !PGM_PAGE_IS_ZERO(pPage);
+                        pRom->aPages[iPage].LiveSave.fWrittenTo = !PGM_PAGE_IS_ZERO(pPage) && !PGM_PAGE_IS_BALLOONED(pPage);
                     else
-                        pRom->aPages[iPage].LiveSave.fWrittenTo = !PGM_PAGE_IS_ZERO(&pRom->aPages[iPage].Shadow);
+                        pRom->aPages[iPage].LiveSave.fWrittenTo = !PGM_PAGE_IS_ZERO(&pRom->aPages[iPage].Shadow) && !PGM_PAGE_IS_BALLOONED(&pRom->aPages[iPage].Shadow);
                 }
             }
@@ -419,5 +419,6 @@
             int rc = VINF_SUCCESS;
             char abPage[PAGE_SIZE];
-            if (!PGM_PAGE_IS_ZERO(pPage))
+            if (    !PGM_PAGE_IS_ZERO(pPage)
+                &&  !PGM_PAGE_IS_BALLOONED(pPage))
             {
                 void const *pvPage;
@@ -503,5 +504,5 @@
                     RTGCPHYS    GCPhys  = pRom->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT);
                     PPGMPAGE    pPage   = PGMROMPROT_IS_ROM(enmProt) ? &pRomPage->Shadow : pgmPhysGetPage(&pVM->pgm.s, GCPhys);
-                    bool        fZero   = PGM_PAGE_IS_ZERO(pPage);
+                    bool        fZero   = PGM_PAGE_IS_ZERO(pPage) || PGM_PAGE_IS_BALLOONED(pPage);
                     int         rc      = VINF_SUCCESS;
                     if (!fZero)
@@ -1074,5 +1075,6 @@
                     {
                         case PGMPAGETYPE_RAM:
-                            if (PGM_PAGE_IS_ZERO(pPage))
+                            if (    PGM_PAGE_IS_ZERO(pPage)
+                                ||  PGM_PAGE_IS_BALLOONED(pPage))
                             {
                                 paLSPages[iPage].fZero   = 1;
@@ -1242,5 +1244,5 @@
     {
         uint32_t u32Crc = RTCrc32(pvPage, PAGE_SIZE);
-        Assert(!PGM_PAGE_IS_ZERO(&pCur->aPages[iPage]) || u32Crc == PGM_STATE_CRC32_ZERO_PAGE);
+        Assert((!PGM_PAGE_IS_ZERO(&pCur->aPages[iPage]) && !PGM_PAGE_IS_BALLOONED(&pCur->aPages[iPage])) || u32Crc == PGM_STATE_CRC32_ZERO_PAGE);
         AssertMsg(paLSPages[iPage].u32Crc == u32Crc,
                   ("%08x != %08x for %RGp %R[pgmpage]\n", paLSPages[iPage].u32Crc, u32Crc,
@@ -1391,4 +1393,21 @@
 
                             case PGM_PAGE_STATE_ZERO:
+                                if (!paLSPages[iPage].fZero)
+                                {
+                                    if (!paLSPages[iPage].fDirty)
+                                    {
+                                        paLSPages[iPage].fDirty = 1;
+                                        pVM->pgm.s.LiveSave.Ram.cReadyPages--;
+                                        pVM->pgm.s.LiveSave.Ram.cDirtyPages++;
+                                    }
+                                    paLSPages[iPage].fZero = 1;
+                                    paLSPages[iPage].fShared = 0;
+#ifdef PGMLIVESAVERAMPAGE_WITH_CRC32
+                                    paLSPages[iPage].u32Crc = PGM_STATE_CRC32_ZERO_PAGE;
+#endif
+                                }
+                                break;
+
+                            case PGM_PAGE_STATE_BALLOONED:
                                 if (!paLSPages[iPage].fZero)
                                 {
@@ -1520,5 +1539,5 @@
 
                     /*
-                     * Only save pages that hasn't changed since last scan and are dirty.
+                     * Only save pages that haven't changed since last scan and are dirty.
                      */
                     if (    uPass != SSM_PASS_FINAL
@@ -1564,5 +1583,5 @@
                     int         rc;
                     RTGCPHYS    GCPhys = pCur->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT);
-                    bool        fZero  = PGM_PAGE_IS_ZERO(&pCur->aPages[iPage]);
+                    bool        fZero  = PGM_PAGE_IS_ZERO(&pCur->aPages[iPage]) || PGM_PAGE_IS_BALLOONED(&pCur->aPages[iPage]);
 
                     if (!fZero)
@@ -2100,5 +2119,6 @@
 
     /* I think this should be sufficient. */
-    if (!PGM_PAGE_IS_ZERO(pPage))
+    if (    !PGM_PAGE_IS_ZERO(pPage)
+        &&  !PGM_PAGE_IS_BALLOONED(pPage))
         return VERR_SSM_UNEXPECTED_DATA;
 
@@ -2535,5 +2555,6 @@
                     case PGM_STATE_REC_RAM_ZERO:
                     {
-                        if (PGM_PAGE_IS_ZERO(pPage))
+                        if (    PGM_PAGE_IS_ZERO(pPage)
+                            ||  PGM_PAGE_IS_BALLOONED(pPage))
                             break;
                         /** @todo implement zero page replacing. */
@@ -2703,5 +2724,6 @@
                 {
                     case PGM_STATE_REC_ROM_SHW_ZERO:
-                        if (PGM_PAGE_IS_ZERO(pRealPage))
+                        if (    PGM_PAGE_IS_ZERO(pRealPage)
+                            ||  PGM_PAGE_IS_BALLOONED(pRealPage))
                             break;
                         /** @todo implement zero page replacing. */
