Index: /trunk/include/VBox/vmm/pdmdev.h
===================================================================
--- /trunk/include/VBox/vmm/pdmdev.h	(revision 38846)
+++ /trunk/include/VBox/vmm/pdmdev.h	(revision 38847)
@@ -76,5 +76,8 @@
  *
  * @returns VBox status.
- * @param   pDevIns     The device instance data.
+ * @param   pDevIns     The device instance data. 
+ *  
+ * @remarks The device critical section is not entered.  The routine may delete 
+ *          the critical section, so the caller cannot exit it.
  */
 typedef DECLCALLBACK(int)   FNPDMDEVDESTRUCT(PPDMDEVINS pDevIns);
@@ -96,5 +99,8 @@
  * @param   offDelta    The relocation delta relative to the old location.
  *
- * @remark  A relocation CANNOT fail.
+ * @remarks A relocation CANNOT fail.
+ *  
+ * @remarks The device critical section is not entered.  The relocations should 
+ *          not normally require any locking.
  */
 typedef DECLCALLBACK(void) FNPDMDEVRELOCATE(PPDMDEVINS pDevIns, RTGCINTPTR offDelta);
@@ -117,4 +123,6 @@
  * @param   cbOut       Size of output data.
  * @param   pcbOut      Where to store the actual size of the output data.
+ *  
+ * @remarks Not used.
  */
 typedef DECLCALLBACK(int) FNPDMDEVIOCTL(PPDMDEVINS pDevIns, RTUINT uFunction,
@@ -129,4 +137,6 @@
  * @returns VBox status.
  * @param   pDevIns     The device instance data.
+ *  
+ * @remarks Caller enters the device critical section.
  */
 typedef DECLCALLBACK(void)   FNPDMDEVPOWERON(PPDMDEVINS pDevIns);
@@ -139,4 +149,6 @@
  * @returns VBox status.
  * @param   pDevIns     The device instance data.
+ *  
+ * @remarks Caller enters the device critical section.
  */
 typedef DECLCALLBACK(void)  FNPDMDEVRESET(PPDMDEVINS pDevIns);
@@ -150,4 +162,6 @@
  * @param   pDevIns     The device instance data.
  * @thread  EMT(0)
+ *  
+ * @remarks Caller enters the device critical section.
  */
 typedef DECLCALLBACK(void)  FNPDMDEVSUSPEND(PPDMDEVINS pDevIns);
@@ -160,4 +174,6 @@
  * @returns VBox status.
  * @param   pDevIns     The device instance data.
+ *  
+ * @remarks Caller enters the device critical section.
  */
 typedef DECLCALLBACK(void)  FNPDMDEVRESUME(PPDMDEVINS pDevIns);
@@ -174,4 +190,6 @@
  * @param   pDevIns     The device instance data.
  * @thread  EMT(0)
+ *  
+ * @remarks Caller enters the device critical section.
  */
 typedef DECLCALLBACK(void)   FNPDMDEVPOWEROFF(PPDMDEVINS pDevIns);
@@ -192,4 +210,6 @@
  * @param   iLUN        The logical unit which is being detached.
  * @param   fFlags      Flags, combination of the PDM_TACH_FLAGS_* \#defines.
+ *  
+ * @remarks Caller enters the device critical section.
  */
 typedef DECLCALLBACK(int)  FNPDMDEVATTACH(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags);
@@ -209,4 +229,6 @@
  * @param   iLUN        The logical unit which is being detached.
  * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
+ *  
+ * @remarks Caller enters the device critical section.
  */
 typedef DECLCALLBACK(void)  FNPDMDEVDETACH(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags);
@@ -221,4 +243,6 @@
  * @param   iLUN        The logicial unit to query.
  * @param   ppBase      Where to store the pointer to the base interface of the LUN.
+ *  
+ * @remarks The device critical section is not entered.
  */
 typedef DECLCALLBACK(int) FNPDMDEVQUERYINTERFACE(PPDMDEVINS pDevIns, unsigned iLUN, PPDMIBASE *ppBase);
@@ -233,4 +257,6 @@
  * @returns VBOX status code.
  * @param   pDevIns     The device instance.
+ *  
+ * @remarks Caller enters the device critical section.
  */
 typedef DECLCALLBACK(int) FNPDMDEVINITCOMPLETE(PPDMDEVINS pDevIns);
@@ -273,27 +299,39 @@
     /** Construct instance - required. */
     PFNPDMDEVCONSTRUCT  pfnConstruct;
-    /** Destruct instance - optional. */
+    /** Destruct instance - optional.
+     * Critical section NOT entered (will be destroyed).  */
     PFNPDMDEVDESTRUCT   pfnDestruct;
-    /** Relocation command - optional. */
+    /** Relocation command - optional.
+     * Critical section NOT entered. */ 
     PFNPDMDEVRELOCATE   pfnRelocate;
-    /** I/O Control interface - optional. */
+    /** I/O Control interface - optional.
+     * Not used.  */
     PFNPDMDEVIOCTL      pfnIOCtl;
-    /** Power on notification - optional. */
+    /** Power on notification - optional.
+     * Critical section is entered. */ 
     PFNPDMDEVPOWERON    pfnPowerOn;
-    /** Reset notification - optional. */
+    /** Reset notification - optional. 
+     * Critical section is entered. */ 
     PFNPDMDEVRESET      pfnReset;
-    /** Suspend notification  - optional. */
+    /** Suspend notification  - optional. 
+     * Critical section is entered. */ 
     PFNPDMDEVSUSPEND    pfnSuspend;
-    /** Resume notification - optional. */
+    /** Resume notification - optional. 
+     * Critical section is entered. */ 
     PFNPDMDEVRESUME     pfnResume;
-    /** Attach command - optional. */
+    /** Attach command - optional. 
+     * Critical section is entered. */ 
     PFNPDMDEVATTACH     pfnAttach;
-    /** Detach notification - optional. */
+    /** Detach notification - optional. 
+     * Critical section is entered. */ 
     PFNPDMDEVDETACH     pfnDetach;
-    /** Query a LUN base interface - optional. */
+    /** Query a LUN base interface - optional.
+     * Critical section is NOT entered. */ 
     PFNPDMDEVQUERYINTERFACE pfnQueryInterface;
-    /** Init complete notification - optional. */
+    /** Init complete notification - optional. 
+     * Critical section is entered. */ 
     PFNPDMDEVINITCOMPLETE   pfnInitComplete;
-    /** Power off notification - optional. */
+    /** Power off notification - optional. 
+     * Critical section is entered. */ 
     PFNPDMDEVPOWEROFF   pfnPowerOff;
     /** @todo */
@@ -3863,6 +3901,7 @@
     /** The critical section for the device.
      *
-     * TM and IOM will enter this critical section before calling into the
-     * device code.  SSM will currently not, but this will be changed later on.
+     * TM and IOM will enter this critical section before calling into the device 
+     * code.  PDM will when doing power on, power off, reset, suspend and resume 
+     * notifications.  SSM will currently not, but this will be changed later on. 
      *
      * The device gets a critical section automatically assigned to it before
Index: /trunk/src/VBox/VMM/VMMR3/PDM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDM.cpp	(revision 38846)
+++ /trunk/src/VBox/VMM/VMMR3/PDM.cpp	(revision 38847)
@@ -1057,5 +1057,7 @@
     {
         LogFlow(("PDMR3PowerOn: Notifying - device '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
+        PDMCritSectEnter(pDevIns->pCritSectRoR3, VERR_IGNORED);
         int rc = VINF_SUCCESS; pDevIns->pReg->pfnPowerOn(pDevIns);
+        PDMCritSectLeave(pDevIns->pCritSectRoR3);
         if (RT_FAILURE(rc))
         {
@@ -1343,4 +1345,7 @@
         if (pDevIns->pReg->pfnReset)
         {
+            uint64_t cNsElapsed = RTTimeNanoTS();
+            PDMCritSectEnter(pDevIns->pCritSectRoR3, VERR_IGNORED);
+
             if (!pDevIns->Internal.s.pfnAsyncNotify)
             {
@@ -1360,4 +1365,10 @@
                 pdmR3NotifyAsyncAdd(pAsync, pDevIns->Internal.s.pDevR3->pReg->szName, pDevIns->iInstance);
             }
+
+            PDMCritSectLeave(pDevIns->pCritSectRoR3);
+            cNsElapsed = RTTimeNanoTS() - cNsElapsed;
+            if (cNsElapsed >= PDMSUSPEND_WARN_AT_NS)
+                LogRel(("PDMR3Reset: device '%s'/%d took %'llu ns to reset\n",
+                        pDevIns->pReg->szName, pDevIns->iInstance, cNsElapsed));
         }
     }
@@ -1580,4 +1591,5 @@
         {
             uint64_t cNsElapsed = RTTimeNanoTS();
+            PDMCritSectEnter(pDevIns->pCritSectRoR3, VERR_IGNORED);
 
             if (!pDevIns->Internal.s.pfnAsyncNotify)
@@ -1599,4 +1611,5 @@
             }
 
+            PDMCritSectLeave(pDevIns->pCritSectRoR3);
             cNsElapsed = RTTimeNanoTS() - cNsElapsed;
             if (cNsElapsed >= PDMSUSPEND_WARN_AT_NS)
@@ -1756,5 +1769,7 @@
     {
         LogFlow(("PDMR3Resume: Notifying - device '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
+        PDMCritSectEnter(pDevIns->pCritSectRoR3, VERR_IGNORED);
         int rc = VINF_SUCCESS; pDevIns->pReg->pfnResume(pDevIns);
+        PDMCritSectLeave(pDevIns->pCritSectRoR3);
         if (RT_FAILURE(rc))
         {
@@ -1939,4 +1954,5 @@
         {
             uint64_t cNsElapsed = RTTimeNanoTS();
+            PDMCritSectEnter(pDevIns->pCritSectRoR3, VERR_IGNORED);
 
             if (!pDevIns->Internal.s.pfnAsyncNotify)
@@ -1958,4 +1974,5 @@
             }
 
+            PDMCritSectLeave(pDevIns->pCritSectRoR3);
             cNsElapsed = RTTimeNanoTS() - cNsElapsed;
             if (cNsElapsed >= PDMPOWEROFF_WARN_AT_NS)
Index: /trunk/src/VBox/VMM/VMMR3/PDMDevice.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMDevice.cpp	(revision 38846)
+++ /trunk/src/VBox/VMM/VMMR3/PDMDevice.cpp	(revision 38847)
@@ -420,5 +420,7 @@
         if (pDevIns->pReg->pfnInitComplete)
         {
+            PDMCritSectEnter(pDevIns->pCritSectRoR3, VERR_IGNORED);
             rc = pDevIns->pReg->pfnInitComplete(pDevIns);
+            PDMCritSectLeave(pDevIns->pCritSectRoR3);
             if (RT_FAILURE(rc))
             {
@@ -796,5 +798,7 @@
             if (!pLun->pTop)
             {
+                PDMCritSectEnter(pDevIns->pCritSectRoR3, VERR_IGNORED);
                 rc = pDevIns->pReg->pfnAttach(pDevIns, iLun, fFlags);
+                PDMCritSectLeave(pDevIns->pCritSectRoR3);
             }
             else
@@ -904,7 +908,9 @@
             if (pDevIns->pReg->pfnAttach)
             {
+                PDMCritSectEnter(pDevIns->pCritSectRoR3, VERR_IGNORED);
                 rc = pDevIns->pReg->pfnAttach(pDevIns, iLun, fFlags);
                 if (RT_SUCCESS(rc) && ppBase)
                     *ppBase = pLun->pTop ? &pLun->pTop->IBase : NULL;
+                PDMCritSectLeave(pDevIns->pCritSectRoR3);
             }
             else
Index: /trunk/src/VBox/VMM/VMMR3/PDMDriver.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMDriver.cpp	(revision 38846)
+++ /trunk/src/VBox/VMM/VMMR3/PDMDriver.cpp	(revision 38847)
@@ -641,5 +641,9 @@
             pLun->pTop = NULL;
             if (!(fFlags & PDM_TACH_FLAGS_NO_CALLBACKS) && pLun->pDevIns->pReg->pfnDetach)
+            {
+                PDMCritSectEnter(pLun->pDevIns->pCritSectRoR3, VERR_IGNORED);
                 pLun->pDevIns->pReg->pfnDetach(pLun->pDevIns, pLun->iLun, fFlags);
+                PDMCritSectLeave(pLun->pDevIns->pCritSectRoR3);
+            }
         }
 
