Index: /trunk/include/VBox/err.h
===================================================================
--- /trunk/include/VBox/err.h	(revision 41846)
+++ /trunk/include/VBox/err.h	(revision 41847)
@@ -569,8 +569,4 @@
 /** PCI passthru is not supported by this build. */
 #define VERR_PGM_PCI_PASSTHRU_MISCONFIG         (-1682)
-/** PCI physical read with bus mastering disabled. */
-#define VINF_PGM_PCI_PHYS_READ_BM_DISABLED      (1683)
-/** PCI physical write with bus mastering disabled. */
-#define VINF_PGM_PCI_PHYS_WRITE_BM_DISABLED     (1684)
 /** @} */
 
@@ -1215,7 +1211,11 @@
  * misconfiguration or in rare cases a buggy pci device. */
 #define VERR_PDM_NO_PCI_BUS                         (-2833)
+/** PCI physical read with bus mastering disabled. */
+#define VINF_PDM_PCI_PHYS_READ_BM_DISABLED          (2833)
 /** The device is not a registered PCI device and thus cannot
  * perform any PCI operations. The device forgot to register it self. */
 #define VERR_PDM_NOT_PCI_DEVICE                     (-2834)
+/** PCI physical write with bus mastering disabled. */
+#define VINF_PDM_PCI_PHYS_WRITE_BM_DISABLED         (2834)
 
 /** The version of the device registration structure is unknown
Index: /trunk/include/VBox/vmm/pdmdev.h
===================================================================
--- /trunk/include/VBox/vmm/pdmdev.h	(revision 41846)
+++ /trunk/include/VBox/vmm/pdmdev.h	(revision 41847)
@@ -2189,5 +2189,5 @@
 typedef struct PDMDEVHLPR3
 {
-    /** Structure version. PDM_DEVHLP_VERSION defines the current version. */
+    /** Structure version. PDM_DEVHLPR3_VERSION defines the current version. */
     uint32_t                        u32Version;
 
@@ -2857,4 +2857,20 @@
     DECLR3CALLBACKMEMBER(void, pfnSTAMRegisterV,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
                                                  STAMUNIT enmUnit, const char *pszDesc, const char *pszName, va_list args));
+
+    /**
+     * Reads data via bus mastering, if enabled. If no bus mastering is available,
+     * this function does nothing and returns VINF_PGM_PCI_PHYS_READ_BM_DISABLED.
+     *
+     * @return  IPRT status code.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
+
+    /**
+     * Writes data via bus mastering, if enabled. If no bus mastering is available,
+     * this function does nothing and returns VINF_PGM_PCI_PHYS_WRITE_BM_DISABLED.
+     *
+     * @return  IPRT status code.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
 
     /**
@@ -3511,5 +3527,5 @@
     /** @} */
 
-    /** Just a safety precaution. (PDM_DEVHLP_VERSION) */
+    /** Just a safety precaution. (PDM_DEVHLPR3_VERSION) */
     uint32_t                        u32TheEnd;
 } PDMDEVHLPR3;
@@ -3521,5 +3537,5 @@
 
 /** Current PDMDEVHLPR3 version number. */
-#define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE(0xffe7, 8, 0)
+#define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE(0xffe7, 9, 0)
 
 
@@ -3531,4 +3547,20 @@
     /** Structure version. PDM_DEVHLPRC_VERSION defines the current version. */
     uint32_t                    u32Version;
+
+    /**
+     * Reads data via bus mastering, if enabled. If no bus mastering is available,
+     * this function does nothing and returns VINF_PGM_PCI_PHYS_READ_BM_DISABLED.
+     *
+     * @return  IPRT status code.
+     */
+    DECLRCCALLBACKMEMBER(int, pfnPCIDevPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
+
+    /**
+     * Writes data via bus mastering, if enabled. If no bus mastering is available,
+     * this function does nothing and returns VINF_PGM_PCI_PHYS_WRITE_BM_DISABLED.
+     *
+     * @return  IPRT status code.
+     */
+    DECLRCCALLBACKMEMBER(int, pfnPCIDevPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
 
     /**
@@ -3712,5 +3744,5 @@
 
 /** Current PDMDEVHLP version number. */
-#define PDM_DEVHLPRC_VERSION                    PDM_VERSION_MAKE(0xffe6, 2, 0)
+#define PDM_DEVHLPRC_VERSION                    PDM_VERSION_MAKE(0xffe6, 3, 0)
 
 
@@ -3722,4 +3754,20 @@
     /** Structure version. PDM_DEVHLPR0_VERSION defines the current version. */
     uint32_t                    u32Version;
+
+    /**
+     * Reads data via bus mastering, if enabled. If no bus mastering is available,
+     * this function does nothing and returns VINF_PGM_PCI_PHYS_READ_BM_DISABLED.
+     *
+     * @return  IPRT status code.
+     */
+    DECLR0CALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
+
+    /**
+     * Writes data via bus mastering, if enabled. If no bus mastering is available,
+     * this function does nothing and returns VINF_PGM_PCI_PHYS_WRITE_BM_DISABLED.
+     *
+     * @return  IPRT status code.
+     */
+    DECLR0CALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
 
     /**
@@ -3911,5 +3959,5 @@
 
 /** Current PDMDEVHLP version number. */
-#define PDM_DEVHLPR0_VERSION                    PDM_VERSION_MAKE(0xffe5, 2, 0)
+#define PDM_DEVHLPR0_VERSION                    PDM_VERSION_MAKE(0xffe5, 3, 0)
 
 
@@ -4641,5 +4689,5 @@
               PCIDevGetVendorId(pPciDev), PCIDevGetDeviceId(pPciDev), pvBuf, cbRead));
 #endif
-        return VINF_PGM_PCI_PHYS_READ_BM_DISABLED;
+        return VINF_PDM_PCI_PHYS_READ_BM_DISABLED;
     }
 
@@ -4665,5 +4713,5 @@
               PCIDevGetVendorId(pPciDev), PCIDevGetDeviceId(pPciDev), pvBuf, cbWrite));
 #endif
-        return VINF_PGM_PCI_PHYS_WRITE_BM_DISABLED;
+        return VINF_PDM_PCI_PHYS_WRITE_BM_DISABLED;
     }
 
Index: /trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp	(revision 41846)
+++ /trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp	(revision 41847)
@@ -57,4 +57,11 @@
 
 /*******************************************************************************
+*   Prototypes                                                                 *
+*******************************************************************************/
+static int pdmR0DevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead);
+static int pdmR0DevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite);
+
+
+/*******************************************************************************
 *   Internal Functions                                                         *
 *******************************************************************************/
@@ -66,4 +73,50 @@
  * @{
  */
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnPCIPhysRead} */
+static DECLCALLBACK(int) pdmR0DevHlp_PCIPhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmR0DevHlp_PCIPhysRead: caller=%p/%d: GCPhys=%RGp pvBuf=%p cbRead=%#x\n",
+             pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbRead));
+
+    PCIDevice *pPciDev = pDevIns->Internal.s.pPciDeviceR0;
+    AssertPtrReturn(pPciDev, VERR_INVALID_POINTER);
+
+    if (!PCIDevIsBusmaster(pPciDev))
+    {
+#ifdef DEBUG
+        LogFlow(("%s: %RU16:%RU16: No bus master (anymore), skipping read %p (%z)\n", __FUNCTION__,
+                 PCIDevGetVendorId(pPciDev), PCIDevGetDeviceId(pPciDev), pvBuf, cbRead));
+#endif
+        return VINF_PDM_PCI_PHYS_READ_BM_DISABLED;
+    }
+
+    return pdmR0DevHlp_PhysRead(pDevIns, GCPhys, pvBuf, cbRead);
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnPCIPhysRead} */
+static DECLCALLBACK(int) pdmR0DevHlp_PCIPhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmR0DevHlp_PCIPhysWrite: caller=%p/%d: GCPhys=%RGp pvBuf=%p cbWrite=%#x\n",
+             pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbWrite));
+
+    PCIDevice *pPciDev = pDevIns->Internal.s.pPciDeviceR0;
+    AssertPtrReturn(pPciDev, VERR_INVALID_POINTER);
+
+    if (!PCIDevIsBusmaster(pPciDev))
+    {
+#ifdef DEBUG
+        LogFlow(("%s: %RU16:%RU16: No bus master (anymore), skipping write %p (%z)\n", __FUNCTION__,
+                 PCIDevGetVendorId(pPciDev), PCIDevGetDeviceId(pPciDev), pvBuf, cbWrite));
+#endif
+        return VINF_PDM_PCI_PHYS_WRITE_BM_DISABLED;
+    }
+
+    return pdmR0DevHlp_PhysWrite(pDevIns, GCPhys, pvBuf, cbWrite);
+}
+
 
 /** @interface_method_impl{PDMDEVHLPR0,pfnPCISetIrq} */
@@ -331,4 +384,6 @@
 {
     PDM_DEVHLPR0_VERSION,
+    pdmR0DevHlp_PCIPhysRead,
+    pdmR0DevHlp_PCIPhysWrite,
     pdmR0DevHlp_PCISetIrq,
     pdmR0DevHlp_ISASetIrq,
Index: /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp	(revision 41846)
+++ /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp	(revision 41847)
@@ -1063,4 +1063,20 @@
 
     NOREF(pVM);
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnPCIDevPhysRead} */
+static DECLCALLBACK(int) pdmR3DevHlp_PCIPhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return PDMDevHlpPCIDevPhysRead(pDevIns->Internal.s.pPciDeviceR3, GCPhys, pvBuf, cbRead);
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnPCIDevPhysWrite} */
+static DECLCALLBACK(int) pdmR3DevHlp_PCIPhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return PDMDevHlpPCIDevPhysWrite(pDevIns->Internal.s.pPciDeviceR3, GCPhys, pvBuf, cbWrite);
 }
 
@@ -3344,4 +3360,6 @@
     pdmR3DevHlp_STAMRegisterF,
     pdmR3DevHlp_STAMRegisterV,
+    pdmR3DevHlp_PCIPhysRead,
+    pdmR3DevHlp_PCIPhysWrite,
     pdmR3DevHlp_PCIRegister,
     pdmR3DevHlp_PCIRegisterMsi,
@@ -3563,4 +3581,6 @@
     pdmR3DevHlp_STAMRegisterF,
     pdmR3DevHlp_STAMRegisterV,
+    pdmR3DevHlp_PCIPhysRead,
+    pdmR3DevHlp_PCIPhysWrite,
     pdmR3DevHlp_PCIRegister,
     pdmR3DevHlp_PCIRegisterMsi,
Index: /trunk/src/VBox/VMM/VMMRC/PDMRCDevice.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMRC/PDMRCDevice.cpp	(revision 41846)
+++ /trunk/src/VBox/VMM/VMMRC/PDMRCDevice.cpp	(revision 41847)
@@ -55,4 +55,11 @@
 
 /*******************************************************************************
+*   Prototypes                                                                 *
+*******************************************************************************/
+static int pdmRCDevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead);
+static int pdmRCDevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite);
+
+
+/*******************************************************************************
 *   Internal Functions                                                         *
 *******************************************************************************/
@@ -63,4 +70,50 @@
  * @{
  */
+
+/** @interface_method_impl{PDMDEVHLPRC,pfnPCIPhysRead} */
+static DECLCALLBACK(int) pdmRCDevHlp_PCIPhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmRCDevHlp_PCIPhysRead: caller=%p/%d: GCPhys=%RGp pvBuf=%p cbRead=%#x\n",
+             pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbRead));
+
+    PCIDevice *pPciDev = pDevIns->Internal.s.pPciDeviceRC;
+    AssertPtrReturn(pPciDev, VERR_INVALID_POINTER);
+
+    if (!PCIDevIsBusmaster(pPciDev))
+    {
+#ifdef DEBUG
+        LogFlow(("%s: %RU16:%RU16: No bus master (anymore), skipping read %p (%z)\n", __FUNCTION__,
+                 PCIDevGetVendorId(pPciDev), PCIDevGetDeviceId(pPciDev), pvBuf, cbRead));
+#endif
+        return VINF_PDM_PCI_PHYS_READ_BM_DISABLED;
+    }
+
+    return pdmRCDevHlp_PhysRead(pDevIns, GCPhys, pvBuf, cbRead);
+}
+
+
+/** @interface_method_impl{PDMDEVHLPRC,pfnPCIPhysRead} */
+static DECLCALLBACK(int) pdmRCDevHlp_PCIPhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmRCDevHlp_PCIPhysWrite: caller=%p/%d: GCPhys=%RGp pvBuf=%p cbWrite=%#x\n",
+             pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbWrite));
+
+    PCIDevice *pPciDev = pDevIns->Internal.s.pPciDeviceRC;
+    AssertPtrReturn(pPciDev, VERR_INVALID_POINTER);
+
+    if (!PCIDevIsBusmaster(pPciDev))
+    {
+#ifdef DEBUG
+        LogFlow(("%s: %RU16:%RU16: No bus master (anymore), skipping write %p (%z)\n", __FUNCTION__,
+                 PCIDevGetVendorId(pPciDev), PCIDevGetDeviceId(pPciDev), pvBuf, cbWrite));
+#endif
+        return VINF_PDM_PCI_PHYS_WRITE_BM_DISABLED;
+    }
+
+    return pdmRCDevHlp_PhysWrite(pDevIns, GCPhys, pvBuf, cbWrite);
+}
+
 
 /** @interface_method_impl{PDMDEVHLPRC,pfnPCISetIrq} */
@@ -316,4 +369,6 @@
 {
     PDM_DEVHLPRC_VERSION,
+    pdmRCDevHlp_PCIPhysRead,
+    pdmRCDevHlp_PCIPhysWrite,
     pdmRCDevHlp_PCISetIrq,
     pdmRCDevHlp_ISASetIrq,
