Index: trunk/src/VBox/VMM/HWACCMInternal.h
===================================================================
--- trunk/src/VBox/VMM/HWACCMInternal.h	(revision 8851)
+++ trunk/src/VBox/VMM/HWACCMInternal.h	(revision 8853)
@@ -211,4 +211,6 @@
         bool                        fResumeVM;
         /** Set if erratum 170 affects the AMD cpu. */
+        bool                        fAlwaysFlushTLB;
+        /** Set if we need to flush the TLB during the world switch. */
         bool                        fForceTLBFlush;
 
Index: trunk/src/VBox/VMM/PGMInternal.h
===================================================================
--- trunk/src/VBox/VMM/PGMInternal.h	(revision 8851)
+++ trunk/src/VBox/VMM/PGMInternal.h	(revision 8853)
@@ -36,4 +36,5 @@
 #include <VBox/log.h>
 #include <VBox/gmm.h>
+#include <VBox/hwaccm.h>
 #include <iprt/avl.h>
 #include <iprt/assert.h>
@@ -266,4 +267,6 @@
 #ifdef IN_GC
 # define PGM_INVL_PG(GCVirt)        ASMInvalidatePage((void *)(GCVirt))
+#elif defined(IN_RING0)
+# define PGM_INVL_PG(GCVirt)        HWACCMR0InvalidatePage(pVM, (RTGCPTR)(GCVirt))
 #else
 # define PGM_INVL_PG(GCVirt)        ((void)0)
@@ -277,4 +280,6 @@
 #ifdef IN_GC
 # define PGM_INVL_BIG_PG(GCVirt)    ASMReloadCR3()
+#elif defined(IN_RING0)
+# define PGM_INVL_BIG_PG(GCVirt)    HWACCMR0FlushTLB(pVM)
 #else
 # define PGM_INVL_BIG_PG(GCVirt)    ((void)0)
@@ -286,4 +291,6 @@
 #ifdef IN_GC
 # define PGM_INVL_GUEST_TLBS()      ASMReloadCR3()
+#elif defined(IN_RING0)
+# define PGM_INVL_GUEST_TLBS()      HWACCMR0FlushTLB(pVM)
 #else
 # define PGM_INVL_GUEST_TLBS()      ((void)0)
Index: trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp	(revision 8851)
+++ trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp	(revision 8853)
@@ -908,4 +908,7 @@
 static int pgmPoolCacheFreeOne(PPGMPOOL pPool, uint16_t iUser)
 {
+#ifdef IN_RING0
+    const PVM pVM = pPool->CTXSUFF(pVM);
+#endif
     Assert(pPool->iAgeHead != pPool->iAgeTail); /* We shouldn't be here if there < 2 cached entries! */
     STAM_COUNTER_INC(&pPool->StatCacheFreeUpOne);
@@ -1032,4 +1035,7 @@
 static int pgmPoolCacheAlloc(PPGMPOOL pPool, RTGCPHYS GCPhys, PGMPOOLKIND enmKind, uint16_t iUser, uint16_t iUserTable, PPPGMPOOLPAGE ppPage)
 {
+#ifdef IN_RING0
+    const PVM pVM = pPool->CTXSUFF(pVM);
+#endif
     /*
      * Look up the GCPhys in the hash.
Index: trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp	(revision 8851)
+++ trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp	(revision 8853)
@@ -807,4 +807,33 @@
         return SVMR0RunGuestCode(pVM, pCtx);
     }
+}
+
+/**
+ * Invalidates a guest page
+ *
+ * @returns VBox status code.
+ * @param   pVM         The VM to operate on.
+ * @param   GCVirt      Page to invalidate
+ */
+HWACCMR0DECL(int) HWACCMR0InvalidatePage(PVM pVM, RTGCPTR GCVirt)
+{
+    if (pVM->hwaccm.s.svm.fSupported)
+        return SVMR0InvalidatePage(pVM, GCVirt);
+
+    return VINF_SUCCESS;
+}
+
+/**
+ * Flushes the guest TLB
+ *
+ * @returns VBox status code.
+ * @param   pVM         The VM to operate on.
+ */
+HWACCMR0DECL(int) HWACCMR0FlushTLB(PVM pVM)
+{
+    if (pVM->hwaccm.s.svm.fSupported)
+        return SVMR0FlushTLB(pVM);
+
+    return VINF_SUCCESS;
 }
 
Index: trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp	(revision 8851)
+++ trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp	(revision 8853)
@@ -170,5 +170,5 @@
     {
         Log(("SVMR0InitVM: AMD cpu with erratum 170 family %x model %x stepping %x\n", u32Family, u32Model, u32Stepping));
-        pVM->hwaccm.s.svm.fForceTLBFlush = true;
+        pVM->hwaccm.s.svm.fAlwaysFlushTLB = true;
     }
 
@@ -681,5 +681,4 @@
     uint64_t    exitCode = (uint64_t)SVM_EXIT_INVALID;
     SVM_VMCB   *pVMCB;
-    bool        fForceTLBFlush = false;
     bool        fGuestStateSynced = false;
     unsigned    cResume = 0;
@@ -768,7 +767,6 @@
     STAM_PROFILE_ADV_START(&pVM->hwaccm.s.StatInGC, x);
 
-    if (    pVM->hwaccm.s.svm.fResumeVM == false
-        ||  pVM->hwaccm.s.svm.fForceTLBFlush
-        ||  fForceTLBFlush)
+    if (    pVM->hwaccm.s.svm.fForceTLBFlush
+        ||  pVM->hwaccm.s.svm.fAlwaysFlushTLB)
     {
         pVMCB->ctrl.TLBCtrl.n.u1TLBFlush = 1;
@@ -778,6 +776,6 @@
 
     /* In case we execute a goto ResumeExecution later on. */
-    pVM->hwaccm.s.svm.fResumeVM = true;
-    fForceTLBFlush = false;
+    pVM->hwaccm.s.svm.fResumeVM      = true;
+    pVM->hwaccm.s.svm.fForceTLBFlush = false;
 
     Assert(sizeof(pVM->hwaccm.s.svm.pVMCBPhys) == 8);
@@ -1287,5 +1285,5 @@
 
             /** @note Force a TLB flush. SVM requires us to do it manually. */
-            fForceTLBFlush = true;
+            pVM->hwaccm.s.svm.fForceTLBFlush = true;
         }
         if (rc == VINF_SUCCESS)
@@ -1599,4 +1597,6 @@
 
     /* Force a TLB flush on VM entry. */
+    pVM->hwaccm.s.svm.fForceTLBFlush = true;
+
     pVM->hwaccm.s.svm.fResumeVM = false;
 
@@ -1654,5 +1654,5 @@
     }
     Assert(rc == VERR_REM_FLUSHED_PAGES_OVERFLOW);
-    return (rc == VERR_REM_FLUSHED_PAGES_OVERFLOW) ? VERR_EM_INTERPRETER : rc;
+    return rc;
 }
 
@@ -1703,2 +1703,38 @@
 }
 
+
+/**
+ * Invalidates a guest page
+ *
+ * @returns VBox status code.
+ * @param   pVM         The VM to operate on.
+ * @param   GCVirt      Page to invalidate
+ */
+HWACCMR0DECL(int) SVMR0InvalidatePage(PVM pVM, RTGCPTR GCVirt)
+{
+    SVM_VMCB   *pVMCB;
+
+    Log2(("SVMR0InvalidatePage %VGv\n", GCVirt));
+    AssertReturn(pVM, VERR_INVALID_PARAMETER);
+    Assert(pVM->hwaccm.s.svm.fSupported);
+
+    pVMCB = (SVM_VMCB *)pVM->hwaccm.s.svm.pVMCB;
+    AssertMsgReturn(pVMCB, ("Invalid pVMCB\n"), VERR_EM_INTERNAL_ERROR);
+
+    SVMInvlpgA(GCVirt, pVMCB->ctrl.TLBCtrl.n.u32ASID);
+    return VINF_SUCCESS;
+}
+
+/**
+ * Flushes the guest TLB
+ *
+ * @returns VBox status code.
+ * @param   pVM         The VM to operate on.
+ */
+HWACCMR0DECL(int) SVMR0FlushTLB(PVM pVM)
+{
+    Log2(("SVMR0FlushTLB\n"));
+    pVM->hwaccm.s.svm.fForceTLBFlush = true;
+
+    return VINF_SUCCESS;
+}
Index: trunk/src/VBox/VMM/VMMR0/HWSVMR0.h
===================================================================
--- trunk/src/VBox/VMM/VMMR0/HWSVMR0.h	(revision 8851)
+++ trunk/src/VBox/VMM/VMMR0/HWSVMR0.h	(revision 8853)
@@ -125,4 +125,21 @@
 HWACCMR0DECL(int) SVMR0LoadGuestState(PVM pVM, CPUMCTX *pCtx);
 
+/**
+ * Invalidates a guest page
+ *
+ * @returns VBox status code.
+ * @param   pVM         The VM to operate on.
+ * @param   GCVirt      Page to invalidate
+ */
+HWACCMR0DECL(int) SVMR0InvalidatePage(PVM pVM, RTGCPTR GCVirt);
+
+/**
+ * Flushes the guest TLB
+ *
+ * @returns VBox status code.
+ * @param   pVM         The VM to operate on.
+ */
+HWACCMR0DECL(int) SVMR0FlushTLB(PVM pVM);
+
 
 /* Convert hidden selector attribute word between VMX and SVM formats. */
