Index: /trunk/include/VBox/csam.h
===================================================================
--- /trunk/include/VBox/csam.h	(revision 8216)
+++ /trunk/include/VBox/csam.h	(revision 8217)
@@ -274,4 +274,14 @@
 
 /**
+ * Unmonitors a code page
+ *
+ * @returns VBox status code
+ * @param   pVM         The VM to operate on.
+ * @param   pPageAddrGC The page to monitor
+ * @param   enmTag      Monitor tag
+ */
+CSAMR3DECL(int) CSAMR3UnmonitorPage(PVM pVM, RTGCPTR pPageAddrGC, CSAMTAG enmTag);
+
+/**
  * Analyse interrupt and trap gates
  *
Index: /trunk/src/VBox/VMM/PATM/CSAM.cpp
===================================================================
--- /trunk/src/VBox/VMM/PATM/CSAM.cpp	(revision 8216)
+++ /trunk/src/VBox/VMM/PATM/CSAM.cpp	(revision 8217)
@@ -1818,4 +1818,29 @@
 
 /**
+ * Unmonitors a code page
+ *
+ * @returns VBox status code
+ * @param   pVM         The VM to operate on.
+ * @param   pPageAddrGC The page to monitor
+ * @param   enmTag      Monitor tag
+ */
+CSAMR3DECL(int) CSAMR3UnmonitorPage(PVM pVM, RTGCPTR pPageAddrGC, CSAMTAG enmTag)
+{
+    pPageAddrGC &= PAGE_BASE_GC_MASK;
+
+    Log(("CSAMR3UnmonitorPage %VGv %d\n", pPageAddrGC, enmTag));
+
+    Assert(enmTag == CSAM_TAG_REM);
+
+#ifdef VBOX_STRICT
+    PCSAMPAGEREC pPageRec;
+
+    pPageRec = (PCSAMPAGEREC)RTAvlPVGet(&pVM->csam.s.pPageTree, (AVLPVKEY)pPageAddrGC);
+    Assert(pPageRec && pPageRec->page.enmTag == enmTag);
+#endif
+    return CSAMR3RemovePage(pVM, pPageAddrGC);
+}
+
+/**
  * Removes a page record from our lookup tree
  *
Index: /trunk/src/recompiler/VBoxREMWrapper.cpp
===================================================================
--- /trunk/src/recompiler/VBoxREMWrapper.cpp	(revision 8216)
+++ /trunk/src/recompiler/VBoxREMWrapper.cpp	(revision 8217)
@@ -493,4 +493,10 @@
     { REMPARMDESC_FLAGS_INT,        sizeof(CSAMTAG), NULL }
 };
+static const REMPARMDESC g_aArgsCSAMR3UnmonitorPage[] =
+{
+    { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
+    { REMPARMDESC_FLAGS_INT,        sizeof(RTGCPTR), NULL },
+    { REMPARMDESC_FLAGS_INT,        sizeof(CSAMTAG), NULL }
+};
 
 static const REMPARMDESC g_aArgsCSAMR3RecordCallAddress[] =
@@ -1009,4 +1015,5 @@
     { "CPUMQueryGuestCtxPtr",                   (void *)(uintptr_t)&CPUMQueryGuestCtxPtr,           &g_aArgsCPUMQueryGuestCtxPtr[0],            ELEMENTS(g_aArgsCPUMQueryGuestCtxPtr),              REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
     { "CSAMR3MonitorPage",                      (void *)(uintptr_t)&CSAMR3MonitorPage,              &g_aArgsCSAMR3MonitorPage[0],               ELEMENTS(g_aArgsCSAMR3MonitorPage),                 REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
+    { "CSAMR3UnmonitorPage",                    (void *)(uintptr_t)&CSAMR3UnmonitorPage,            &g_aArgsCSAMR3UnmonitorPage[0],             ELEMENTS(g_aArgsCSAMR3UnmonitorPage),               REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
     { "CSAMR3RecordCallAddress",                (void *)(uintptr_t)&CSAMR3RecordCallAddress,        &g_aArgsCSAMR3RecordCallAddress[0],         ELEMENTS(g_aArgsCSAMR3RecordCallAddress),           REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
 #if defined(VBOX_WITH_DEBUGGER) && !(defined(RT_OS_WINDOWS) && defined(RT_ARCH_AMD64)) /* the callbacks are problematic */
Index: /trunk/src/recompiler/VBoxRecompiler.c
===================================================================
--- /trunk/src/recompiler/VBoxRecompiler.c	(revision 8216)
+++ /trunk/src/recompiler/VBoxRecompiler.c	(revision 8217)
@@ -1375,4 +1375,21 @@
         &&  !HWACCMIsEnabled(env->pVM))
         CSAMR3MonitorPage(env->pVM, GCPtr, CSAM_TAG_REM);
+}
+
+/**
+ * Called from tlb_unprotect_code in order to clear write monitoring for a code page.
+ *
+ * @param   env             Pointer to the CPU environment.
+ * @param   GCPtr           Code page to monitor
+ */
+void remR3UnprotectCode(CPUState *env, RTGCPTR GCPtr)
+{
+    Assert(env->pVM->rem.s.fInREM);
+    if (     (env->cr[0] & X86_CR0_PG)                      /* paging must be enabled */
+        &&  !(env->state & CPU_EMULATE_SINGLE_INSTR)        /* ignore during single instruction execution */
+        &&   (((env->hflags >> HF_CPL_SHIFT) & 3) == 0)     /* supervisor mode only */
+        &&  !(env->eflags & VM_MASK)                        /* no V86 mode */
+        &&  !HWACCMIsEnabled(env->pVM))
+        CSAMR3UnmonitorPage(env->pVM, GCPtr, CSAM_TAG_REM);
 }
 
