Index: /trunk/include/VBox/vmm/pgm.h
===================================================================
--- /trunk/include/VBox/vmm/pgm.h	(revision 55899)
+++ /trunk/include/VBox/vmm/pgm.h	(revision 55900)
@@ -74,4 +74,34 @@
 /** Pointer to a relocation callback function. */
 typedef FNPGMRELOCATE *PFNPGMRELOCATE;
+
+
+/**
+ * Memory access origin.
+ */
+typedef enum PGMACCESSORIGIN
+{
+    /** Invalid zero value. */
+    PGMACCESSORIGIN_INVALID = 0,
+    /** IEM is access memory. */
+    PGMACCESSORIGIN_IEM,
+    /** HM is access memory. */
+    PGMACCESSORIGIN_HM,
+    /** Some device is access memory. */
+    PGMACCESSORIGIN_DEVICE,
+    /** Someone debugging is access memory. */
+    PGMACCESSORIGIN_DEBUGGER,
+    /** SELM is access memory. */
+    PGMACCESSORIGIN_SELM,
+    /** FTM is access memory. */
+    PGMACCESSORIGIN_FTM,
+    /** REM is access memory. */
+    PGMACCESSORIGIN_REM,
+    /** IOM is access memory. */
+    PGMACCESSORIGIN_IOM,
+    /** End of valid values. */
+    PGMACCESSORIGIN_END,
+    /** Type size hack. */
+    PGMACCESSORIGIN_32BIT_HACK = 0x7fffffff
+} PGMACCESSORIGIN;
 
 
@@ -182,4 +212,6 @@
  * @returns VBox status code (appropriate for GC return).
  * @param   pVM             VM Handle.
+ * @param   pVCpu           Pointer to the cross context CPU context for the
+ *                          calling EMT.
  * @param   uErrorCode      CPU Error code (X86_TRAP_PF_XXX).
  * @param   pRegFrame       Trap register frame.
@@ -189,5 +221,4 @@
  *                          (If it's a EIP range this is the EIP, if not it's pvFault.)
  * @param   pvUser          User argument.
- * @todo    Add pVCpu, possibly replacing pVM.
  */
 typedef DECLCALLBACK(int) FNPGMRCVIRTPFHANDLER(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault,
@@ -212,23 +243,25 @@
  * @param   cbBuf           How much it's reading/writing.
  * @param   enmAccessType   The access type.
+ * @param   enmOrigin       Who is calling.
  * @param   pvUser          User argument.
- * @todo    Add pVCpu, possibly replacing pVM.
- */
-typedef DECLCALLBACK(int) FNPGMR3VIRTHANDLER(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf,
-                                             PGMACCESSTYPE enmAccessType, void *pvUser);
+ */
+typedef DECLCALLBACK(int) FNPGMR3VIRTHANDLER(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf,
+                                             PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser);
 /** Pointer to PGM access callback. */
 typedef FNPGMR3VIRTHANDLER *PFNPGMR3VIRTHANDLER;
 
-
 /**
  * \#PF Handler callback for invalidation of virtual access handler ranges.
  *
  * @param   pVM             VM Handle.
+ * @param   pVCpu           Pointer to the cross context CPU context for the
+ *                          calling EMT.
  * @param   GCPtr           The virtual address the guest has changed.
  * @param   pvUser          User argument.
  */
-typedef DECLCALLBACK(int) FNPGMR3VIRTINVALIDATE(PVM pVM, RTGCPTR GCPtr, void *pvUser);
+typedef DECLCALLBACK(int) FNPGMR3VIRTINVALIDATE(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, void *pvUser);
 /** Pointer to PGM invalidation callback. */
 typedef FNPGMR3VIRTINVALIDATE *PFNPGMR3VIRTINVALIDATE;
+
 
 /**
@@ -244,4 +277,5 @@
 /** Pointer to PGMR3PhysEnumDirtyFTPages callback. */
 typedef FNPGMENUMDIRTYFTPAGES *PFNPGMENUMDIRTYFTPAGES;
+
 
 /**
@@ -400,19 +434,4 @@
 VMMDECL(int)        PGMPhysGCPtr2GCPhys(PVMCPU pVCpu, RTGCPTR GCPtr, PRTGCPHYS pGCPhys);
 VMMDECL(void)       PGMPhysReleasePageMappingLock(PVM pVM, PPGMPAGEMAPLOCK pLock);
-/** Memory access origin. */
-typedef enum PGMACCESSORIGIN
-{
-    PGMACCESSORIGIN_INVALID = 0,
-    PGMACCESSORIGIN_IEM,
-    PGMACCESSORIGIN_HM,
-    PGMACCESSORIGIN_DEVICE,
-    PGMACCESSORIGIN_DEBUGGER,
-    PGMACCESSORIGIN_SELM,
-    PGMACCESSORIGIN_FTM,
-    PGMACCESSORIGIN_IOM,
-    PGMACCESSORIGIN_REM,
-    PGMACCESSORIGIN_END,
-    PGMACCESSORIGIN_32BIT_HACK = 0x7fffffff
-} PGMACCESSORIGIN;
 VMMDECL(int)        PGMPhysRead(PVM pVM, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead, PGMACCESSORIGIN enmOrigin);
 VMMDECL(int)        PGMPhysWrite(PVM pVM, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite, PGMACCESSORIGIN enmOrigin);
Index: /trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp	(revision 55899)
+++ /trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp	(revision 55900)
@@ -2082,6 +2082,7 @@
  * @param   pvBuf       Where to put the bits we read.
  * @param   cb          How much to read - less or equal to a page.
- */
-static int pgmPhysReadHandler(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void *pvBuf, size_t cb)
+ * @param   enmOrigin       The origin of this call.
+ */
+static int pgmPhysReadHandler(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void *pvBuf, size_t cb, PGMACCESSORIGIN enmOrigin)
 {
     /*
@@ -2108,4 +2109,5 @@
      * Deal with any physical handlers.
      */
+    PVMCPU pVCpu = VMMGetCpu(pVM);
 #ifdef IN_RING3
     PPGMPHYSHANDLER pPhys = NULL;
@@ -2174,5 +2176,5 @@
 
             STAM_PROFILE_START(&pVirt->Stat, h);
-            rc2 = pVirtType->CTX_SUFF(pfnHandler)(pVM, GCPtr, (void *)pvSrc, pvBuf, cb, PGMACCESSTYPE_READ,
+            rc2 = pVirtType->CTX_SUFF(pfnHandler)(pVM, pVCpu, GCPtr, (void *)pvSrc, pvBuf, cb, PGMACCESSTYPE_READ, enmOrigin,
                                                   pVirt->CTX_SUFF(pvUser));
             STAM_PROFILE_STOP(&pVirt->Stat, h);
@@ -2254,5 +2256,5 @@
                                 || PGM_PAGE_IS_SPECIAL_ALIAS_MMIO(pPage)))
                 {
-                    int rc = pgmPhysReadHandler(pVM, pPage, pRam->GCPhys + off, pvBuf, cb);
+                    int rc = pgmPhysReadHandler(pVM, pPage, pRam->GCPhys + off, pvBuf, cb, enmOrigin);
                     if (RT_FAILURE(rc))
                     {
@@ -2337,6 +2339,8 @@
  * @param   pvBuf       What to write.
  * @param   cbWrite     How much to write - less or equal to a page.
- */
-static int pgmPhysWriteHandler(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void const *pvBuf, size_t cbWrite)
+ * @param   enmOrigin       The origin of this call.
+ */
+static int pgmPhysWriteHandler(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void const *pvBuf, size_t cbWrite,
+                               PGMACCESSORIGIN enmOrigin)
 {
     PGMPAGEMAPLOCK  PgMpLck;
@@ -2351,4 +2355,5 @@
      * the heavy usage of full page handlers in the page pool.
      */
+    PVMCPU pVCpu = VMMGetCpu(pVM);
     if (   !PGM_PAGE_HAS_ACTIVE_VIRTUAL_HANDLERS(pPage)
         || PGM_PAGE_IS_MMIO_OR_SPECIAL_ALIAS(pPage) /* screw virtual handlers on MMIO pages */)
@@ -2461,6 +2466,6 @@
 
                     STAM_PROFILE_START(&pCur->Stat, h);
-                    rc = pCurType->CTX_SUFF(pfnHandler)(pVM, GCPtr, pvDst, (void *)pvBuf, cbRange, PGMACCESSTYPE_WRITE,
-                                                        pCur->CTX_SUFF(pvUser));
+                    rc = pCurType->CTX_SUFF(pfnHandler)(pVM, pVCpu, GCPtr, pvDst, (void *)pvBuf, cbRange, PGMACCESSTYPE_WRITE,
+                                                        enmOrigin, pCur->CTX_SUFF(pvUser));
                     STAM_PROFILE_STOP(&pCur->Stat, h);
                 }
@@ -2649,6 +2654,6 @@
                                   + (GCPhys & PAGE_OFFSET_MASK);
                 STAM_PROFILE_START(&pVirt->Stat, h);
-                rc = pVirtType->CTX_SUFF(pfnHandler)(pVM, GCPtr, pvDst, (void *)pvBuf, cbRange, PGMACCESSTYPE_WRITE,
-                                                     pVirt->CTX_SUFF(pvUser));
+                rc = pVirtType->CTX_SUFF(pfnHandler)(pVM, pVCpu, GCPtr, pvDst, (void *)pvBuf, cbRange, PGMACCESSTYPE_WRITE,
+                                                     enmOrigin, pVirt->CTX_SUFF(pvUser));
                 STAM_PROFILE_STOP(&pVirt->Stat, h);
                 AssertLogRelMsg(rc == VINF_SUCCESS || rc == VINF_PGM_HANDLER_DO_DEFAULT, ("rc=%Rrc GCPhys=%RGp pPage=%R[pgmpage] %s\n", rc, GCPhys, pPage, pVirt->pszDesc));
@@ -2704,6 +2709,6 @@
                                   + (GCPhys & PAGE_OFFSET_MASK);
                 STAM_PROFILE_START(&pVirt->Stat, h2);
-                int rc2 = pVirtType->CTX_SUFF(pfnHandler)(pVM, GCPtr, pvDst, (void *)pvBuf, cbRange, PGMACCESSTYPE_WRITE,
-                                                          pVirt->CTX_SUFF(pvUser));
+                int rc2 = pVirtType->CTX_SUFF(pfnHandler)(pVM, pVCpu, GCPtr, pvDst, (void *)pvBuf, cbRange, PGMACCESSTYPE_WRITE,
+                                                          enmOrigin, pVirt->CTX_SUFF(pvUser));
                 STAM_PROFILE_STOP(&pVirt->Stat, h2);
                 if (rc2 == VINF_SUCCESS && rc == VINF_PGM_HANDLER_DO_DEFAULT)
@@ -2801,5 +2806,5 @@
                     || PGM_PAGE_IS_SPECIAL_ALIAS_MMIO(pPage))
                 {
-                    int rc = pgmPhysWriteHandler(pVM, pPage, pRam->GCPhys + off, pvBuf, cb);
+                    int rc = pgmPhysWriteHandler(pVM, pPage, pRam->GCPhys + off, pvBuf, cb, enmOrigin);
                     if (RT_FAILURE(rc))
                     {
Index: /trunk/src/VBox/VMM/VMMR3/CSAM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/CSAM.cpp	(revision 55899)
+++ /trunk/src/VBox/VMM/VMMR3/CSAM.cpp	(revision 55900)
@@ -2172,4 +2172,6 @@
  * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.
  * @param   pVM             Pointer to the VM.
+ * @param   pVCpu       Pointer to the cross context CPU context for the
+ *                      calling EMT.
  * @param   GCPtr           The virtual address the guest is writing to. (not correct if it's an alias!)
  * @param   pvPtr           The HC mapping of that address.
@@ -2177,8 +2179,9 @@
  * @param   cbBuf           How much it's reading/writing.
  * @param   enmAccessType   The access type.
+ * @param   enmOrigin       Who is making this write.
  * @param   pvUser          User argument.
  */
-static DECLCALLBACK(int) csamR3CodePageWriteHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf,
-                                                    PGMACCESSTYPE enmAccessType, void *pvUser)
+static DECLCALLBACK(int) csamR3CodePageWriteHandler(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf,
+                                                    PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser)
 {
     int rc;
@@ -2199,4 +2202,5 @@
     else
     {
+        AssertFailed(); /* PGM should make sure this does not happen anymore! */
         /* Queue the write instead otherwise we'll get concurrency issues. */
         /** @note in theory not correct to let it write the data first before disabling a patch!
@@ -2216,7 +2220,9 @@
  *
  * @param   pVM             Pointer to the VM.
+ * @param   pVCpu           Pointer to the cross context CPU context for the
+ *                          calling EMT.
  * @param   GCPtr           The virtual address the guest has changed.
  */
-static DECLCALLBACK(int) csamR3CodePageInvalidate(PVM pVM, RTGCPTR GCPtr, void *pvUser)
+static DECLCALLBACK(int) csamR3CodePageInvalidate(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, void *pvUser)
 {
     g_fInCsamR3CodePageInvalidate = true;
Index: /trunk/src/VBox/VMM/VMMR3/PATM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PATM.cpp	(revision 55899)
+++ /trunk/src/VBox/VMM/VMMR3/PATM.cpp	(revision 55900)
@@ -984,4 +984,6 @@
  * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.
  * @param   pVM             Pointer to the VM.
+ * @param   pVCpu           Pointer to the cross context CPU context for the
+ *                          calling EMT.
  * @param   GCPtr           The virtual address the guest is writing to. (not correct if it's an alias!)
  * @param   pvPtr           The HC mapping of that address.
@@ -989,11 +991,12 @@
  * @param   cbBuf           How much it's reading/writing.
  * @param   enmAccessType   The access type.
- * @param   pvUser          User argument.
- */
-static DECLCALLBACK(int) patmR3VirtPageHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf,
-                                               PGMACCESSTYPE enmAccessType, void *pvUser)
+ * @param   enmOrigin       Who is making this write.
+ * @param   pvUser          The address of the guest page we're monitoring.
+ */
+static DECLCALLBACK(int) patmR3VirtPageHandler(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf,
+                                               PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser)
 {
     Assert(enmAccessType == PGMACCESSTYPE_WRITE); NOREF(enmAccessType);
-    NOREF(pvPtr); NOREF(pvBuf); NOREF(cbBuf); NOREF(pvUser);
+    NOREF(pVCpu); NOREF(pvPtr); NOREF(pvBuf); NOREF(cbBuf); NOREF(enmOrigin); NOREF(pvUser);
 
     /** @todo could be the wrong virtual address (alias) */
Index: /trunk/src/VBox/VMM/VMMR3/SELM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/SELM.cpp	(revision 55899)
+++ /trunk/src/VBox/VMM/VMMR3/SELM.cpp	(revision 55900)
@@ -1491,4 +1491,6 @@
  * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.
  * @param   pVM             Pointer to the VM.
+ * @param   pVCpu           Pointer to the cross context CPU context for the
+ *                          calling EMT.
  * @param   GCPtr           The virtual address the guest is writing to. (not correct if it's an alias!)
  * @param   pvPtr           The HC mapping of that address.
@@ -1496,14 +1498,15 @@
  * @param   cbBuf           How much it's reading/writing.
  * @param   enmAccessType   The access type.
- * @param   pvUser          User argument.
- */
-static DECLCALLBACK(int) selmR3GuestGDTWriteHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf,
-                                                    PGMACCESSTYPE enmAccessType, void *pvUser)
+ * @param   enmOrigin       Who is making this write.
+ * @param   pvUser          Unused.
+ */
+static DECLCALLBACK(int) selmR3GuestGDTWriteHandler(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf,
+                                                    PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser)
 {
     Assert(enmAccessType == PGMACCESSTYPE_WRITE); NOREF(enmAccessType);
     Log(("selmR3GuestGDTWriteHandler: write to %RGv size %d\n", GCPtr, cbBuf)); NOREF(GCPtr); NOREF(cbBuf);
-    NOREF(pvPtr); NOREF(pvBuf); NOREF(pvUser);
-
-    VMCPU_FF_SET(VMMGetCpu(pVM), VMCPU_FF_SELM_SYNC_GDT);
+    NOREF(pvPtr); NOREF(pvBuf); NOREF(enmOrigin); NOREF(pvUser);
+
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_GDT);
     return VINF_PGM_HANDLER_DO_DEFAULT;
 }
@@ -1520,4 +1523,6 @@
  * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.
  * @param   pVM             Pointer to the VM.
+ * @param   pVCpu           Pointer to the cross context CPU context for the
+ *                          calling EMT.
  * @param   GCPtr           The virtual address the guest is writing to. (not correct if it's an alias!)
  * @param   pvPtr           The HC mapping of that address.
@@ -1525,14 +1530,15 @@
  * @param   cbBuf           How much it's reading/writing.
  * @param   enmAccessType   The access type.
- * @param   pvUser          User argument.
- */
-static DECLCALLBACK(int) selmR3GuestLDTWriteHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf,
-                                                    PGMACCESSTYPE enmAccessType, void *pvUser)
+ * @param   enmOrigin       Who is making this write.
+ * @param   pvUser          Unused.
+ */
+static DECLCALLBACK(int) selmR3GuestLDTWriteHandler(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf,
+                                                    PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser)
 {
     Assert(enmAccessType == PGMACCESSTYPE_WRITE); NOREF(enmAccessType);
     Log(("selmR3GuestLDTWriteHandler: write to %RGv size %d\n", GCPtr, cbBuf)); NOREF(GCPtr); NOREF(cbBuf);
-    NOREF(pvPtr); NOREF(pvBuf); NOREF(pvUser);
-
-    VMCPU_FF_SET(VMMGetCpu(pVM), VMCPU_FF_SELM_SYNC_LDT);
+    NOREF(pvPtr); NOREF(pvBuf); NOREF(enmOrigin); NOREF(pvUser);
+
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_LDT);
     return VINF_PGM_HANDLER_DO_DEFAULT;
 }
@@ -1550,4 +1556,6 @@
  * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.
  * @param   pVM             Pointer to the VM.
+ * @param   pVCpu           Pointer to the cross context CPU context for the
+ *                          calling EMT.
  * @param   GCPtr           The virtual address the guest is writing to. (not correct if it's an alias!)
  * @param   pvPtr           The HC mapping of that address.
@@ -1555,12 +1563,13 @@
  * @param   cbBuf           How much it's reading/writing.
  * @param   enmAccessType   The access type.
- * @param   pvUser          User argument.
- */
-static DECLCALLBACK(int) selmR3GuestTSSWriteHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf,
-                                                    PGMACCESSTYPE enmAccessType, void *pvUser)
+ * @param   enmOrigin       Who is making this write.
+ * @param   pvUser          Unused.
+ */
+static DECLCALLBACK(int) selmR3GuestTSSWriteHandler(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf,
+                                                    PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser)
 {
     Assert(enmAccessType == PGMACCESSTYPE_WRITE); NOREF(enmAccessType);
     Log(("selmR3GuestTSSWriteHandler: write %.*Rhxs to %RGv size %d\n", RT_MIN(8, cbBuf), pvBuf, GCPtr, cbBuf));
-    NOREF(pvBuf); NOREF(GCPtr); NOREF(cbBuf); NOREF(pvUser);NOREF(pvPtr);
+    NOREF(pvBuf); NOREF(GCPtr); NOREF(cbBuf); NOREF(enmOrigin); NOREF(pvUser); NOREF(pvPtr);
 
     /** @todo This can be optimized by checking for the ESP0 offset and tracking TR
@@ -1569,5 +1578,5 @@
      *        changes while we're in REM. */
 
-    VMCPU_FF_SET(VMMGetCpu(pVM), VMCPU_FF_SELM_SYNC_TSS);
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_TSS);
     return VINF_PGM_HANDLER_DO_DEFAULT;
 }
Index: /trunk/src/VBox/VMM/VMMR3/TRPM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/TRPM.cpp	(revision 55899)
+++ /trunk/src/VBox/VMM/VMMR3/TRPM.cpp	(revision 55900)
@@ -442,5 +442,5 @@
 static DECLCALLBACK(int) trpmR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
 #ifdef TRPM_TRACK_GUEST_IDT_CHANGES
-static DECLCALLBACK(int) trpmR3GuestIDTWriteHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser);
+static FNPGMR3VIRTHANDLER trpmR3GuestIDTWriteHandler;
 #endif
 
@@ -1181,4 +1181,6 @@
  * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.
  * @param   pVM             Pointer to the VM.
+ * @param   pVCpu           Pointer to the cross context CPU context for the
+ *                          calling EMT.
  * @param   GCPtr           The virtual address the guest is writing to. (not correct if it's an alias!)
  * @param   pvPtr           The HC mapping of that address.
@@ -1186,15 +1188,16 @@
  * @param   cbBuf           How much it's reading/writing.
  * @param   enmAccessType   The access type.
+ * @param   enmOrigin       The origin of this call.
  * @param   pvUser          User argument.
  */
-static DECLCALLBACK(int) trpmR3GuestIDTWriteHandler(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf,
-                                                    PGMACCESSTYPE enmAccessType, void *pvUser)
+static DECLCALLBACK(int) trpmR3GuestIDTWriteHandler(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf,
+                                                    PGMACCESSTYPE enmAccessType, PGMACCESSORIGIN enmOrigin, void *pvUser)
 {
     Assert(enmAccessType == PGMACCESSTYPE_WRITE); NOREF(enmAccessType);
     Log(("trpmR3GuestIDTWriteHandler: write to %RGv size %d\n", GCPtr, cbBuf)); NOREF(GCPtr); NOREF(cbBuf);
-    NOREF(pvPtr); NOREF(pvUser); NOREF(pvBuf);
+    NOREF(pvPtr); NOREF(pvUser); NOREF(pvBuf); NOREF(enmOrigin); NOREF(pvUser);
     Assert(!HMIsEnabled(pVM));
 
-    VMCPU_FF_SET(VMMGetCpu(pVM), VMCPU_FF_TRPM_SYNC_IDT);
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_TRPM_SYNC_IDT);
     return VINF_PGM_HANDLER_DO_DEFAULT;
 }
Index: /trunk/src/VBox/VMM/VMMRC/CSAMRC.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMRC/CSAMRC.cpp	(revision 55899)
+++ /trunk/src/VBox/VMM/VMMRC/CSAMRC.cpp	(revision 55900)
@@ -57,5 +57,7 @@
  * @returns VBox status code (appropriate for GC return).
  * @param   pVM         Pointer to the VM.
- * @param   uErrorCode   CPU Error code.
+ * @param   pVCpu       Pointer to the cross context CPU context for the calling
+ *                      EMT.
+ * @param   uErrorCode  CPU Error code.
  * @param   pRegFrame   Trap register frame.
  * @param   pvFault     The fault address (cr2).
@@ -65,5 +67,5 @@
  * @param   pvUser      Ignored.
  */
-DECLEXPORT(int) csamRCCodePageWritePfHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault,
+DECLEXPORT(int) csamRCCodePageWritePfHandler(PVM pVM, PVMCPU pVCpu, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault,
                                              RTGCPTR pvRange, uintptr_t offRange, void *pvUser)
 {
@@ -71,5 +73,4 @@
     bool         fPatchCode = PATMIsPatchGCAddr(pVM, pRegFrame->eip);
     int          rc;
-    PVMCPU       pVCpu = VMMGetCpu0(pVM);
     NOREF(uErrorCode);
 
Index: /trunk/src/VBox/VMM/VMMRC/PATMRC.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMRC/PATMRC.cpp	(revision 55899)
+++ /trunk/src/VBox/VMM/VMMRC/PATMRC.cpp	(revision 55900)
@@ -50,5 +50,7 @@
  * @returns VBox status code (appropriate for trap handling and GC return).
  * @param   pVM         Pointer to the VM.
- * @param   uErrorCode   CPU Error code.
+ * @param   pVCpu       Pointer to the cross context CPU context for the
+ *                      calling EMT.
+ * @param   uErrorCode  CPU Error code.
  * @param   pRegFrame   Trap register frame.
  * @param   pvFault     The fault address (cr2).
@@ -56,9 +58,10 @@
  * @param   offRange    The offset of the access into this range.
  *                      (If it's a EIP range this is the EIP, if not it's pvFault.)
+ * @param   pvUser      The physical address of the guest page being monitored.
  */
-DECLEXPORT(int) patmRCVirtPagePfHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault,
+DECLEXPORT(int) patmRCVirtPagePfHandler(PVM pVM, PVMCPU pVCpu, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault,
                                         RTGCPTR pvRange, uintptr_t offRange, void *pvUser)
 {
-    NOREF(uErrorCode); NOREF(pRegFrame); NOREF(pvFault); NOREF(pvRange); NOREF(offRange);
+    NOREF(pVCpu); NOREF(uErrorCode); NOREF(pRegFrame); NOREF(pvFault); NOREF(pvRange); NOREF(offRange); NOREF(pvUser);
     pVM->patm.s.pvFaultMonitor = (RTRCPTR)(RTRCUINTPTR)pvFault;
     return VINF_PATM_CHECK_PATCH_PAGE;
Index: /trunk/src/VBox/VMM/VMMRC/SELMRC.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMRC/SELMRC.cpp	(revision 55899)
+++ /trunk/src/VBox/VMM/VMMRC/SELMRC.cpp	(revision 55900)
@@ -228,4 +228,6 @@
  * @returns VBox status code (appropriate for trap handling and GC return).
  * @param   pVM         Pointer to the VM.
+ * @param   pVCpu       Pointer to the cross context CPU context for the
+ *                      calling EMT.
  * @param   uErrorCode  CPU Error code.
  * @param   pRegFrame   Trap register frame.
@@ -235,8 +237,7 @@
  *                      (If it's a EIP range this is the EIP, if not it's pvFault.)
  */
-DECLEXPORT(int) selmRCGuestGDTWritePfHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault,
+DECLEXPORT(int) selmRCGuestGDTWritePfHandler(PVM pVM, PVMCPU pVCpu, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault,
                                              RTGCPTR pvRange, uintptr_t offRange, void *pvUser)
 {
-    PVMCPU pVCpu = VMMGetCpu0(pVM);
     LogFlow(("selmRCGuestGDTWritePfHandler errcode=%x fault=%RGv offRange=%08x\n", (uint32_t)uErrorCode, pvFault, offRange));
     NOREF(pvRange); NOREF(pvUser);
@@ -322,4 +323,6 @@
  * @returns VBox status code (appropriate for trap handling and GC return).
  * @param   pVM         Pointer to the VM.
+ * @param   pVCpu       Pointer to the cross context CPU context for the
+ *                      calling EMT.
  * @param   uErrorCode   CPU Error code.
  * @param   pRegFrame   Trap register frame.
@@ -330,5 +333,5 @@
  * @param   pvUser      Unused.
  */
-DECLEXPORT(int) selmRCGuestLDTWritePfHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault,
+DECLEXPORT(int) selmRCGuestLDTWritePfHandler(PVM pVM, PVMCPU pVCpu, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault,
                                              RTGCPTR pvRange, uintptr_t offRange, void *pvUser)
 {
@@ -337,5 +340,5 @@
     NOREF(uErrorCode); NOREF(pRegFrame); NOREF(pvFault); NOREF(pvRange); NOREF(offRange); NOREF(pvUser);
 
-    VMCPU_FF_SET(VMMGetCpu0(pVM), VMCPU_FF_SELM_SYNC_LDT);
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_SELM_SYNC_LDT);
     STAM_COUNTER_INC(&pVM->selm.s.StatRCWriteGuestLDT);
     return VINF_EM_RAW_EMULATE_INSTR_LDT_FAULT;
@@ -377,4 +380,6 @@
  * @returns VBox status code (appropriate for trap handling and GC return).
  * @param   pVM         Pointer to the VM.
+ * @param   pVCpu       Pointer to the cross context CPU context for the
+ *                      calling EMT.
  * @param   uErrorCode  CPU Error code.
  * @param   pRegFrame   Trap register frame.
@@ -385,8 +390,7 @@
  * @param   pvUser      Unused.
  */
-DECLEXPORT(int) selmRCGuestTSSWritePfHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault,
+DECLEXPORT(int) selmRCGuestTSSWritePfHandler(PVM pVM, PVMCPU pVCpu, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault,
                                              RTGCPTR pvRange, uintptr_t offRange, void *pvUser)
 {
-    PVMCPU pVCpu = VMMGetCpu0(pVM);
     LogFlow(("selmRCGuestTSSWritePfHandler errcode=%x fault=%RGv offRange=%08x\n", (uint32_t)uErrorCode, pvFault, offRange));
     NOREF(pvRange); NOREF(pvUser);
@@ -532,4 +536,6 @@
  * @returns VBox status code (appropriate for trap handling and GC return).
  * @param   pVM         Pointer to the VM.
+ * @param   pVCpu       Pointer to the cross context CPU context for the
+ *                      calling EMT.
  * @param   uErrorCode   CPU Error code.
  * @param   pRegFrame   Trap register frame.
@@ -540,9 +546,9 @@
  * @param   pvUser      Unused.
  */
-DECLEXPORT(int) selmRCShadowGDTWritePfHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault,
+DECLEXPORT(int) selmRCShadowGDTWritePfHandler(PVM pVM, PVMCPU pVCpu, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault,
                                               RTGCPTR pvRange, uintptr_t offRange, void *pvUser)
 {
     LogRel(("FATAL ERROR: selmRCShadowGDTWritePfHandler: eip=%08X pvFault=%RGv pvRange=%RGv\r\n", pRegFrame->eip, pvFault, pvRange));
-    NOREF(pVM); NOREF(uErrorCode); NOREF(pRegFrame); NOREF(pvFault); NOREF(pvRange); NOREF(offRange); NOREF(pvUser);
+    NOREF(pVM); NOREF(pVCpu); NOREF(uErrorCode); NOREF(pRegFrame); NOREF(pvFault); NOREF(pvRange); NOREF(offRange); NOREF(pvUser);
     return VERR_SELM_SHADOW_GDT_WRITE;
 }
@@ -556,4 +562,6 @@
  * @returns VBox status code (appropriate for trap handling and GC return).
  * @param   pVM         Pointer to the VM.
+ * @param   pVCpu       Pointer to the cross context CPU context for the
+ *                      calling EMT.
  * @param   uErrorCode   CPU Error code.
  * @param   pRegFrame   Trap register frame.
@@ -564,10 +572,10 @@
  * @param   pvUser      Unused.
  */
-DECLEXPORT(int) selmRCShadowLDTWritePfHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault,
+DECLEXPORT(int) selmRCShadowLDTWritePfHandler(PVM pVM, PVMCPU pVCpu, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault,
                                               RTGCPTR pvRange, uintptr_t offRange, void *pvUser)
 {
     LogRel(("FATAL ERROR: selmRCShadowLDTWritePfHandler: eip=%08X pvFault=%RGv pvRange=%RGv\r\n", pRegFrame->eip, pvFault, pvRange));
     Assert(pvFault - (uintptr_t)pVM->selm.s.pvLdtRC < (unsigned)(65536U + PAGE_SIZE));
-    NOREF(pVM); NOREF(uErrorCode); NOREF(pRegFrame); NOREF(pvFault); NOREF(pvRange); NOREF(offRange); NOREF(pvUser);
+    NOREF(pVM); NOREF(pVCpu); NOREF(uErrorCode); NOREF(pRegFrame); NOREF(pvFault); NOREF(pvRange); NOREF(offRange); NOREF(pvUser);
     return VERR_SELM_SHADOW_LDT_WRITE;
 }
@@ -581,4 +589,6 @@
  * @returns VBox status code (appropriate for trap handling and GC return).
  * @param   pVM         Pointer to the VM.
+ * @param   pVCpu       Pointer to the cross context CPU context for the
+ *                      calling EMT.
  * @param   uErrorCode   CPU Error code.
  * @param   pRegFrame   Trap register frame.
@@ -589,9 +599,9 @@
  * @param   pvUser      Unused.
  */
-DECLEXPORT(int) selmRCShadowTSSWritePfHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault,
+DECLEXPORT(int) selmRCShadowTSSWritePfHandler(PVM pVM, PVMCPU pVCpu, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault,
                                               RTGCPTR pvRange, uintptr_t offRange, void *pvUser)
 {
     LogRel(("FATAL ERROR: selmRCShadowTSSWritePfHandler: eip=%08X pvFault=%RGv pvRange=%RGv\r\n", pRegFrame->eip, pvFault, pvRange));
-    NOREF(pVM); NOREF(uErrorCode); NOREF(pRegFrame); NOREF(pvFault); NOREF(pvRange); NOREF(offRange); NOREF(pvUser);
+    NOREF(pVM); NOREF(pVCpu); NOREF(uErrorCode); NOREF(pRegFrame); NOREF(pvFault); NOREF(pvRange); NOREF(offRange); NOREF(pvUser);
     return VERR_SELM_SHADOW_TSS_WRITE;
 }
Index: /trunk/src/VBox/VMM/VMMRC/TRPMRC.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMRC/TRPMRC.cpp	(revision 55899)
+++ /trunk/src/VBox/VMM/VMMRC/TRPMRC.cpp	(revision 55900)
@@ -95,4 +95,6 @@
  * @returns VBox status code (appropriate for trap handling and GC return).
  * @param   pVM         Pointer to the VM.
+ * @param   pVCpu       Pointer to the cross context CPU context for the
+ *                      calling EMT.
  * @param   uErrorCode   CPU Error code.
  * @param   pRegFrame   Trap register frame.
@@ -103,8 +105,7 @@
  * @param   pvUser      Unused.
  */
-DECLEXPORT(int) trpmRCGuestIDTWritePfHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault,
+DECLEXPORT(int) trpmRCGuestIDTWritePfHandler(PVM pVM, PVMCPU pVCpu, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault,
                                              RTGCPTR pvRange, uintptr_t offRange, void *pvUser)
 {
-    PVMCPU      pVCpu = VMMGetCpu0(pVM);
     uint16_t    cbIDT;
     RTGCPTR     GCPtrIDT    = (RTGCPTR)CPUMGetGuestIDTR(pVCpu, &cbIDT);
@@ -160,5 +161,7 @@
  * @returns VBox status code (appropriate for trap handling and GC return).
  * @param   pVM         Pointer to the VM.
- * @param   uErrorCode   CPU Error code.
+ * @param   pVCpu       Pointer to the cross context CPU context for the
+ *                      calling EMT.
+ * @param   uErrorCode  CPU Error code.
  * @param   pRegFrame   Trap register frame.
  * @param   pvFault     The fault address (cr2).
@@ -168,8 +171,7 @@
  * @param   pvUser      Unused.
  */
-DECLEXPORT(int) trpmRCShadowIDTWritePfHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault,
+DECLEXPORT(int) trpmRCShadowIDTWritePfHandler(PVM pVM, PVMCPU pVCpu, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault,
                                               RTGCPTR pvRange, uintptr_t offRange, void *pvUser)
 {
-    PVMCPU pVCpu = VMMGetCpu0(pVM);
     LogRel(("FATAL ERROR: trpmRCShadowIDTWritePfHandler: eip=%08X pvFault=%RGv pvRange=%08RGv\r\n", pRegFrame->eip, pvFault, pvRange));
     NOREF(uErrorCode); NOREF(offRange); NOREF(pvUser);
