Index: trunk/src/VBox/Devices/Graphics/DevVGASavedState.h
===================================================================
--- trunk/src/VBox/Devices/Graphics/DevVGASavedState.h	(revision 50517)
+++ trunk/src/VBox/Devices/Graphics/DevVGASavedState.h	(revision 50518)
@@ -23,5 +23,6 @@
 #define Graphics_DevVGASavedState_h
 
-#define VGA_SAVEDSTATE_VERSION              11
+#define VGA_SAVEDSTATE_VERSION              12
+#define VGA_SAVEDSTATE_VERSION_HGSMIMA      12 /* HGSMI memory allocator. */
 #define VGA_SAVEDSTATE_VERSION_VMSVGA       11
 #define VGA_SAVEDSTATE_VERSION_VMSVGA_2D    10 /* <- internal build with 2d state only */
Index: trunk/src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp
===================================================================
--- trunk/src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp	(revision 50517)
+++ trunk/src/VBox/Devices/Graphics/HGSMI/HGSMIHost.cpp	(revision 50518)
@@ -1327,4 +1327,62 @@
 }
 
+static int hgsmiHostSaveMA(PSSMHANDLE pSSM, HGSMIMADATA *pMA)
+{
+    int rc = SSMR3PutU32(pSSM, pMA->cBlocks);
+    if (RT_SUCCESS(rc))
+    {
+        HGSMIMABLOCK *pIter;
+        RTListForEach(&pMA->listBlocks, pIter, HGSMIMABLOCK, nodeBlock)
+        {
+            SSMR3PutU32(pSSM, pIter->descriptor);
+        }
+
+        rc = SSMR3PutU32(pSSM, pMA->cbMaxBlock);
+    }
+
+    return rc;
+}
+
+static int hgsmiHostLoadMA(PSSMHANDLE pSSM, uint32_t *pcBlocks, HGSMIOFFSET **ppaDescriptors, HGSMISIZE *pcbMaxBlock)
+{
+    int rc = SSMR3GetU32(pSSM, pcBlocks);
+    if (RT_SUCCESS(rc))
+    {
+        HGSMIOFFSET *paDescriptors = NULL;
+        if (*pcBlocks > 0)
+        {
+            paDescriptors = (HGSMIOFFSET *)RTMemAlloc(*pcBlocks * sizeof(HGSMIOFFSET));
+            if (paDescriptors)
+            {
+                uint32_t i;
+                for (i = 0; i < *pcBlocks; ++i)
+                {
+                    SSMR3GetU32(pSSM, &paDescriptors[i]);
+                }
+            }
+            else
+            {
+                rc = VERR_NO_MEMORY;
+            }
+        }
+
+        if (RT_SUCCESS(rc))
+        {
+            rc = SSMR3GetU32(pSSM, pcbMaxBlock);
+        }
+
+        if (RT_SUCCESS(rc))
+        {
+            *ppaDescriptors = paDescriptors;
+        }
+        else
+        {
+            RTMemFree(paDescriptors);
+        }
+    }
+
+    return rc;
+}
+
 int HGSMIHostSaveStateExec (PHGSMIINSTANCE pIns, PSSMHANDLE pSSM)
 {
@@ -1332,9 +1390,13 @@
 
     int rc;
+
+    SSMR3PutU32(pSSM, pIns->hostHeap.u32HeapType);
 
     HGSMIOFFSET off = pIns->pHGFlags ? HGSMIPointerToOffset(&pIns->area, (const HGSMIBUFFERHEADER *)pIns->pHGFlags) : HGSMIOFFSET_VOID;
     SSMR3PutU32 (pSSM, off);
 
-    off = HGSMIHeapHandleLocationOffset(&pIns->hostHeap);
+    off = pIns->hostHeap.u32HeapType == HGSMI_HEAP_TYPE_MA?
+              0:
+              HGSMIHeapHandleLocationOffset(&pIns->hostHeap);
     rc = SSMR3PutU32 (pSSM, off);
     if(off != HGSMIOFFSET_VOID)
@@ -1356,4 +1418,12 @@
             hgsmiFIFOUnlock (pIns);
         }
+
+        if (RT_SUCCESS(rc))
+        {
+            if (pIns->hostHeap.u32HeapType == HGSMI_HEAP_TYPE_MA)
+            {
+                rc = hgsmiHostSaveMA(pSSM, &pIns->hostHeap.u.ma);
+            }
+        }
     }
 
@@ -1372,4 +1442,12 @@
     int rc;
     HGSMIOFFSET off;
+    uint32_t u32HeapType = HGSMI_HEAP_TYPE_NULL;
+
+    if (u32Version >= VGA_SAVEDSTATE_VERSION_HGSMIMA)
+    {
+        rc = SSMR3GetU32(pSSM, &u32HeapType);
+        AssertRCReturn(rc, rc);
+    }
+
     rc = SSMR3GetU32(pSSM, &off);
     AssertRCReturn(rc, rc);
@@ -1381,4 +1459,12 @@
     if(off != HGSMIOFFSET_VOID)
     {
+        /* There is a saved heap. */
+        if (u32HeapType == HGSMI_HEAP_TYPE_NULL)
+        {
+            u32HeapType = u32Version > VGA_SAVEDSTATE_VERSION_HOST_HEAP?
+                              HGSMI_HEAP_TYPE_OFFSET:
+                              HGSMI_HEAP_TYPE_POINTER;
+        }
+
         HGSMIOFFSET offHeap;
         SSMR3GetU32(pSSM, &offHeap);
@@ -1388,24 +1474,4 @@
         rc = SSMR3GetU64(pSSM, &oldMem);
         AssertRCReturn(rc, rc);
-
-        rc = hgsmiHostHeapLock (pIns);
-        if (RT_SUCCESS (rc))
-        {
-            Assert(!pIns->hostHeap.cRefs);
-            pIns->hostHeap.cRefs = 0;
-
-            rc = HGSMIHeapRelocate(&pIns->hostHeap,
-                                   u32Version > VGA_SAVEDSTATE_VERSION_HOST_HEAP?
-                                       HGSMI_HEAP_TYPE_OFFSET:
-                                       HGSMI_HEAP_TYPE_POINTER,
-                                   pIns->area.pu8Base+offHeap,
-                                   off,
-                                   uintptr_t(pIns->area.pu8Base) - uintptr_t(oldMem),
-                                   cbHeap,
-                                   offHeap,
-                                   &g_hgsmiEnv);
-
-            hgsmiHostHeapUnlock (pIns);
-        }
 
         if (RT_SUCCESS(rc))
@@ -1425,4 +1491,48 @@
 
                 hgsmiFIFOUnlock (pIns);
+            }
+        }
+
+        if (RT_SUCCESS(rc))
+        {
+            if (u32HeapType == HGSMI_HEAP_TYPE_MA)
+            {
+                uint32_t cBlocks = 0;
+                HGSMISIZE cbMaxBlock = 0;
+                HGSMIOFFSET *paDescriptors = NULL;
+                rc = hgsmiHostLoadMA(pSSM, &cBlocks, &paDescriptors, &cbMaxBlock);
+                if (RT_SUCCESS(rc))
+                {
+                    rc = HGSMIHeapRestoreMA(&pIns->hostHeap,
+                                            pIns->area.pu8Base+offHeap,
+                                            cbHeap,
+                                            offHeap,
+                                            cBlocks,
+                                            paDescriptors,
+                                            cbMaxBlock,
+                                            &g_hgsmiEnv);
+
+                    RTMemFree(paDescriptors);
+                }
+            }
+            else if (   u32HeapType == HGSMI_HEAP_TYPE_OFFSET
+                     || u32HeapType == HGSMI_HEAP_TYPE_POINTER)
+            {
+                rc = hgsmiHostHeapLock (pIns);
+                if (RT_SUCCESS (rc))
+                {
+                    Assert(!pIns->hostHeap.cRefs);
+                    pIns->hostHeap.cRefs = 0;
+
+                    rc = HGSMIHeapRelocate(&pIns->hostHeap,
+                                           u32HeapType,
+                                           pIns->area.pu8Base+offHeap,
+                                           off,
+                                           uintptr_t(pIns->area.pu8Base) - uintptr_t(oldMem),
+                                           cbHeap,
+                                           offHeap);
+
+                    hgsmiHostHeapUnlock (pIns);
+                }
             }
         }
@@ -1748,4 +1858,6 @@
 #endif
 
+    HGSMIHeapDestroy(&pIns->hostHeap);
+
     HGSMIHeapSetupUninitialized(&pIns->hostHeap);
 
@@ -1759,4 +1871,6 @@
     if (pIns)
     {
+        HGSMIHeapDestroy(&pIns->hostHeap);
+
         if (RTCritSectIsInitialized (&pIns->hostHeapCritSect))
         {
