Index: /trunk/src/VBox/Devices/Graphics/DevVGA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA.cpp	(revision 24713)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA.cpp	(revision 24714)
@@ -5453,4 +5453,5 @@
 
     if (    uVersion != VGA_SAVEDSTATE_VERSION
+        &&  uVersion != VGA_SAVEDSTATE_VERSION_WITH_CONFIG
         &&  uVersion != VGA_SAVEDSTATE_VERSION_HGSMI
         &&  uVersion != VGA_SAVEDSTATE_VERSION_PRE_HGSMI
Index: /trunk/src/VBox/Devices/Graphics/DevVGA.h
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA.h	(revision 24713)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA.h	(revision 24714)
@@ -49,5 +49,6 @@
 #endif /* VBOX_WITH_HGSMI */
 
-#define VGA_SAVEDSTATE_VERSION              4
+#define VGA_SAVEDSTATE_VERSION              5
+#define VGA_SAVEDSTATE_VERSION_WITH_CONFIG  4
 #define VGA_SAVEDSTATE_VERSION_HGSMI        3
 #define VGA_SAVEDSTATE_VERSION_PRE_HGSMI    2
Index: /trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp	(revision 24713)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp	(revision 24714)
@@ -66,4 +66,18 @@
 } VBVAVIEW;
 
+typedef struct VBVAMOUSESHAPEINFO
+{
+    bool fSet;
+    bool fVisible;
+    bool fAlpha;
+    uint32_t u32HotX;
+    uint32_t u32HotY;
+    uint32_t u32Width;
+    uint32_t u32Height;
+    uint32_t cbShape;
+    uint32_t cbAllocated;
+    uint8_t *pu8Shape;
+} VBVAMOUSESHAPEINFO;
+
 /* @todo saved state: save and restore VBVACONTEXT */
 typedef struct _VBVACONTEXT
@@ -71,4 +85,5 @@
     uint32_t cViews;
     VBVAVIEW aViews[64 /* @todo SchemaDefs::MaxGuestMonitors*/];
+    VBVAMOUSESHAPEINFO mouseShapeInfo;
 } VBVACONTEXT;
 
@@ -519,45 +534,46 @@
 }
 
-static int vbvaMousePointerShape (PVGASTATE pVGAState, VBVACONTEXT *pCtx, const VBVAMOUSEPOINTERSHAPE *pShape, HGSMISIZE cbShape)
-{
-    bool fVisible = (pShape->fu32Flags & VBOX_MOUSE_POINTER_VISIBLE) != 0;
-    bool fAlpha =   (pShape->fu32Flags & VBOX_MOUSE_POINTER_ALPHA) != 0;
-    bool fShape =   (pShape->fu32Flags & VBOX_MOUSE_POINTER_SHAPE) != 0;
-
-    HGSMISIZE cbPointerData = 0;
-
-    if (fShape)
-    {
-         cbPointerData = ((((pShape->u32Width + 7) / 8) * pShape->u32Height + 3) & ~3)
-                         + pShape->u32Width * 4 * pShape->u32Height;
-    }
-
-    if (cbPointerData > cbShape - RT_OFFSETOF(VBVAMOUSEPOINTERSHAPE, au8Data))
-    {
-        Log(("vbvaMousePointerShape: calculated pointer data size is too big (%d bytes, limit %d)\n",
-              cbPointerData, cbShape - RT_OFFSETOF(VBVAMOUSEPOINTERSHAPE, au8Data)));
-        return VERR_INVALID_PARAMETER;
-    }
-
-    if (pVGAState->pDrv->pfnVBVAMousePointerShape == NULL)
-    {
-        return VERR_NOT_SUPPORTED;
-    }
-
+#ifdef DEBUG_sunlover
+void dumpMouseShapeInfo(const VBVAMOUSESHAPEINFO *pMouseShapeInfo)
+{
+    LogFlow(("fSet = %d, fVisible %d, fAlpha %d, @%d,%d %dx%d (%p, %d/%d)\n",
+             pMouseShapeInfo->fSet,
+             pMouseShapeInfo->fVisible,
+             pMouseShapeInfo->fAlpha,
+             pMouseShapeInfo->u32HotX,
+             pMouseShapeInfo->u32HotY,
+             pMouseShapeInfo->u32Width,
+             pMouseShapeInfo->u32Height,
+             pMouseShapeInfo->pu8Shape,
+             pMouseShapeInfo->cbShape,
+             pMouseShapeInfo->cbAllocated
+             ));
+}
+#endif
+
+static int vbvaUpdateMousePointerShape(PVGASTATE pVGAState, VBVAMOUSESHAPEINFO *pMouseShapeInfo, bool fShape, const uint8_t *pu8Shape)
+{
     int rc;
-
-    if (fShape)
+    LogFlowFunc(("pVGAState %p, pMouseShapeInfo %p, fShape %d, pu8Shape %p\n",
+                  pVGAState, pMouseShapeInfo, fShape, pu8Shape));
+#ifdef DEBUG_sunlover
+    dumpMouseShapeInfo(pMouseShapeInfo);
+#endif
+
+    if (fShape && pu8Shape != NULL)
     {
         rc = pVGAState->pDrv->pfnVBVAMousePointerShape (pVGAState->pDrv,
-                                                        fVisible,
-                                                        fAlpha,
-                                                        pShape->u32HotX, pShape->u32HotY,
-                                                        pShape->u32Width, pShape->u32Height,
-                                                        &pShape->au8Data[0]);
+                                                        pMouseShapeInfo->fVisible,
+                                                        pMouseShapeInfo->fAlpha,
+                                                        pMouseShapeInfo->u32HotX,
+                                                        pMouseShapeInfo->u32HotY,
+                                                        pMouseShapeInfo->u32Width,
+                                                        pMouseShapeInfo->u32Height,
+                                                        pu8Shape);
     }
     else
     {
         rc = pVGAState->pDrv->pfnVBVAMousePointerShape (pVGAState->pDrv,
-                                                        fVisible,
+                                                        pMouseShapeInfo->fVisible,
                                                         false,
                                                         0, 0,
@@ -565,4 +581,68 @@
                                                         NULL);
     }
+
+    return rc;
+}
+
+static int vbvaMousePointerShape (PVGASTATE pVGAState, VBVACONTEXT *pCtx, const VBVAMOUSEPOINTERSHAPE *pShape, HGSMISIZE cbShape)
+{
+    bool fVisible = (pShape->fu32Flags & VBOX_MOUSE_POINTER_VISIBLE) != 0;
+    bool fAlpha =   (pShape->fu32Flags & VBOX_MOUSE_POINTER_ALPHA) != 0;
+    bool fShape =   (pShape->fu32Flags & VBOX_MOUSE_POINTER_SHAPE) != 0;
+
+    HGSMISIZE cbPointerData = 0;
+
+    if (fShape)
+    {
+         cbPointerData = ((((pShape->u32Width + 7) / 8) * pShape->u32Height + 3) & ~3)
+                         + pShape->u32Width * 4 * pShape->u32Height;
+    }
+
+    if (cbPointerData > cbShape - RT_OFFSETOF(VBVAMOUSEPOINTERSHAPE, au8Data))
+    {
+        Log(("vbvaMousePointerShape: calculated pointer data size is too big (%d bytes, limit %d)\n",
+              cbPointerData, cbShape - RT_OFFSETOF(VBVAMOUSEPOINTERSHAPE, au8Data)));
+        return VERR_INVALID_PARAMETER;
+    }
+
+    /* Save mouse info it will be used to restore mouse pointer after restoring saved state. */
+    pCtx->mouseShapeInfo.fSet = true;
+    pCtx->mouseShapeInfo.fVisible = fVisible;
+    pCtx->mouseShapeInfo.fAlpha = fAlpha;
+    pCtx->mouseShapeInfo.u32HotX = pShape->u32HotX;
+    pCtx->mouseShapeInfo.u32HotY = pShape->u32HotY;
+    pCtx->mouseShapeInfo.u32Width = pShape->u32Width;
+    pCtx->mouseShapeInfo.u32Height = pShape->u32Height;
+    if (fShape)
+    {
+        /* Reallocate memory buffer if necessary. */
+        if (cbPointerData > pCtx->mouseShapeInfo.cbAllocated)
+        {
+            RTMemFree (pCtx->mouseShapeInfo.pu8Shape);
+            pCtx->mouseShapeInfo.pu8Shape = NULL;
+            pCtx->mouseShapeInfo.cbShape = 0;
+
+            uint8_t *pu8Shape = (uint8_t *)RTMemAlloc (cbPointerData);
+            if (pu8Shape)
+            {
+                pCtx->mouseShapeInfo.pu8Shape = pu8Shape;
+                pCtx->mouseShapeInfo.cbAllocated = cbPointerData;
+            }
+        }
+
+        /* Copy shape bitmaps. */
+        if (pCtx->mouseShapeInfo.pu8Shape)
+        {
+            memcpy (pCtx->mouseShapeInfo.pu8Shape, &pShape->au8Data[0], cbPointerData);
+            pCtx->mouseShapeInfo.cbShape = cbPointerData;
+        }
+    }
+
+    if (pVGAState->pDrv->pfnVBVAMousePointerShape == NULL)
+    {
+        return VERR_NOT_SUPPORTED;
+    }
+
+    int rc = vbvaUpdateMousePointerShape(pVGAState, &pCtx->mouseShapeInfo, fShape, &pShape->au8Data[0]);
 
     return rc;
@@ -629,4 +709,6 @@
               pView->partialRecord.pu8));
     }
+
+    dumpMouseShapeInfo(&pCtx->mouseShapeInfo);
 }
 #endif /* DEBUG_sunlover */
@@ -705,4 +787,31 @@
                 }
             }
+
+            /* Save mouse pointer shape information. */
+            rc = SSMR3PutBool (pSSM, pCtx->mouseShapeInfo.fSet);
+            AssertRCReturn(rc, rc);
+            rc = SSMR3PutBool (pSSM, pCtx->mouseShapeInfo.fVisible);
+            AssertRCReturn(rc, rc);
+            rc = SSMR3PutBool (pSSM, pCtx->mouseShapeInfo.fAlpha);
+            AssertRCReturn(rc, rc);
+            rc = SSMR3PutU32 (pSSM, pCtx->mouseShapeInfo.u32HotX);
+            AssertRCReturn(rc, rc);
+            rc = SSMR3PutU32 (pSSM, pCtx->mouseShapeInfo.u32HotY);
+            AssertRCReturn(rc, rc);
+            rc = SSMR3PutU32 (pSSM, pCtx->mouseShapeInfo.u32Width);
+            AssertRCReturn(rc, rc);
+            rc = SSMR3PutU32 (pSSM, pCtx->mouseShapeInfo.u32Height);
+            AssertRCReturn(rc, rc);
+            rc = SSMR3PutU32 (pSSM, pCtx->mouseShapeInfo.cbShape);
+            AssertRCReturn(rc, rc);
+            if (pCtx->mouseShapeInfo.cbShape)
+            {
+                rc = SSMR3PutMem (pSSM, pCtx->mouseShapeInfo.pu8Shape, pCtx->mouseShapeInfo.cbShape);
+                AssertRCReturn(rc, rc);
+            }
+
+            /* Size of some additional data. For future extensions. */
+            rc = SSMR3PutU32 (pSSM, 0);
+            AssertRCReturn(rc, rc);
         }
     }
@@ -713,5 +822,5 @@
 int vboxVBVALoadStateExec (PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t u32Version)
 {
-    if (u32Version < 3)
+    if (u32Version < VGA_SAVEDSTATE_VERSION_HGSMI)
     {
         /* Nothing was saved. */
@@ -810,4 +919,50 @@
             }
 
+            if (u32Version > VGA_SAVEDSTATE_VERSION_WITH_CONFIG)
+            {
+                /* Read mouse pointer shape information. */
+                rc = SSMR3GetBool (pSSM, &pCtx->mouseShapeInfo.fSet);
+                AssertRCReturn(rc, rc);
+                rc = SSMR3GetBool (pSSM, &pCtx->mouseShapeInfo.fVisible);
+                AssertRCReturn(rc, rc);
+                rc = SSMR3GetBool (pSSM, &pCtx->mouseShapeInfo.fAlpha);
+                AssertRCReturn(rc, rc);
+                rc = SSMR3GetU32 (pSSM, &pCtx->mouseShapeInfo.u32HotX);
+                AssertRCReturn(rc, rc);
+                rc = SSMR3GetU32 (pSSM, &pCtx->mouseShapeInfo.u32HotY);
+                AssertRCReturn(rc, rc);
+                rc = SSMR3GetU32 (pSSM, &pCtx->mouseShapeInfo.u32Width);
+                AssertRCReturn(rc, rc);
+                rc = SSMR3GetU32 (pSSM, &pCtx->mouseShapeInfo.u32Height);
+                AssertRCReturn(rc, rc);
+                rc = SSMR3GetU32 (pSSM, &pCtx->mouseShapeInfo.cbShape);
+                AssertRCReturn(rc, rc);
+                if (pCtx->mouseShapeInfo.cbShape)
+                {
+                    pCtx->mouseShapeInfo.pu8Shape = (uint8_t *)RTMemAlloc(pCtx->mouseShapeInfo.cbShape);
+                    if (pCtx->mouseShapeInfo.pu8Shape == NULL)
+                    {
+                        return VERR_NO_MEMORY;
+                    }
+                    pCtx->mouseShapeInfo.cbAllocated = pCtx->mouseShapeInfo.cbShape;
+                    rc = SSMR3GetMem (pSSM, pCtx->mouseShapeInfo.pu8Shape, pCtx->mouseShapeInfo.cbShape);
+                    AssertRCReturn(rc, rc);
+                }
+                else
+                {
+                    pCtx->mouseShapeInfo.pu8Shape = NULL;
+                }
+
+                /* Size of some additional data. For future extensions. */
+                uint32_t cbExtra = 0;
+                rc = SSMR3GetU32 (pSSM, &cbExtra);
+                AssertRCReturn(rc, rc);
+                if (cbExtra > 0)
+                {
+                    rc = SSMR3Skip(pSSM, cbExtra);
+                    AssertRCReturn(rc, rc);
+                }
+            }
+
             pCtx->cViews = iView;
             LogFlowFunc(("%d views loaded\n", pCtx->cViews));
@@ -839,4 +994,9 @@
                 vbvaResize (pVGAState, pView, &pView->screen);
             }
+        }
+
+        if (pCtx->mouseShapeInfo.fSet)
+        {
+            vbvaUpdateMousePointerShape(pVGAState, &pCtx->mouseShapeInfo, true, pCtx->mouseShapeInfo.pu8Shape);
         }
     }
@@ -1402,4 +1562,10 @@
             vbvaDisable (uScreenId, pVGAState, pCtx);
         }
+
+        pCtx->mouseShapeInfo.fSet = false;
+        RTMemFree(pCtx->mouseShapeInfo.pu8Shape);
+        pCtx->mouseShapeInfo.pu8Shape = NULL;
+        pCtx->mouseShapeInfo.cbAllocated = 0;
+        pCtx->mouseShapeInfo.cbShape = 0;
     }
 
@@ -1467,4 +1633,15 @@
 void VBVADestroy (PVGASTATE pVGAState)
 {
+    VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext (pVGAState->pHGSMI);
+
+    if (pCtx)
+    {
+        pCtx->mouseShapeInfo.fSet = false;
+        RTMemFree(pCtx->mouseShapeInfo.pu8Shape);
+        pCtx->mouseShapeInfo.pu8Shape = NULL;
+        pCtx->mouseShapeInfo.cbAllocated = 0;
+        pCtx->mouseShapeInfo.cbShape = 0;
+    }
+
     HGSMIDestroy (pVGAState->pHGSMI);
     pVGAState->pHGSMI = NULL;
