Index: trunk/src/VBox/VMM/FTM.cpp
===================================================================
--- trunk/src/VBox/VMM/FTM.cpp	(revision 32101)
+++ trunk/src/VBox/VMM/FTM.cpp	(revision 32102)
@@ -117,8 +117,14 @@
     AssertRCReturn(rc, rc);
 
-    STAM_REL_REG(pVM, &pVM->ftm.s.StatReceivedMem,               STAMTYPE_COUNTER, "/FT/Received/Mem",                   STAMUNIT_BYTES, "The amount of memory pages that was received.");
-    STAM_REL_REG(pVM, &pVM->ftm.s.StatReceivedState,             STAMTYPE_COUNTER, "/FT/Received/State",                 STAMUNIT_BYTES, "The amount of state information that was received.");
-    STAM_REL_REG(pVM, &pVM->ftm.s.StatSentMem,                   STAMTYPE_COUNTER, "/FT/Sent/Mem",                       STAMUNIT_BYTES, "The amount of memory pages that was sent.");
-    STAM_REL_REG(pVM, &pVM->ftm.s.StatSentState,                 STAMTYPE_COUNTER, "/FT/Sent/State",                     STAMUNIT_BYTES, "The amount of state information that was sent.");
+    /*
+     * Register statistics.
+     */
+    STAM_REL_REG(pVM, &pVM->ftm.s.StatReceivedMem,               STAMTYPE_COUNTER, "/FT/Received/Mem",                  STAMUNIT_BYTES, "The amount of memory pages that was received.");
+    STAM_REL_REG(pVM, &pVM->ftm.s.StatReceivedState,             STAMTYPE_COUNTER, "/FT/Received/State",                STAMUNIT_BYTES, "The amount of state information that was received.");
+    STAM_REL_REG(pVM, &pVM->ftm.s.StatSentMem,                   STAMTYPE_COUNTER, "/FT/Sent/Mem",                      STAMUNIT_BYTES, "The amount of memory pages that was sent.");
+    STAM_REL_REG(pVM, &pVM->ftm.s.StatSentState,                 STAMTYPE_COUNTER, "/FT/Sent/State",                    STAMUNIT_BYTES, "The amount of state information that was sent.");
+    STAM_REL_REG(pVM, &pVM->ftm.s.StatDeltaVM,                   STAMTYPE_COUNTER, "/FT/Sync/DeltaVM",                  STAMUNIT_OCCURENCES, "Number of delta vm syncs.");
+    STAM_REL_REG(pVM, &pVM->ftm.s.StatFullSync,                  STAMTYPE_COUNTER, "/FT/Sync/Full",                     STAMUNIT_OCCURENCES, "Number of full vm syncs.");
+    STAM_REL_REG(pVM, &pVM->ftm.s.StatDeltaMem,                  STAMTYPE_COUNTER, "/FT/Sync/DeltaMem",                 STAMUNIT_OCCURENCES, "Number of delta mem syncs.");
 
     return VINF_SUCCESS;
@@ -578,4 +584,16 @@
 
 /**
+ * VMR3ReqCallWait callback
+ *
+ * @param   pVM         The VM handle.
+ *
+ */
+static DECLCALLBACK(void) ftmR3WriteProtectMemory(PVM pVM)
+{
+    int rc = PGMR3PhysWriteProtectRAM(pVM);
+    AssertRC(rc);
+}
+
+/**
  * Sync the VM state partially or fully
  *
@@ -584,5 +602,5 @@
  * @param   enmState    Which state to sync
  */
-static DECLCALLBACK(void) ftmR3PerformSync(PVM pVM, FTMSYNCSTATE enmState)
+static int ftmR3PerformSync(PVM pVM, FTMSYNCSTATE enmState)
 {
     int rc;
@@ -592,5 +610,5 @@
     {
         rc = VMR3Suspend(pVM);
-        AssertReturnVoid(RT_SUCCESS(rc));
+        AssertRCReturn(rc, rc);
     }
 
@@ -604,4 +622,6 @@
         bool fSuspended = false;
 
+        STAM_REL_COUNTER_INC((fFullSync) ? &pVM->ftm.s.StatFullSync : &pVM->ftm.s.StatDeltaVM);
+
         rc = ftmR3TcpSubmitCommand(pVM, (fFullSync) ? "full-sync" : "checkpoint");
         AssertRC(rc);
@@ -619,15 +639,18 @@
     case FTMSYNCSTATE_DELTA_MEMORY:
         /* Nothing to do as we sync the memory in an async thread; no need to block EMT. */
+        STAM_REL_COUNTER_INC(&pVM->ftm.s.StatDeltaMem);
         break;
     }
+
     /* Write protect all memory. */
-    rc = PGMR3PhysWriteProtectRAM(pVM);
-    AssertRC(rc);
+    rc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)ftmR3WriteProtectMemory, 1, pVM);
+    AssertRCReturn(rc, rc);
 
     if (enmState != FTMSYNCSTATE_DELTA_MEMORY)
     {
         rc = VMR3Resume(pVM);
-        AssertRC(rc);
-    }
+        AssertRCReturn(rc, rc);
+    }
+    return VINF_SUCCESS;
 }
 
@@ -725,6 +748,5 @@
      */
 
-    rc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)ftmR3PerformSync, 2, pVM, FTMSYNCSTATE_FULL);
-    AssertRC(rc);
+    rc = ftmR3PerformSync(pVM, FTMSYNCSTATE_FULL);
 
     for (;;)
@@ -743,6 +765,5 @@
 
             /* sync the changed memory with the standby node. */
-            rc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)ftmR3PerformSync, 2, pVM, FTMSYNCSTATE_DELTA_MEMORY);
-            AssertRC(rc);
+            rc = ftmR3PerformSync(pVM, FTMSYNCSTATE_DELTA_MEMORY);
 
             /* Enumerate all dirty pages and send them to the standby VM. */
@@ -1045,4 +1066,6 @@
 VMMR3DECL(int) FTMR3SyncState(PVM pVM)
 {
+    VM_ASSERT_OTHER_THREAD(pVM);
+
     if (!pVM->fFaultTolerantMaster)
         return VINF_SUCCESS;
@@ -1060,6 +1083,5 @@
 
     /* Sync state + changed memory with the standby node. */
-    rc = VMR3ReqCallWait(pVM, VMCPUID_ANY, (PFNRT)ftmR3PerformSync, 2, pVM, FTMSYNCSTATE_DELTA_VM);
-    AssertRC(rc);
+    rc = ftmR3PerformSync(pVM, FTMSYNCSTATE_DELTA_VM);
 
     PDMCritSectLeave(&pVM->ftm.s.CritSect);
Index: trunk/src/VBox/VMM/FTMInternal.h
===================================================================
--- trunk/src/VBox/VMM/FTMInternal.h	(revision 32101)
+++ trunk/src/VBox/VMM/FTMInternal.h	(revision 32102)
@@ -100,4 +100,7 @@
     STAMCOUNTER         StatSentMem;
     STAMCOUNTER         StatSentState;
+    STAMCOUNTER         StatDeltaMem;
+    STAMCOUNTER         StatDeltaVM;
+    STAMCOUNTER         StatFullSync;
 } FTM;
 AssertCompileMemberAlignment(FTM, CritSect, 8);
