Index: /trunk/include/VBox/vmm/pgm.h
===================================================================
--- /trunk/include/VBox/vmm/pgm.h	(revision 55908)
+++ /trunk/include/VBox/vmm/pgm.h	(revision 55909)
@@ -132,4 +132,35 @@
 
 
+/** @def PGM_ALL_CB_DECL
+ * Macro for declaring a handler callback for all contexts.  The handler
+ * callback is static in ring-3, and exported in RC and R0.
+ * @sa PGM_ALL_CB2_DECL.
+ */
+#if defined(IN_RC) || defined(IN_RING0)
+# ifdef __cplusplus
+#  define PGM_ALL_CB_DECL(type)     extern "C" DECLEXPORT(type)
+# else
+#  define PGM_ALL_CB_DECL(type)     DECLEXPORT(type)
+# endif
+#else
+# define PGM_ALL_CB_DECL(type)      static type
+#endif
+
+/** @def PGM_ALL_CB2_DECL
+ * Macro for declaring a handler callback for all contexts.  The handler
+ * callback is hidden in ring-3, and exported in RC and R0.
+ * @sa PGM_ALL_CB2_DECL.
+ */
+#if defined(IN_RC) || defined(IN_RING0)
+# ifdef __cplusplus
+#  define PGM_ALL_CB2_DECL(type)    extern "C" DECLEXPORT(type)
+# else
+#  define PGM_ALL_CB2_DECL(type)    DECLEXPORT(type)
+# endif
+#else
+# define PGM_ALL_CB2_DECL(type)     DECLHIDDEN(type)
+#endif
+
+
 /**
  * \#PF Handler callback for physical access handler ranges in RC and R0.
@@ -170,11 +201,9 @@
  * @param   enmOrigin       The origin of this call.
  * @param   pvUser          User argument.
- *
- * @todo    Add pVCpu, possibly replacing pVM.
- */
-typedef DECLCALLBACK(int) FNPGMR3PHYSHANDLER(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf,
-                                             PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser);
+ */
+typedef DECLCALLBACK(int) FNPGMPHYSHANDLER(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf,
+                                           PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser);
 /** Pointer to PGM access callback. */
-typedef FNPGMR3PHYSHANDLER *PFNPGMR3PHYSHANDLER;
+typedef FNPGMPHYSHANDLER *PFNPGMPHYSHANDLER;
 
 
@@ -567,10 +596,10 @@
 
 VMMR3_INT_DECL(int) PGMR3HandlerPhysicalTypeRegisterEx(PVM pVM, PGMPHYSHANDLERKIND enmKind,
-                                                       PFNPGMR3PHYSHANDLER pfnHandlerR3,
+                                                       PFNPGMPHYSHANDLER pfnHandlerR3,
                                                        R0PTRTYPE(PFNPGMRZPHYSPFHANDLER) pfnPfHandlerR0,
                                                        RCPTRTYPE(PFNPGMRZPHYSPFHANDLER) pfnPfHandlerRC,
                                                        const char *pszDesc, PPGMPHYSHANDLERTYPE phType);
 VMMR3DECL(int)      PGMR3HandlerPhysicalTypeRegister(PVM pVM, PGMPHYSHANDLERKIND enmKind,
-                                                     R3PTRTYPE(PFNPGMR3PHYSHANDLER) pfnHandlerR3,
+                                                     R3PTRTYPE(PFNPGMPHYSHANDLER) pfnHandlerR3,
                                                      const char *pszModR0, const char *pszPfHandlerR0,
                                                      const char *pszModRC, const char *pszPfHandlerRC, const char *pszDesc,
Index: /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp	(revision 55908)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA-SVGA.cpp	(revision 55909)
@@ -164,8 +164,8 @@
 #ifdef IN_RING3
 # ifdef DEBUG_FIFO_ACCESS
-static FNPGMR3PHYSHANDLER vmsvgaR3FIFOAccessHandler;
+static FNPGMPHYSHANDLER vmsvgaR3FIFOAccessHandler;
 # endif
 # ifdef DEBUG_GMR_ACCESS
-static FNPGMR3PHYSHANDLER vmsvgaR3GMRAccessHandler;
+static FNPGMPHYSHANDLER vmsvgaR3GMRAccessHandler;
 # endif
 #endif
Index: /trunk/src/VBox/Devices/Graphics/DevVGA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA.cpp	(revision 55908)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA.cpp	(revision 55909)
@@ -268,10 +268,8 @@
 #ifndef IN_RING3
 RT_C_DECLS_BEGIN
-DECLEXPORT(FNPGMRZPHYSPFHANDLER) vgaLbfAccessPfHandler;
+DECLEXPORT(FNPGMRZPHYSPFHANDLER)  vgaLbfAccessPfHandler;
 RT_C_DECLS_END
 #endif
-#ifdef IN_RING3
-static FNPGMR3PHYSHANDLER vgaR3LFBAccessHandler;
-#endif
+PGM_ALL_CB_DECL(FNPGMPHYSHANDLER) vgaLFBAccessHandler;
 
 
@@ -3551,12 +3549,12 @@
     return vgaLFBAccess(pVM, pThis, GCPhysFault, pvFault);
 }
-
-#else /* IN_RING3 */
+#endif /* !IN_RING3 */
+
 
 /**
- * @callback_method_impl{FNPGMR3PHYSHANDLER, HC access handler for the LFB.}
- */
-static DECLCALLBACK(int) vgaR3LFBAccessHandler(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf,
-                                               PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser)
+ * @callback_method_impl{FNPGMPHYSHANDLER, HC access handler for the LFB.}
+ */
+PGM_ALL_CB_DECL(int) vgaLFBAccessHandler(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf,
+                                         PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser)
 {
     PVGASTATE   pThis = (PVGASTATE)pvUser;
@@ -3572,5 +3570,5 @@
     return rc;
 }
-#endif /* IN_RING3 */
+
 
 /* -=-=-=-=-=- All rings: VGA BIOS I/Os -=-=-=-=-=- */
@@ -6217,5 +6215,5 @@
      */
     rc = PGMR3HandlerPhysicalTypeRegister(pVM, PGMPHYSHANDLERKIND_WRITE,
-                                          vgaR3LFBAccessHandler,
+                                          vgaLFBAccessHandler,
                                           g_DeviceVga.szR0Mod, "vgaLbfAccessPfHandler",
                                           g_DeviceVga.szRCMod, "vgaLbfAccessPfHandler",
Index: /trunk/src/VBox/Devices/Network/DevPCNet.cpp
===================================================================
--- /trunk/src/VBox/Devices/Network/DevPCNet.cpp	(revision 55908)
+++ /trunk/src/VBox/Devices/Network/DevPCNet.cpp	(revision 55909)
@@ -633,4 +633,12 @@
 static void pcnetPollTimerStart(PPCNETSTATE pThis);
 static int  pcnetXmitPending(PPCNETSTATE pThis, bool fOnWorkerThread);
+#ifdef PCNET_NO_POLLING
+PGM_ALL_CB_DECL(FNPGMPHYSHANDLER)           pcnetHandleRingWrite;
+# ifndef IN_RING3
+RT_C_DECLS_BEGIN
+DECLEXPORT(CTX_SUFF(FNPGM,PHYSPFHANDLER))   pcnetHandleRingWritePf;
+RT_C_DECLS_END
+# endif
+#endif
 
 
@@ -1089,9 +1097,6 @@
 
 #ifdef PCNET_NO_POLLING
+
 # ifndef IN_RING3
-RT_C_DECLS_BEGIN
-DECLEXPORT(CTX_SUFF(FNPGM,PHYSPFHANDLER)) pcnetHandleRingWritePf;
-RT_C_DECLS_END
-
 /**
  * #PF Virtual Handler callback for Guest write access to the ring descriptor page(pThis)
@@ -1147,11 +1152,9 @@
     return VINF_IOM_R3_MMIO_WRITE; /* handle in ring3 */
 }
-
-# else /* IN_RING3 */
-
-static FNPGMR3PHYSHANDLER pcnetR3HandleRingWrite;
-
-/**
- * #PF Handler callback for physical access handler ranges (MMIO among others) in HC.
+#endif /* !IN_RING3 */
+
+
+/**
+ * #PF Handler callback for physical access handler ranges (MMIO among others).
  *
  * The handler can not raise any faults, it's mainly for monitoring write access
@@ -1170,11 +1173,11 @@
  * @param   pvUser          User argument.
  */
-static DECLCALLBACK(int) pcnetR3HandleRingWrite(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf,
-                                                PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser)
+PGM_ALL_CB_DECL(int) pcnetHandleRingWrite(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf,
+                                          PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser)
 {
     PPDMDEVINS  pDevIns = (PPDMDEVINS)pvUser;
     PPCNETSTATE pThis   = PDMINS_2_DATA(pDevIns, PPCNETSTATE);
 
-    Log(("#%d pcnetR3HandleRingWrite: write to %#010x\n", PCNET_INST_NR, GCPhys));
+    Log(("#%d pcnetHandleRingWrite: write to %#010x\n", PCNET_INST_NR, GCPhys));
 #ifdef VBOX_WITH_STATISTICS
     STAM_COUNTER_INC(&CTXSUFF(pThis->StatRingWrite));
@@ -1206,5 +1209,4 @@
     return VINF_SUCCESS;
 }
-# endif /* !IN_RING3 */
 #endif /* PCNET_NO_POLLING */
 
@@ -4978,5 +4980,5 @@
 
     rc = PGMR3HandlerPhysicalTypeRegister(PDMDevHlpGetVM(pDevIns), PGMPHYSHANDLERKIND_WRITE,
-                                          pcnetR3HandleRingWrite,
+                                          pcnetHandleRingWrite,
                                           g_DevicePCNet.szR0Mod, "pcnetHandleRingWritePf",
                                           g_DevicePCNet.szRCMod, "pcnetHandleRingWritePf",
Index: /trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp	(revision 55908)
+++ /trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp	(revision 55909)
@@ -1788,5 +1788,4 @@
 
 
-#ifdef IN_RING3
 /**
  * \#PF Handler callback for MMIO ranges.
@@ -1804,6 +1803,6 @@
  * @param   pvUser          Pointer to the MMIO range entry.
  */
-DECLCALLBACK(int) iomR3MmioHandler(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhysFault, void *pvPhys, void *pvBuf, size_t cbBuf,
-                                   PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser)
+PGM_ALL_CB2_DECL(int) iomMmioHandler(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhysFault, void *pvPhys, void *pvBuf, size_t cbBuf,
+                                     PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser)
 {
     PIOMMMIORANGE pRange = (PIOMMMIORANGE)pvUser;
@@ -1847,5 +1846,4 @@
     return rc;
 }
-#endif /* IN_RING3 */
 
 
Index: /trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp	(revision 55908)
+++ /trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp	(revision 55909)
@@ -149,5 +149,109 @@
 }
 
-#endif /* IN_RING3 */
+#endif /* !IN_RING3 */
+
+
+/**
+ * Access handler callback for ROM write accesses.
+ *
+ * @returns VINF_SUCCESS if the handler have carried out the operation.
+ * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.
+ * @param   pVM             Pointer to the VM.
+ * @param   pVCpu           The cross context CPU structure for the calling EMT.
+ * @param   GCPhys          The physical address the guest is writing to.
+ * @param   pvPhys          The HC mapping of that address.
+ * @param   pvBuf           What the guest is reading/writing.
+ * @param   cbBuf           How much it's reading/writing.
+ * @param   enmAccessType   The access type.
+ * @param   enmOrigin       Who is making the access.
+ * @param   pvUser          User argument.
+ */
+PGM_ALL_CB2_DECL(int) pgmPhysRomWriteHandler(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf,
+                                             PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser)
+{
+    PPGMROMRANGE    pRom     = (PPGMROMRANGE)pvUser;
+    const uint32_t  iPage    = (GCPhys - pRom->GCPhys) >> PAGE_SHIFT;
+    Assert(iPage < (pRom->cb >> PAGE_SHIFT));
+    PPGMROMPAGE     pRomPage = &pRom->aPages[iPage];
+    Log5(("pgmPhysRomWriteHandler: %d %c %#08RGp %#04zx\n", pRomPage->enmProt, enmAccessType == PGMACCESSTYPE_READ ? 'R' : 'W', GCPhys, cbBuf));
+    NOREF(pVCpu); NOREF(pvPhys); NOREF(enmOrigin);
+
+    if (enmAccessType == PGMACCESSTYPE_READ)
+    {
+        switch (pRomPage->enmProt)
+        {
+            /*
+             * Take the default action.
+             */
+            case PGMROMPROT_READ_ROM_WRITE_IGNORE:
+            case PGMROMPROT_READ_RAM_WRITE_IGNORE:
+            case PGMROMPROT_READ_ROM_WRITE_RAM:
+            case PGMROMPROT_READ_RAM_WRITE_RAM:
+                return VINF_PGM_HANDLER_DO_DEFAULT;
+
+            default:
+                AssertMsgFailedReturn(("enmProt=%d iPage=%d GCPhys=%RGp\n",
+                                       pRom->aPages[iPage].enmProt, iPage, GCPhys),
+                                      VERR_IPE_NOT_REACHED_DEFAULT_CASE);
+        }
+    }
+    else
+    {
+        Assert(enmAccessType == PGMACCESSTYPE_WRITE);
+        switch (pRomPage->enmProt)
+        {
+            /*
+             * Ignore writes.
+             */
+            case PGMROMPROT_READ_ROM_WRITE_IGNORE:
+            case PGMROMPROT_READ_RAM_WRITE_IGNORE:
+                return VINF_SUCCESS;
+
+            /*
+             * Write to the RAM page.
+             */
+            case PGMROMPROT_READ_ROM_WRITE_RAM:
+            case PGMROMPROT_READ_RAM_WRITE_RAM: /* yes this will get here too, it's *way* simpler that way. */
+            {
+                /* This should be impossible now, pvPhys doesn't work cross page anylonger. */
+                Assert(((GCPhys - pRom->GCPhys + cbBuf - 1) >> PAGE_SHIFT) == iPage);
+
+                /*
+                 * Take the lock, do lazy allocation, map the page and copy the data.
+                 *
+                 * Note that we have to bypass the mapping TLB since it works on
+                 * guest physical addresses and entering the shadow page would
+                 * kind of screw things up...
+                 */
+                int rc = pgmLock(pVM);
+                AssertRC(rc);
+
+                PPGMPAGE pShadowPage = &pRomPage->Shadow;
+                if (!PGMROMPROT_IS_ROM(pRomPage->enmProt))
+                {
+                    pShadowPage = pgmPhysGetPage(pVM, GCPhys);
+                    AssertLogRelReturn(pShadowPage, VERR_PGM_PHYS_PAGE_GET_IPE);
+                }
+
+                void *pvDstPage;
+                rc = pgmPhysPageMakeWritableAndMap(pVM, pShadowPage, GCPhys & X86_PTE_PG_MASK, &pvDstPage);
+                if (RT_SUCCESS(rc))
+                {
+                    memcpy((uint8_t *)pvDstPage + (GCPhys & PAGE_OFFSET_MASK), pvBuf, cbBuf);
+                    pRomPage->LiveSave.fWrittenTo = true;
+                }
+
+                pgmUnlock(pVM);
+                return rc;
+            }
+
+            default:
+                AssertMsgFailedReturn(("enmProt=%d iPage=%d GCPhys=%RGp\n",
+                                       pRom->aPages[iPage].enmProt, iPage, GCPhys),
+                                      VERR_IPE_NOT_REACHED_DEFAULT_CASE);
+        }
+    }
+}
+
 
 /**
@@ -2126,5 +2230,5 @@
         Assert((pPhys->Core.KeyLast & PAGE_OFFSET_MASK) == PAGE_OFFSET_MASK);
 
-        PFNPGMR3PHYSHANDLER pfnHandler = PGMPHYSHANDLER_GET_TYPE(pVM, pPhys)->CTX_SUFF(pfnHandler); Assert(pfnHandler);
+        PFNPGMPHYSHANDLER pfnHandler = PGMPHYSHANDLER_GET_TYPE(pVM, pPhys)->CTX_SUFF(pfnHandler); Assert(pfnHandler);
         void *pvUser = pPhys->CTX_SUFF(pvUser);
 
@@ -2387,5 +2491,5 @@
             if (RT_SUCCESS(rc))
             {
-                PFNPGMR3PHYSHANDLER pfnHandler = PGMPHYSHANDLER_GET_TYPE(pVM, pCur)->CTX_SUFF(pfnHandler);
+                PFNPGMPHYSHANDLER pfnHandler = PGMPHYSHANDLER_GET_TYPE(pVM, pCur)->CTX_SUFF(pfnHandler);
                 void *pvUser = pCur->CTX_SUFF(pvUser);
 
@@ -2612,5 +2716,5 @@
                 cbRange = offVirt;
 #ifdef IN_RING3
-            PFNPGMR3PHYSHANDLER pfnHandler = PGMPHYSHANDLER_GET_TYPE(pVM, pPhys)->CTX_SUFF(pfnHandler);
+            PFNPGMPHYSHANDLER pfnHandler = PGMPHYSHANDLER_GET_TYPE(pVM, pPhys)->CTX_SUFF(pfnHandler);
             void *pvUser = pPhys->CTX_SUFF(pvUser);
 
@@ -2688,5 +2792,5 @@
             Log5(("pgmPhysWriteHandler: GCPhys=%RGp cbRange=%#x pPage=%R[pgmpage] phys/virt %s/%s\n", GCPhys, cbRange, pPage, R3STRING(pPhys->pszDesc), R3STRING(pVirt->pszDesc) ));
 
-            PFNPGMR3PHYSHANDLER pfnHandler = PGMPHYSHANDLER_GET_TYPE(pVM, pPhys)->CTX_SUFF(pfnHandler);
+            PFNPGMPHYSHANDLER pfnHandler = PGMPHYSHANDLER_GET_TYPE(pVM, pPhys)->CTX_SUFF(pfnHandler);
             void *pvUser = pPhys->CTX_SUFF(pvUser);
 
Index: /trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp	(revision 55908)
+++ /trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp	(revision 55909)
@@ -51,7 +51,4 @@
 static int pgmPoolTrackAddUser(PPGMPOOL pPool, PPGMPOOLPAGE pPage, uint16_t iUser, uint32_t iUserTable);
 static void pgmPoolMonitorModifiedRemove(PPGMPOOL pPool, PPGMPOOLPAGE pPage);
-#ifndef IN_RING3
-DECLEXPORT(FNPGMRZPHYSPFHANDLER) pgmPoolAccessPfHandler;
-#endif
 #if defined(LOG_ENABLED) || defined(VBOX_STRICT)
 static const char *pgmPoolPoolKindToStr(uint8_t enmKind);
@@ -143,10 +140,10 @@
  * @param   pVM         Pointer to the VM.
  * @param   pvDst       Destination address
- * @param   pvSrc       Source guest virtual address.
+ * @param   pvSrc       Pointer to the mapping of @a GCPhysSrc or NULL depending
+ *                      on the context (e.g. \#PF in R0 & RC).
  * @param   GCPhysSrc   The source guest physical address.
  * @param   cb          Size of data to read
  */
-DECLINLINE(int) pgmPoolPhysSimpleReadGCPhys(PVM pVM, void *pvDst, CTXTYPE(RTGCPTR, RTHCPTR, RTGCPTR) pvSrc,
-                                            RTGCPHYS GCPhysSrc, size_t cb)
+DECLINLINE(int) pgmPoolPhysSimpleReadGCPhys(PVM pVM, void *pvDst, void const *pvSrc, RTGCPHYS GCPhysSrc, size_t cb)
 {
 #if defined(IN_RING3)
@@ -172,10 +169,10 @@
  * @param   pPage       The head page.
  * @param   GCPhysFault The guest physical fault address.
- * @param   uAddress    In R0 and GC this is the guest context fault address (flat).
- *                      In R3 this is the host context 'fault' address.
+ * @param   pvAddress   Pointer to the mapping of @a GCPhysFault or NULL
+ *                      depending on the context (e.g. \#PF in R0 & RC).
  * @param   cbWrite     Write size; might be zero if the caller knows we're not crossing entry boundaries
  */
-void pgmPoolMonitorChainChanging(PVMCPU pVCpu, PPGMPOOL pPool, PPGMPOOLPAGE pPage, RTGCPHYS GCPhysFault,
-                                 CTXTYPE(RTGCPTR, RTHCPTR, RTGCPTR) pvAddress, unsigned cbWrite)
+static void pgmPoolMonitorChainChanging(PVMCPU pVCpu, PPGMPOOL pPool, PPGMPOOLPAGE pPage, RTGCPHYS GCPhysFault,
+                                        void const *pvAddress, unsigned cbWrite)
 {
     AssertMsg(pPage->iMonitoredPrev == NIL_PGMPOOL_IDX, ("%u (idx=%u)\n", pPage->iMonitoredPrev, pPage->idx));
@@ -348,9 +345,7 @@
                     {
                         X86PTEPAE GstPte;
-#   ifdef IN_RING3
-                        int rc = pgmPoolPhysSimpleReadGCPhys(pVM, &GstPte, (RTHCPTR)((RTHCUINTPTR)pvAddress + sizeof(GstPte)), GCPhysFault + sizeof(GstPte), sizeof(GstPte));
-#   else
-                        int rc = pgmPoolPhysSimpleReadGCPhys(pVM, &GstPte, pvAddress + sizeof(GstPte), GCPhysFault + sizeof(GstPte), sizeof(GstPte));
-#   endif
+                        int rc = pgmPoolPhysSimpleReadGCPhys(pVM, &GstPte,
+                                                             pvAddress ? (uint8_t const *)pvAddress + sizeof(GstPte) : NULL,
+                                                             GCPhysFault + sizeof(GstPte), sizeof(GstPte));
                         AssertRC(rc);
                         Log4(("pgmPoolMonitorChainChanging pae: deref %016RX64 GCPhys %016RX64\n", PGMSHWPTEPAE_GET_HCPHYS(uShw.pPTPae->a[iShw2]), GstPte.u & X86_PTE_PAE_PG_MASK));
@@ -423,5 +418,5 @@
                     }
                 }
-#if 0 /* useful when running PGMAssertCR3(), a bit too troublesome for general use (TLBs). */
+#if 0 /* useful when running PGMAssertCR3(), a bit too troublesome for general use (TLBs). - not working any longer... */
                 if (    uShw.pPD->a[iShw].n.u1Present
                     &&  !VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3))
@@ -926,8 +921,8 @@
 #if defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) || defined(IN_RC)
         uint32_t iPrevSubset = PGMRZDynMapPushAutoSubset(pVCpu);
-        pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault, (RTGCPTR)pu32, uIncrement);
+        pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault, NULL, uIncrement);
         PGMRZDynMapPopAutoSubset(pVCpu, iPrevSubset);
 #else
-        pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault, (RTGCPTR)pu32, uIncrement);
+        pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault, NULL, uIncrement);
 #endif
 #ifdef IN_RC
@@ -985,10 +980,10 @@
     uint32_t cbWrite = DISGetParamSize(pDis, &pDis->Param1);
     if (cbWrite <= 8)
-        pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault, pvFault, cbWrite);
+        pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault, NULL, cbWrite);
     else
     {
         Assert(cbWrite <= 16);
-        pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault, pvFault, 8);
-        pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault + 8, pvFault + 8, cbWrite - 8);
+        pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault, NULL, 8);
+        pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault + 8, NULL, cbWrite - 8);
     }
 
@@ -1356,4 +1351,71 @@
 
 # endif /* !IN_RING3 */
+
+/**
+ * Access handler callback for PT write accesses.
+ *
+ * The handler can not raise any faults, it's mainly for monitoring write access
+ * to certain pages.
+ *
+ * @returns VINF_SUCCESS if the handler has carried out the operation.
+ * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.
+ * @param   pVM             Pointer to the VM.
+ * @param   pVCpu           The cross context CPU structure for the calling EMT.
+ * @param   GCPhys          The physical address the guest is writing to.
+ * @param   pvPhys          The HC mapping of that address.
+ * @param   pvBuf           What the guest is reading/writing.
+ * @param   cbBuf           How much it's reading/writing.
+ * @param   enmAccessType   The access type.
+ * @param   enmOrigin       Who is making the access.
+ * @param   pvUser          User argument.
+ */
+PGM_ALL_CB2_DECL(int) pgmPoolAccessHandler(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf,
+                                           PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser)
+{
+    PPGMPOOL        pPool = pVM->pgm.s.CTX_SUFF(pPool);
+    STAM_PROFILE_START(&pPool->StatMonitorR3, a);
+    PPGMPOOLPAGE    pPage = (PPGMPOOLPAGE)pvUser;
+    LogFlow(("PGM_ALL_CB_DECL: GCPhys=%RGp %p:{.Core=%RHp, .idx=%d, .GCPhys=%RGp, .enmType=%d}\n",
+             GCPhys, pPage, pPage->Core.Key, pPage->idx, pPage->GCPhys, pPage->enmKind));
+
+    NOREF(pvBuf); NOREF(enmAccessType); NOREF(enmOrigin);
+
+    /*
+     * We don't have to be very sophisticated about this since there are relativly few calls here.
+     * However, we must try our best to detect any non-cpu accesses (disk / networking).
+     */
+    pgmLock(pVM);
+    if (PHYS_PAGE_ADDRESS(GCPhys) != PHYS_PAGE_ADDRESS(pPage->GCPhys))
+    {
+        /* Pool page changed while we were waiting for the lock; ignore. */
+        Log(("CPU%d: PGM_ALL_CB_DECL pgm pool page for %RGp changed (to %RGp) while waiting!\n", pVCpu->idCpu, PHYS_PAGE_ADDRESS(GCPhys), PHYS_PAGE_ADDRESS(pPage->GCPhys)));
+        pgmUnlock(pVM);
+        return VINF_PGM_HANDLER_DO_DEFAULT;
+    }
+
+    Assert(pPage->enmKind != PGMPOOLKIND_FREE);
+/** @todo we can do better than this now.   */
+    if (   (   pPage->cModifications < 96 /* it's cheaper here. */
+            || pgmPoolIsPageLocked(pPage) )
+        && cbBuf <= 4)
+    {
+        /* Clear the shadow entry. */
+        if (!pPage->cModifications++)
+            pgmPoolMonitorModifiedInsert(pPool, pPage);
+        /** @todo r=bird: making unsafe assumption about not crossing entries here! */
+        pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhys, pvBuf, 0 /* unknown write size */);
+        STAM_PROFILE_STOP(&pPool->StatMonitorR3, a);
+    }
+    else
+    {
+        pgmPoolMonitorChainFlush(pPool, pPage); /* ASSUME that VERR_PGM_POOL_CLEARED can be ignored here and that FFs will deal with it in due time. */
+        STAM_PROFILE_STOP_EX(&pPool->StatMonitorR3, &pPool->StatMonitorR3FlushPage, a);
+    }
+    pgmUnlock(pVM);
+    return VINF_PGM_HANDLER_DO_DEFAULT;
+}
+
+
+
 
 # ifdef PGMPOOL_WITH_OPTIMIZED_DIRTY_PT
Index: /trunk/src/VBox/VMM/VMMR3/GIM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/GIM.cpp	(revision 55908)
+++ /trunk/src/VBox/VMM/VMMR3/GIM.cpp	(revision 55909)
@@ -70,5 +70,5 @@
 static DECLCALLBACK(int) gimR3Save(PVM pVM, PSSMHANDLE pSSM);
 static DECLCALLBACK(int) gimR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uSSMVersion, uint32_t uPass);
-static FNPGMR3PHYSHANDLER gimR3Mmio2WriteHandler;
+static FNPGMPHYSHANDLER gimR3Mmio2WriteHandler;
 
 
Index: /trunk/src/VBox/VMM/VMMR3/IOM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/IOM.cpp	(revision 55908)
+++ /trunk/src/VBox/VMM/VMMR3/IOM.cpp	(revision 55909)
@@ -187,5 +187,5 @@
          */
         rc = PGMR3HandlerPhysicalTypeRegister(pVM, PGMPHYSHANDLERKIND_MMIO,
-                                              iomR3MmioHandler,
+                                              iomMmioHandler,
                                               NULL, "iomMmioPfHandler",
                                               NULL, "iomMmioPfHandler",
Index: /trunk/src/VBox/VMM/VMMR3/PGM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PGM.cpp	(revision 55908)
+++ /trunk/src/VBox/VMM/VMMR3/PGM.cpp	(revision 55909)
@@ -1456,5 +1456,5 @@
     if (RT_SUCCESS(rc))
         rc = PGMR3HandlerPhysicalTypeRegister(pVM, PGMPHYSHANDLERKIND_WRITE,
-                                              pgmR3PhysRomWriteHandler,
+                                              pgmPhysRomWriteHandler,
                                               NULL, "pgmPhysRomWritePfHandler",
                                               NULL, "pgmPhysRomWritePfHandler",
Index: /trunk/src/VBox/VMM/VMMR3/PGMHandler.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PGMHandler.cpp	(revision 55908)
+++ /trunk/src/VBox/VMM/VMMR3/PGMHandler.cpp	(revision 55909)
@@ -81,5 +81,5 @@
  */
 VMMR3_INT_DECL(int) PGMR3HandlerPhysicalTypeRegisterEx(PVM pVM, PGMPHYSHANDLERKIND enmKind,
-                                                       PFNPGMR3PHYSHANDLER pfnHandlerR3,
+                                                       PFNPGMPHYSHANDLER pfnHandlerR3,
                                                        R0PTRTYPE(PFNPGMRZPHYSPFHANDLER) pfnPfHandlerR0,
                                                        RCPTRTYPE(PFNPGMRZPHYSPFHANDLER) pfnPfHandlerRC,
@@ -143,5 +143,5 @@
  */
 VMMR3DECL(int) PGMR3HandlerPhysicalTypeRegister(PVM pVM, PGMPHYSHANDLERKIND enmKind,
-                                                R3PTRTYPE(PFNPGMR3PHYSHANDLER) pfnHandlerR3,
+                                                R3PTRTYPE(PFNPGMPHYSHANDLER) pfnHandlerR3,
                                                 const char *pszModR0, const char *pszPfHandlerR0,
                                                 const char *pszModRC, const char *pszPfHandlerRC, const char *pszDesc,
Index: /trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp	(revision 55908)
+++ /trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp	(revision 55909)
@@ -3497,107 +3497,4 @@
 
 /**
- * \#PF Handler callback for ROM write accesses.
- *
- * @returns VINF_SUCCESS if the handler have carried out the operation.
- * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.
- * @param   pVM             Pointer to the VM.
- * @param   pVCpu           The cross context CPU structure for the calling EMT.
- * @param   GCPhys          The physical address the guest is writing to.
- * @param   pvPhys          The HC mapping of that address.
- * @param   pvBuf           What the guest is reading/writing.
- * @param   cbBuf           How much it's reading/writing.
- * @param   enmAccessType   The access type.
- * @param   enmOrigin       Who is making the access.
- * @param   pvUser          User argument.
- */
-DECLCALLBACK(int) pgmR3PhysRomWriteHandler(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf,
-                                           PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser)
-{
-    PPGMROMRANGE    pRom     = (PPGMROMRANGE)pvUser;
-    const uint32_t  iPage    = (GCPhys - pRom->GCPhys) >> PAGE_SHIFT;
-    Assert(iPage < (pRom->cb >> PAGE_SHIFT));
-    PPGMROMPAGE     pRomPage = &pRom->aPages[iPage];
-    Log5(("pgmR3PhysRomWriteHandler: %d %c %#08RGp %#04zx\n", pRomPage->enmProt, enmAccessType == PGMACCESSTYPE_READ ? 'R' : 'W', GCPhys, cbBuf));
-    NOREF(pVCpu); NOREF(pvPhys); NOREF(enmOrigin);
-
-    if (enmAccessType == PGMACCESSTYPE_READ)
-    {
-        switch (pRomPage->enmProt)
-        {
-            /*
-             * Take the default action.
-             */
-            case PGMROMPROT_READ_ROM_WRITE_IGNORE:
-            case PGMROMPROT_READ_RAM_WRITE_IGNORE:
-            case PGMROMPROT_READ_ROM_WRITE_RAM:
-            case PGMROMPROT_READ_RAM_WRITE_RAM:
-                return VINF_PGM_HANDLER_DO_DEFAULT;
-
-            default:
-                AssertMsgFailedReturn(("enmProt=%d iPage=%d GCPhys=%RGp\n",
-                                       pRom->aPages[iPage].enmProt, iPage, GCPhys),
-                                      VERR_IPE_NOT_REACHED_DEFAULT_CASE);
-        }
-    }
-    else
-    {
-        Assert(enmAccessType == PGMACCESSTYPE_WRITE);
-        switch (pRomPage->enmProt)
-        {
-            /*
-             * Ignore writes.
-             */
-            case PGMROMPROT_READ_ROM_WRITE_IGNORE:
-            case PGMROMPROT_READ_RAM_WRITE_IGNORE:
-                return VINF_SUCCESS;
-
-            /*
-             * Write to the RAM page.
-             */
-            case PGMROMPROT_READ_ROM_WRITE_RAM:
-            case PGMROMPROT_READ_RAM_WRITE_RAM: /* yes this will get here too, it's *way* simpler that way. */
-            {
-                /* This should be impossible now, pvPhys doesn't work cross page anylonger. */
-                Assert(((GCPhys - pRom->GCPhys + cbBuf - 1) >> PAGE_SHIFT) == iPage);
-
-                /*
-                 * Take the lock, do lazy allocation, map the page and copy the data.
-                 *
-                 * Note that we have to bypass the mapping TLB since it works on
-                 * guest physical addresses and entering the shadow page would
-                 * kind of screw things up...
-                 */
-                int rc = pgmLock(pVM);
-                AssertRC(rc);
-
-                PPGMPAGE pShadowPage = &pRomPage->Shadow;
-                if (!PGMROMPROT_IS_ROM(pRomPage->enmProt))
-                {
-                    pShadowPage = pgmPhysGetPage(pVM, GCPhys);
-                    AssertLogRelReturn(pShadowPage, VERR_PGM_PHYS_PAGE_GET_IPE);
-                }
-
-                void *pvDstPage;
-                rc = pgmPhysPageMakeWritableAndMap(pVM, pShadowPage, GCPhys & X86_PTE_PG_MASK, &pvDstPage);
-                if (RT_SUCCESS(rc))
-                {
-                    memcpy((uint8_t *)pvDstPage + (GCPhys & PAGE_OFFSET_MASK), pvBuf, cbBuf);
-                    pRomPage->LiveSave.fWrittenTo = true;
-                }
-
-                pgmUnlock(pVM);
-                return rc;
-            }
-
-            default:
-                AssertMsgFailedReturn(("enmProt=%d iPage=%d GCPhys=%RGp\n",
-                                       pRom->aPages[iPage].enmProt, iPage, GCPhys),
-                                      VERR_IPE_NOT_REACHED_DEFAULT_CASE);
-        }
-    }
-}
-
-
-/**
  * Called by PGMR3MemSetup to reset the shadow, switch to the virgin, and verify
  * that the virgin part is untouched.
Index: /trunk/src/VBox/VMM/VMMR3/PGMPool.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PGMPool.cpp	(revision 55908)
+++ /trunk/src/VBox/VMM/VMMR3/PGMPool.cpp	(revision 55909)
@@ -114,5 +114,4 @@
 *   Internal Functions                                                         *
 *******************************************************************************/
-static FNPGMR3PHYSHANDLER pgmR3PoolAccessHandler;
 #ifdef VBOX_WITH_DEBUGGER
 static FNDBGCCMD pgmR3PoolCmdCheck;
@@ -283,5 +282,5 @@
     pPool->hAccessHandlerType = NIL_PGMPHYSHANDLERTYPE;
     rc = PGMR3HandlerPhysicalTypeRegister(pVM, PGMPHYSHANDLERKIND_WRITE,
-                                          pgmR3PoolAccessHandler,
+                                          pgmPoolAccessHandler,
                                           NULL, "pgmPoolAccessPfHandler",
                                           NULL, "pgmPoolAccessPfHandler",
@@ -491,118 +490,4 @@
 
 
-
-/**
- * Worker used by pgmR3PoolAccessHandler when it's invoked by an async thread.
- *
- * @param   pPool   The pool.
- * @param   pPage   The page.
- */
-static DECLCALLBACK(void) pgmR3PoolFlushReusedPage(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
-{
-    /* for the present this should be safe enough I think... */
-    pgmLock(pPool->pVMR3);
-    if (    pPage->fReusedFlushPending
-        &&  pPage->enmKind != PGMPOOLKIND_FREE)
-        pgmPoolFlushPage(pPool, pPage);
-    pgmUnlock(pPool->pVMR3);
-}
-
-
-/**
- * \#PF Handler callback for PT write accesses.
- *
- * The handler can not raise any faults, it's mainly for monitoring write access
- * to certain pages.
- *
- * @returns VINF_SUCCESS if the handler has carried out the operation.
- * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.
- * @param   pVM             Pointer to the VM.
- * @param   pVCpu           The cross context CPU structure for the calling EMT.
- * @param   GCPhys          The physical address the guest is writing to.
- * @param   pvPhys          The HC mapping of that address.
- * @param   pvBuf           What the guest is reading/writing.
- * @param   cbBuf           How much it's reading/writing.
- * @param   enmAccessType   The access type.
- * @param   enmOrigin       Who is making the access.
- * @param   pvUser          User argument.
- */
-static DECLCALLBACK(int) pgmR3PoolAccessHandler(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf,
-                                                PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser)
-{
-    STAM_PROFILE_START(&pVM->pgm.s.pPoolR3->StatMonitorR3, a);
-    PPGMPOOL        pPool = pVM->pgm.s.pPoolR3;
-    PPGMPOOLPAGE    pPage = (PPGMPOOLPAGE)pvUser;
-    LogFlow(("pgmR3PoolAccessHandler: GCPhys=%RGp %p:{.Core=%RHp, .idx=%d, .GCPhys=%RGp, .enmType=%d}\n",
-             GCPhys, pPage, pPage->Core.Key, pPage->idx, pPage->GCPhys, pPage->enmKind));
-
-    NOREF(pvBuf); NOREF(enmAccessType); NOREF(enmOrigin);
-
-    /*
-     * We don't have to be very sophisticated about this since there are relativly few calls here.
-     * However, we must try our best to detect any non-cpu accesses (disk / networking).
-     *
-     * Just to make life more interesting, we'll have to deal with the async threads too.
-     * We cannot flush a page if we're in an async thread because of REM notifications.
-     */
-    pgmLock(pVM);
-    if (PHYS_PAGE_ADDRESS(GCPhys) != PHYS_PAGE_ADDRESS(pPage->GCPhys))
-    {
-        /* Pool page changed while we were waiting for the lock; ignore. */
-        Log(("CPU%d: pgmR3PoolAccessHandler pgm pool page for %RGp changed (to %RGp) while waiting!\n", pVCpu->idCpu, PHYS_PAGE_ADDRESS(GCPhys), PHYS_PAGE_ADDRESS(pPage->GCPhys)));
-        pgmUnlock(pVM);
-        return VINF_PGM_HANDLER_DO_DEFAULT;
-    }
-
-    Assert(pPage->enmKind != PGMPOOLKIND_FREE);
-
-    /* @todo this code doesn't make any sense. remove the if (!pVCpu) block */
-    if (!pVCpu) /** @todo This shouldn't happen any longer, all access handlers will be called on an EMT. All ring-3 handlers, except MMIO, already own the PGM lock. @bugref{3170} */
-    {
-        Log(("pgmR3PoolAccessHandler: async thread, requesting EMT to flush the page: %p:{.Core=%RHp, .idx=%d, .GCPhys=%RGp, .enmType=%d}\n",
-             pPage, pPage->Core.Key, pPage->idx, pPage->GCPhys, pPage->enmKind));
-        STAM_COUNTER_INC(&pPool->StatMonitorR3Async);
-        if (!pPage->fReusedFlushPending)
-        {
-            pgmUnlock(pVM);
-            int rc = VMR3ReqCallVoidNoWait(pPool->pVMR3, VMCPUID_ANY, (PFNRT)pgmR3PoolFlushReusedPage, 2, pPool, pPage);
-            AssertRCReturn(rc, rc);
-            pgmLock(pVM);
-            pPage->fReusedFlushPending = true;
-            pPage->cModifications += 0x1000;
-        }
-
-        pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhys, pvPhys, 0 /* unknown write size */);
-        /** @todo r=bird: making unsafe assumption about not crossing entries here! */
-        while (cbBuf > 4)
-        {
-            cbBuf -= 4;
-            pvPhys = (uint8_t *)pvPhys + 4;
-            GCPhys += 4;
-            pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhys, pvPhys, 0 /* unknown write size */);
-        }
-        STAM_PROFILE_STOP(&pPool->StatMonitorR3, a);
-    }
-    else if (    (   pPage->cModifications < 96 /* it's cheaper here. */
-                  || pgmPoolIsPageLocked(pPage)
-                  )
-             &&  cbBuf <= 4)
-    {
-        /* Clear the shadow entry. */
-        if (!pPage->cModifications++)
-            pgmPoolMonitorModifiedInsert(pPool, pPage);
-        /** @todo r=bird: making unsafe assumption about not crossing entries here! */
-        pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhys, pvPhys, 0 /* unknown write size */);
-        STAM_PROFILE_STOP(&pPool->StatMonitorR3, a);
-    }
-    else
-    {
-        pgmPoolMonitorChainFlush(pPool, pPage); /* ASSUME that VERR_PGM_POOL_CLEARED can be ignored here and that FFs will deal with it in due time. */
-        STAM_PROFILE_STOP_EX(&pPool->StatMonitorR3, &pPool->StatMonitorR3FlushPage, a);
-    }
-    pgmUnlock(pVM);
-    return VINF_PGM_HANDLER_DO_DEFAULT;
-}
-
-
 /**
  * Rendezvous callback used by pgmR3PoolClearAll that clears all shadow pages
Index: /trunk/src/VBox/VMM/include/IOMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/IOMInternal.h	(revision 55908)
+++ /trunk/src/VBox/VMM/include/IOMInternal.h	(revision 55909)
@@ -425,7 +425,5 @@
 DECLEXPORT(FNPGMRZPHYSPFHANDLER)    iomMmioPfHandler;
 #endif
-#ifdef IN_RING3
-FNPGMR3PHYSHANDLER                  iomR3MmioHandler;
-#endif
+PGM_ALL_CB2_DECL(FNPGMPHYSHANDLER)  iomMmioHandler;
 
 /* IOM locking helpers. */
Index: /trunk/src/VBox/VMM/include/PGMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/PGMInternal.h	(revision 55908)
+++ /trunk/src/VBox/VMM/include/PGMInternal.h	(revision 55909)
@@ -595,5 +595,5 @@
     RTRCPTR                             RCPtrPadding;
     /** Pointer to R3 callback function. */
-    R3PTRTYPE(PFNPGMR3PHYSHANDLER)      pfnHandlerR3;
+    R3PTRTYPE(PFNPGMPHYSHANDLER)        pfnHandlerR3;
     /** Pointer to R0 callback function for \#PFs. */
     R0PTRTYPE(PFNPGMRZPHYSPFHANDLER)    pfnPfHandlerR0;
@@ -4146,4 +4146,5 @@
 int             pgmPhysGCPhys2CCPtrInternalReadOnly(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, const void **ppv, PPGMPAGEMAPLOCK pLock);
 void            pgmPhysReleaseInternalPageMappingLock(PVM pVM, PPGMPAGEMAPLOCK pLock);
+PGM_ALL_CB2_DECL(FNPGMPHYSHANDLER) pgmPhysRomWriteHandler;
 #ifndef IN_RING3
 DECLEXPORT(FNPGMRZPHYSPFHANDLER) pgmPhysPfHandlerRedirectToHC;
@@ -4161,5 +4162,4 @@
 
 #ifdef IN_RING3
-FNPGMR3PHYSHANDLER pgmR3PhysRomWriteHandler;
 void            pgmR3PhysRelinkRamRanges(PVM pVM);
 int             pgmR3PhysRamPreAllocate(PVM pVM);
@@ -4205,7 +4205,10 @@
 uint16_t        pgmPoolTrackPhysExtAddref(PVM pVM, PPGMPAGE pPhysPage, uint16_t u16, uint16_t iShwPT, uint16_t iPte);
 void            pgmPoolTrackPhysExtDerefGCPhys(PPGMPOOL pPool, PPGMPOOLPAGE pPoolPage, PPGMPAGE pPhysPage, uint16_t iPte);
-void            pgmPoolMonitorChainChanging(PVMCPU pVCpu, PPGMPOOL pPool, PPGMPOOLPAGE pPage, RTGCPHYS GCPhysFault, CTXTYPE(RTGCPTR, RTHCPTR, RTGCPTR) pvAddress, unsigned cbWrite);
 int             pgmPoolMonitorChainFlush(PPGMPOOL pPool, PPGMPOOLPAGE pPage);
 void            pgmPoolMonitorModifiedInsert(PPGMPOOL pPool, PPGMPOOLPAGE pPage);
+PGM_ALL_CB2_DECL(FNPGMPHYSHANDLER) pgmPoolAccessHandler;
+#ifndef IN_RING3
+DECLEXPORT(FNPGMRZPHYSPFHANDLER)   pgmPoolAccessPfHandler;
+#endif
 
 void            pgmPoolAddDirtyPage(PVM pVM, PPGMPOOL pPool, PPGMPOOLPAGE pPage);
