Index: /trunk/include/VBox/err.h
===================================================================
--- /trunk/include/VBox/err.h	(revision 23708)
+++ /trunk/include/VBox/err.h	(revision 23709)
@@ -569,29 +569,31 @@
 /** Vote for another pass.  */
 #define VINF_SSM_VOTE_FOR_ANOTHER_PASS          1851
+/** Vote for done tell SSM not to call again until the final pass. */
+#define VINF_SSM_VOTE_DONE_DONT_CALL_AGAIN      1852
 /** Vote for giving up.  */
-#define VERR_SSM_VOTE_FOR_GIVING_UP             (-1852)
+#define VERR_SSM_VOTE_FOR_GIVING_UP             (-1853)
 /** Giving up a live snapshot/migration attempt because of too many passes. */
-#define VERR_SSM_TOO_MANY_PASSES                (-1853)
+#define VERR_SSM_TOO_MANY_PASSES                (-1854)
 /** Giving up a live snapshot/migration attempt because the state grew to
  * big. */
-#define VERR_SSM_STATE_GREW_TOO_BIG             (-1854)
+#define VERR_SSM_STATE_GREW_TOO_BIG             (-1855)
 /** Giving up a live snapshot attempt because we're low on disk space.  */
-#define VERR_SSM_LOW_ON_DISK_SPACE              (-1855)
+#define VERR_SSM_LOW_ON_DISK_SPACE              (-1856)
 /** The operation was cancelled. */
-#define VERR_SSM_CANCELLED                      (-1856)
+#define VERR_SSM_CANCELLED                      (-1857)
 /** Nothing that can be cancelled.  */
-#define VERR_SSM_NO_PENDING_OPERATION           (-1857)
+#define VERR_SSM_NO_PENDING_OPERATION           (-1858)
 /** The operation has already been cancelled. */
-#define VERR_SSM_ALREADY_CANCELLED              (-1858)
+#define VERR_SSM_ALREADY_CANCELLED              (-1859)
 /** The machine was powered off while saving. */
-#define VERR_SSM_LIVE_POWERED_OFF               (-1859)
+#define VERR_SSM_LIVE_POWERED_OFF               (-1860)
 /** The live snapshot/migration operation was aborted because of a guru
  *  meditation. */
-#define VERR_SSM_LIVE_GURU_MEDITATION           (-1860)
+#define VERR_SSM_LIVE_GURU_MEDITATION           (-1861)
 /** The live snapshot/migration operation was aborted because of a fatal runtime
  *  error. */
-#define VERR_SSM_LIVE_FATAL_ERROR               (-1861)
+#define VERR_SSM_LIVE_FATAL_ERROR               (-1862)
 /** The VM was suspended while saving, don't resume execution. */
-#define VINF_SSM_LIVE_SUSPENDED                  1862
+#define VINF_SSM_LIVE_SUSPENDED                  1863
 /** @} */
 
Index: /trunk/include/VBox/ssm.h
===================================================================
--- /trunk/include/VBox/ssm.h	(revision 23708)
+++ /trunk/include/VBox/ssm.h	(revision 23709)
@@ -170,4 +170,6 @@
  * @retval  VINF_SUCCESS if done.
  * @retval  VINF_SSM_VOTE_FOR_ANOTHER_PASS if another pass is needed.
+ * @retval  VINF_SSM_VOTE_DONE_DONT_CALL_AGAIN if the live saving of the unit is
+ *          done and there is not need calling it again before the final pass.
  * @retval  VERR_SSM_VOTE_FOR_GIVING_UP if its time to give up.
  *
@@ -295,4 +297,6 @@
  * @retval  VINF_SUCCESS if done.
  * @retval  VINF_SSM_VOTE_FOR_ANOTHER_PASS if another pass is needed.
+ * @retval  VINF_SSM_VOTE_DONE_DONT_CALL_AGAIN if the live saving of the unit is
+ *          done and there is not need calling it again before the final pass.
  * @retval  VERR_SSM_VOTE_FOR_GIVING_UP if its time to give up.
  *
@@ -421,4 +425,6 @@
  * @retval  VINF_SUCCESS if done.
  * @retval  VINF_SSM_VOTE_FOR_ANOTHER_PASS if another pass is needed.
+ * @retval  VINF_SSM_VOTE_DONE_DONT_CALL_AGAIN if the live saving of the unit is
+ *          done and there is not need calling it again before the final pass.
  * @retval  VERR_SSM_VOTE_FOR_GIVING_UP if its time to give up.
  *
@@ -541,5 +547,11 @@
  * being called every time.
  *
- * @returns true if done, false if there is more that needs to be saved first.
+ * @returns VBox status code.
+ * @retval  VINF_SUCCESS if done.
+ * @retval  VINF_SSM_VOTE_FOR_ANOTHER_PASS if another pass is needed.
+ * @retval  VINF_SSM_VOTE_DONE_DONT_CALL_AGAIN if the live saving of the unit is
+ *          done and there is not need calling it again before the final pass.
+ * @retval  VERR_SSM_VOTE_FOR_GIVING_UP if its time to give up.
+ *
  * @param   pSSM            SSM operation handle.
  * @param   pvUser          User argument.
Index: /trunk/src/VBox/VMM/SSM.cpp
===================================================================
--- /trunk/src/VBox/VMM/SSM.cpp	(revision 23708)
+++ /trunk/src/VBox/VMM/SSM.cpp	(revision 23709)
@@ -4260,4 +4260,5 @@
 static int ssmR3LiveDoVoteRun(PVM pVM, PSSMHANDLE pSSM, uint32_t uPass)
 {
+    int rcRet = VINF_SUCCESS;
     AssertRC(pSSM->rc);
     pSSM->rc = VINF_SUCCESS;
@@ -4265,5 +4266,6 @@
     for (PSSMUNIT pUnit = pVM->ssm.s.pHead; pUnit; pUnit = pUnit->pNext)
     {
-        if (pUnit->u.Common.pfnLiveVote)
+        if (    pUnit->u.Common.pfnLiveVote
+            &&  !pUnit->fDoneLive)
         {
             int rc;
@@ -4293,21 +4295,28 @@
                 {
                     Log(("ssmR3DoLiveVoteRun: '%s'/#%u -> VINF_SSM_VOTE_FOR_ANOTHER_PASS (pass=%u)\n", pUnit->szName, pUnit->u32Instance, uPass));
-                    return VINF_SSM_VOTE_FOR_ANOTHER_PASS;
+                    rcRet = VINF_SSM_VOTE_FOR_ANOTHER_PASS;
                 }
-
-                /*
-                 * rc is usually VERR_SSM_VOTE_FOR_GIVING_UP here, but we allow
-                 * other status codes for better user feed back.  However, no
-                 * other non-error status is allowed.
-                 */
-                LogRel(("SSM: Error - '%s'/#%u voted %Rrc! (pass=%u)\n", pUnit->szName, pUnit->u32Instance, rc, uPass));
-                AssertMsgReturn(RT_FAILURE(rc), ("%Rrc; '%s'\n", rc, pUnit->szName), pSSM->rc = VERR_IPE_UNEXPECTED_INFO_STATUS);
-                return pSSM->rc = rc;
+                else if (rc == VINF_SSM_VOTE_DONE_DONT_CALL_AGAIN)
+                {
+                    pUnit->fDoneLive = true;
+                    Log(("ssmR3DoLiveVoteRun: '%s'/#%u -> VINF_SSM_VOTE_DONE_DONT_CALL_AGAIN (pass=%u)\n", pUnit->szName, pUnit->u32Instance, uPass));
+                }
+                else
+                {
+                    /*
+                     * rc is usually VERR_SSM_VOTE_FOR_GIVING_UP here, but we allow
+                     * other status codes for better user feed back.  However, no
+                     * other non-error status is allowed.
+                     */
+                    LogRel(("SSM: Error - '%s'/#%u voted %Rrc! (pass=%u)\n", pUnit->szName, pUnit->u32Instance, rc, uPass));
+                    AssertMsgReturn(RT_FAILURE(rc), ("%Rrc; '%s'\n", rc, pUnit->szName), pSSM->rc = VERR_IPE_UNEXPECTED_INFO_STATUS);
+                    return pSSM->rc = rc;
+                }
             }
         }
     }
-
-    LogRel(("SSM: Step 1 completed after pass %u.\n", uPass));
-    return VINF_SUCCESS;
+    if (rcRet == VINF_SUCCESS)
+        LogRel(("SSM: Step 1 completed after pass %u.\n", uPass));
+    return rcRet;
 }
 
@@ -4334,5 +4343,6 @@
          * Skip units without a callback (this is most).
          */
-        if (!pUnit->u.Common.pfnLiveExec)
+        if (   !pUnit->u.Common.pfnLiveExec
+            || pUnit->fDoneLive)
             continue;
         pUnit->offStream = ssmR3StrmTell(&pSSM->Strm);
Index: /trunk/src/VBox/VMM/SSMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/SSMInternal.h	(revision 23708)
+++ /trunk/src/VBox/VMM/SSMInternal.h	(revision 23709)
@@ -67,4 +67,7 @@
      * done or not. */
     bool                    fCalled;
+    /** Finished its live part.
+     * This is used to handle VERR_SSM_VOTE_FOR_GIVING_UP.  */
+    bool                    fDoneLive;
     /** Callback interface type. */
     SSMUNITTYPE             enmType;
