Index: trunk/include/VBox/vmm/iom.h
===================================================================
--- trunk/include/VBox/vmm/iom.h	(revision 37464)
+++ trunk/include/VBox/vmm/iom.h	(revision 37466)
@@ -264,6 +264,4 @@
 VMMR3_INT_DECL(int)  IOMR3MmioDeregister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange);
 
-VMMR3DECL(PPDMCRITSECT) IOMR3GetCritSect(PVM pVM);
-
 /** @} */
 #endif /* IN_RING3 */
Index: trunk/include/VBox/vmm/pdmapi.h
===================================================================
--- trunk/include/VBox/vmm/pdmapi.h	(revision 37464)
+++ trunk/include/VBox/vmm/pdmapi.h	(revision 37466)
@@ -122,4 +122,5 @@
 VMMR3DECL(int)  PDMR3DeviceAttach(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, uint32_t fFlags, PPDMIBASE *ppBase);
 VMMR3DECL(int)  PDMR3DeviceDetach(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, uint32_t fFlags);
+VMMR3_INT_DECL(PPDMCRITSECT) PDMR3DevGetCritSect(PVM pVM, PPDMDEVINS pDevIns);
 VMMR3DECL(int)  PDMR3DriverAttach(PVM pVM, const char *pszDevice, unsigned iDevIns, unsigned iLun, uint32_t fFlags, PPPDMIBASE ppBase);
 VMMR3DECL(int)  PDMR3DriverDetach(PVM pVM, const char *pszDevice, unsigned iDevIns, unsigned iLun,
Index: trunk/include/VBox/vmm/pdmdev.h
===================================================================
--- trunk/include/VBox/vmm/pdmdev.h	(revision 37464)
+++ trunk/include/VBox/vmm/pdmdev.h	(revision 37466)
@@ -2943,4 +2943,16 @@
 
     /**
+     * Changes the device level critical section from the automatically created
+     * default to one desired by the device constructor.
+     *
+     * @returns VBox status code.
+     * @param   pDevIns             The device instance.
+     * @param   pCritSect           The critical section to use.  NULL is not
+     *                              valid, instead use the NOP critical
+     *                              section.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnSetDeviceCritSect,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
+
+    /**
      * Creates a PDM thread.
      *
@@ -3422,5 +3434,5 @@
 
 /** Current PDMDEVHLPR3 version number. */
-#define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE(0xffe7, 5, 0)
+#define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE(0xffe7, 7, 0)
 
 
@@ -3830,8 +3842,6 @@
     /** Pointer to device instance data. */
     RTRCPTR                     pvInstanceDataRC;
-    /** The critical section for the device, see pCritSectR3.
-     * This is automatically resolved by PDM when pCritSectR3 is set by the
-     * constructor. */
-    RCPTRTYPE(PPDMCRITSECT)     pCritSectRC;
+    /** The critical section for the device, see pCritSectXR3. */
+    RCPTRTYPE(PPDMCRITSECT)     pCritSectRoRC;
     /** Alignment padding.  */
     RTRCPTR                     pAlignmentRC;
@@ -3841,8 +3851,6 @@
     /** Pointer to device instance data (R0). */
     RTR0PTR                     pvInstanceDataR0;
-    /** The critical section for the device, see pCritSectR3.
-    * This is automatically resolved by PDM when pCritSectR3 is set by the
-    * constructor. */
-    R0PTRTYPE(PPDMCRITSECT)     pCritSectR0;
+    /** The critical section for the device, see pCritSectXR3. */
+    R0PTRTYPE(PPDMCRITSECT)     pCritSectRoR0;
 
     /** Pointer the HC PDM Device API. */
@@ -3850,14 +3858,15 @@
     /** Pointer to device instance data. */
     RTR3PTR                     pvInstanceDataR3;
-    /** The critical section for the device. (Optional)
-     *
-     * The device constructor initializes this if it has a critical section for
-     * the device and desires it to be taken automatically by MMIO, I/O port
-     * and timer callbacks to the device.  The advantages using this locking
-     * approach is both less code and avoiding the global IOM lock.
-     *
-     * @remarks Will not yet be taken by SSM.
-     */
-    R3PTRTYPE(PPDMCRITSECT)     pCritSectR3;
+    /** 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.
+     *
+     * The device gets a critical section automatically assigned to it before
+     * the constructor is called.  If the constructor wishes to use a different
+     * critical section, it calls PDMDevHlpSetDeviceCritSect() to change it
+     * very early on.
+     */
+    R3PTRTYPE(PPDMCRITSECT)     pCritSectRoR3;
 
     /** Pointer to device registration structure.  */
@@ -4562,4 +4571,12 @@
 
 /**
+ * @copydoc PDMDEVHLPR3::pfnSetDeviceCritSect
+ */
+DECLINLINE(int) PDMDevHlpSetDeviceCritSect(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
+{
+    return pDevIns->pHlpR3->pfnSetDeviceCritSect(pDevIns, pCritSect);
+}
+
+/**
  * @copydoc PDMDEVHLPR3::pfnThreadCreate
  */
