Index: /trunk/src/VBox/VMM/VMMR3/SSM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/SSM.cpp	(revision 44504)
+++ /trunk/src/VBox/VMM/VMMR3/SSM.cpp	(revision 44505)
@@ -147,4 +147,6 @@
 #include <VBox/vmm/ssm.h>
 #include <VBox/vmm/dbgf.h>
+#include <VBox/vmm/pdmapi.h>
+#include <VBox/vmm/pdmcritsect.h>
 #include <VBox/vmm/mm.h>
 #include "SSMInternal.h"
@@ -1253,4 +1255,5 @@
         pUnit->u.Dev.pfnLoadDone = pfnLoadDone;
         pUnit->u.Dev.pDevIns = pDevIns;
+        pUnit->pCritSect = PDMR3DevGetCritSect(pVM, pDevIns);
     }
     return rc;
@@ -4239,4 +4242,37 @@
 
 
+
+/**
+ * Enters the critical session (optionally) associated with the unit.
+ *
+ * @param   pUnit               The unit.
+ */
+DECLINLINE(void) ssmR3UnitCritSectEnter(PSSMUNIT pUnit)
+{
+    PPDMCRITSECT pCritSect = pUnit->pCritSect;
+    if (pCritSect)
+    {
+        int rc = PDMCritSectEnter(pCritSect, VERR_IGNORED);
+        AssertRC(rc);
+    }
+}
+
+
+/**
+ * Leaves the critical session (optionally) associated with the unit.
+ *
+ * @param   pUnit               The unit.
+ */
+DECLINLINE(void) ssmR3UnitCritSectLeave(PSSMUNIT pUnit)
+{
+    PPDMCRITSECT pCritSect = pUnit->pCritSect;
+    if (pCritSect)
+    {
+        int rc = PDMCritSectLeave(pCritSect);
+        AssertRC(rc);
+    }
+}
+
+
 /**
  * Do the pfnSaveDone run.
@@ -4262,4 +4298,5 @@
             int rcOld = pSSM->rc;
             int rc;
+            ssmR3UnitCritSectEnter(pUnit);
             switch (pUnit->enmType)
             {
@@ -4280,4 +4317,5 @@
                     break;
             }
+            ssmR3UnitCritSectLeave(pUnit);
             if (RT_SUCCESS(rc) && pSSM->rc != rcOld)
                 rc = pSSM->rc;
@@ -4609,4 +4647,5 @@
          */
         ssmR3DataWriteBegin(pSSM);
+        ssmR3UnitCritSectEnter(pUnit);
         switch (pUnit->enmType)
         {
@@ -4628,4 +4667,5 @@
                 break;
         }
+        ssmR3UnitCritSectLeave(pUnit);
         pUnit->fCalled = true;
         if (RT_FAILURE(rc) && RT_SUCCESS_NP(pSSM->rc))
@@ -4697,4 +4737,5 @@
         {
             int rc;
+            ssmR3UnitCritSectEnter(pUnit);
             switch (pUnit->enmType)
             {
@@ -4715,4 +4756,5 @@
                     break;
             }
+            ssmR3UnitCritSectLeave(pUnit);
             pUnit->fCalled = true;
             if (RT_FAILURE(rc) && RT_SUCCESS_NP(pSSM->rc))
@@ -5038,4 +5080,5 @@
         {
             int rc;
+            ssmR3UnitCritSectEnter(pUnit);
             switch (pUnit->enmType)
             {
@@ -5056,4 +5099,5 @@
                     break;
             }
+            ssmR3UnitCritSectLeave(pUnit);
             pUnit->fCalled = true;
             Assert(pSSM->rc == VINF_SUCCESS);
@@ -5176,4 +5220,5 @@
          */
         ssmR3DataWriteBegin(pSSM);
+        ssmR3UnitCritSectEnter(pUnit);
         switch (pUnit->enmType)
         {
@@ -5194,4 +5239,5 @@
                 break;
         }
+        ssmR3UnitCritSectLeave(pUnit);
         pUnit->fCalled = true;
         if (RT_FAILURE(rc) && RT_SUCCESS_NP(pSSM->rc))
@@ -5333,4 +5379,5 @@
         {
             int rc;
+            ssmR3UnitCritSectEnter(pUnit);
             switch (pUnit->enmType)
             {
@@ -5351,4 +5398,5 @@
                     break;
             }
+            ssmR3UnitCritSectLeave(pUnit);
             pUnit->fCalled = true;
             if (RT_FAILURE(rc) && RT_SUCCESS_NP(pSSM->rc))
@@ -7918,4 +7966,5 @@
                             break;
                         }
+                        ssmR3UnitCritSectEnter(pUnit);
                         switch (pUnit->enmType)
                         {
@@ -7936,4 +7985,5 @@
                                 break;
                         }
+                        ssmR3UnitCritSectLeave(pUnit);
                         pUnit->fCalled = true;
                         if (RT_FAILURE(rc) && RT_SUCCESS_NP(pSSM->rc))
@@ -8181,4 +8231,5 @@
             pSSM->u.Read.pCurUnit     = pUnit;
             ssmR3DataReadBeginV2(pSSM);
+            ssmR3UnitCritSectEnter(pUnit);
             switch (pUnit->enmType)
             {
@@ -8199,4 +8250,5 @@
                     break;
             }
+            ssmR3UnitCritSectLeave(pUnit);
             pUnit->fCalled = true;
             if (RT_FAILURE(rc) && RT_SUCCESS_NP(pSSM->rc))
@@ -8351,4 +8403,5 @@
                 Handle.u.Read.pCurUnit = pUnit;
                 pUnit->fCalled = true;
+                ssmR3UnitCritSectEnter(pUnit);
                 switch (pUnit->enmType)
                 {
@@ -8369,4 +8422,5 @@
                         break;
                 }
+                ssmR3UnitCritSectLeave(pUnit);
                 Handle.u.Read.pCurUnit = NULL;
                 if (RT_FAILURE(rc) && RT_SUCCESS_NP(Handle.rc))
@@ -8422,4 +8476,5 @@
                 int const rcOld = Handle.rc;
                 rc = VINF_SUCCESS;
+                ssmR3UnitCritSectEnter(pUnit);
                 switch (pUnit->enmType)
                 {
@@ -8440,4 +8495,5 @@
                         break;
                 }
+                ssmR3UnitCritSectLeave(pUnit);
                 Handle.u.Read.pCurUnit = NULL;
                 if (RT_SUCCESS(rc) && Handle.rc != rcOld)
Index: /trunk/src/VBox/VMM/include/SSMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/SSMInternal.h	(revision 44504)
+++ /trunk/src/VBox/VMM/include/SSMInternal.h	(revision 44505)
@@ -200,4 +200,6 @@
      * This is used for constructing the directory. */
     RTFOFF                  offStream;
+    /** Critical section to be taken before working any of the callbacks. */
+    PPDMCRITSECT            pCritSect;
     /** The guessed size of the data unit - used only for progress indication. */
     size_t                  cbGuess;
