Index: /trunk/include/VBox/hwaccm.h
===================================================================
--- /trunk/include/VBox/hwaccm.h	(revision 19811)
+++ /trunk/include/VBox/hwaccm.h	(revision 19812)
@@ -81,4 +81,5 @@
 #ifndef IN_RC
 VMMDECL(int)     HWACCMFlushTLB(PVMCPU pVCpu);
+VMMDECL(int)     HWACCMFlushAllTLBs(PVM pVM);
 VMMDECL(int)     HWACCMInvalidatePhysPage(PVMCPU pVCpu, RTGCPHYS GCPhys);
 VMMDECL(bool)    HWACCMIsNestedPagingActive(PVM pVM);
Index: /trunk/include/VBox/vm.h
===================================================================
--- /trunk/include/VBox/vm.h	(revision 19811)
+++ /trunk/include/VBox/vm.h	(revision 19812)
@@ -293,4 +293,9 @@
  * (NON-GLOBAL FLUSH) */
 #define VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL    RT_BIT_32(17)
+/** Check for pending TLB shootdown actions. */
+#define VMCPU_FF_TLB_SHOOTDOWN              RT_BIT_32(18)
+/** Check for pending TLB flush action. */
+#define VMCPU_FF_TLB_FLUSH_BIT              19
+#define VMCPU_FF_TLB_FLUSH                  RT_BIT_32(VMCPU_FF_TLB_FLUSH_BIT)
 /** Check the interupt and trap gates */
 #define VMCPU_FF_TRPM_SYNC_IDT              RT_BIT_32(20)
@@ -303,6 +308,4 @@
 /** Inhibit interrupts pending. See EMGetInhibitInterruptsPC(). */
 #define VMCPU_FF_INHIBIT_INTERRUPTS         RT_BIT_32(24)
-/** Check for pending TLB shootdown actions. */
-#define VMCPU_FF_TLB_SHOOTDOWN              RT_BIT_32(25)
 /** CSAM needs to scan the page that's being executed */
 #define VMCPU_FF_CSAM_SCAN_PAGE             RT_BIT_32(26)
@@ -451,8 +454,18 @@
 #define VM_FF_TESTANDCLEAR(pVM, iBit)        (ASMBitTestAndClear(&(pVM)->fGlobalForcedActions, iBit))
 
+/** @def VMCPU_FF_TESTANDCLEAR
+ * Checks if one (!) force action in the specified set is pending and clears it atomically
+ *
+ * @returns true if the bit was set.
+ * @returns false if the bit was clear.
+ * @param   pVCpu   VMCPU Handle.
+ * @param   iBit    Bit position to check and clear
+ */
+#define VMCPU_FF_TESTANDCLEAR(pVCpu, iBit)    (ASMBitTestAndClear(&(pVCpu)->fLocalForcedActions, iBit))
+
 /** @def VMCPU_FF_ISPENDING
  * Checks if one or more force action in the specified set is pending for the given VCPU.
  *
- * @param   pVCpu     VMCPU Handle.
+ * @param   pVCpu   VMCPU Handle.
  * @param   fFlags  The flags to check for.
  */
Index: /trunk/src/VBox/VMM/HWACCM.cpp
===================================================================
--- /trunk/src/VBox/VMM/HWACCM.cpp	(revision 19811)
+++ /trunk/src/VBox/VMM/HWACCM.cpp	(revision 19812)
@@ -351,5 +351,6 @@
         HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatFlushASID,              "/HWACCM/CPU%d/Flush/TLB/ASID");
         HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatFlushTLBInvlpga,        "/HWACCM/CPU%d/Flush/TLB/PhysInvl");
-        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatTlbShootdown,           "/HWACCM/CPU%d/Flush/TLB/Shootdown");
+        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatTlbShootdown,           "/HWACCM/CPU%d/Flush/Shootdown/Page");
+        HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatTlbShootdownFlush,      "/HWACCM/CPU%d/Flush/Shootdown/TLB");
         
         HWACCM_REG_COUNTER(&pVCpu->hwaccm.s.StatTSCOffset,              "/HWACCM/CPU%d/TSC/Offset");
Index: /trunk/src/VBox/VMM/HWACCMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/HWACCMInternal.h	(revision 19811)
+++ /trunk/src/VBox/VMM/HWACCMInternal.h	(revision 19812)
@@ -641,4 +641,5 @@
     STAMCOUNTER             StatFlushTLBInvlpga;
     STAMCOUNTER             StatTlbShootdown;
+    STAMCOUNTER             StatTlbShootdownFlush;
 
     STAMCOUNTER             StatSwitchGuestIrq;
Index: /trunk/src/VBox/VMM/VMMAll/HWACCMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/HWACCMAll.cpp	(revision 19811)
+++ /trunk/src/VBox/VMM/VMMAll/HWACCMAll.cpp	(revision 19812)
@@ -80,4 +80,42 @@
 }
 
+#ifndef IN_RC
+/**
+ * Flush the TLBs of all VCPUs
+ *
+ * @returns VBox status code.
+ * @param   pVM       The VM to operate on.
+ */
+VMMDECL(int) HWACCMFlushAllTLBs(PVM pVM)
+{
+    if (pVM->cCPUs == 1)
+        return HWACCMFlushTLB(&pVM->aCpus[0]);
+
+    VMCPUID idThisCpu = VMMGetCpuId(pVM);
+
+    for (unsigned idCpu = 0; idCpu < pVM->cCPUs; idCpu++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[idCpu];
+
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
+        if (idThisCpu == idCpu)
+            continue;
+
+        if (VMCPU_GET_STATE(pVCpu) == VMCPUSTATE_STARTED_EXEC)
+        {
+            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTlbShootdownFlush);
+#ifdef IN_RING0
+            RTMpPokeCpu(idCpu);
+#else
+            VMR3NotifyCpuFFU(pVCpu->pUVCpu, VMNOTIFYFF_FLAGS_POKE);
+#endif
+        }
+        else
+            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFlushTLBManual);
+    }
+    return VINF_SUCCESS;
+}
+#endif
+
 /**
  * Checks if nested paging is enabled
Index: /trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp	(revision 19811)
+++ /trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp	(revision 19812)
@@ -914,6 +914,4 @@
     }
 
-    VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC);
-
     /* When external interrupts are pending, we should exit the VM when IF is set. */
     /* Note! *After* VM_FF_INHIBIT_INTERRUPTS check!!! */
@@ -987,4 +985,10 @@
         goto end;
     }
+
+    /* Disable interrupts to make sure a poke will interrupt execution. 
+     * This must be done *before* we check for TLB flushes; TLB shootdowns rely on this.
+     */
+    RTCCUINTREG uFlags = ASMIntDisableFlags();
+    VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC);
 
     pCpu = HWACCMR0GetCurrentCpu();
@@ -1002,4 +1006,8 @@
 
     pVCpu->hwaccm.s.idLastCpu = pCpu->idCpu;
+
+    /* Check for tlb shootdown flushes. */
+    if (VMCPU_FF_TESTANDCLEAR(pVCpu, VMCPU_FF_TLB_FLUSH_BIT))
+        pVCpu->hwaccm.s.fForceTLBFlush = true;
 
     /* Make sure we flush the TLB when required. Switch ASID to achieve the same thing, but without actually flushing the whole TLB (which is expensive). */
@@ -1073,4 +1081,5 @@
     TMNotifyEndOfExecution(pVCpu);
     VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STARTED);
+    ASMSetFlags(uFlags);
     STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatInGC, x);
 
Index: /trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp	(revision 19811)
+++ /trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp	(revision 19812)
@@ -1828,4 +1828,8 @@
         Assert(!pCpu->fFlushTLB);
 
+    /* Check for tlb shootdown flushes. */
+    if (VMCPU_FF_TESTANDCLEAR(pVCpu, VMCPU_FF_TLB_FLUSH_BIT))
+        pVCpu->hwaccm.s.fForceTLBFlush = true;
+
     pVCpu->hwaccm.s.idLastCpu = pCpu->idCpu;
     pCpu->fFlushTLB           = false;
@@ -1887,4 +1891,8 @@
 
     pVCpu->hwaccm.s.idLastCpu = pCpu->idCpu;
+
+    /* Check for tlb shootdown flushes. */
+    if (VMCPU_FF_TESTANDCLEAR(pVCpu, VMCPU_FF_TLB_FLUSH_BIT))
+        pVCpu->hwaccm.s.fForceTLBFlush = true;
 
     /* Make sure we flush the TLB when required. Switch ASID to achieve the same thing, but without actually flushing the whole TLB (which is expensive). */
@@ -2107,6 +2115,4 @@
     /** @todo check timers?? */
 
-    VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC);
-
     /* TPR caching using CR8 is only available in 64 bits mode */
     /* Note the 32 bits exception for AMD (X86_CPUID_AMD_FEATURE_ECX_CR8L), but that appears missing in Intel CPUs */
@@ -2185,4 +2191,10 @@
     if (rc != VINF_SUCCESS)
         goto end;
+
+    /* Disable interrupts to make sure a poke will interrupt execution. 
+     * This must be done *before* we check for TLB flushes; TLB shootdowns rely on this.
+     */
+    RTCCUINTREG uFlags = ASMIntDisableFlags();
+    VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC);
 
     /* Deal with tagged TLB setup and invalidation. */
@@ -2224,4 +2236,5 @@
     TMNotifyEndOfExecution(pVCpu);
     VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STARTED);
+    ASMSetFlags(uFlags);
 
     AssertMsg(!pVCpu->hwaccm.s.vmx.VMCSCache.Write.cValidEntries, ("pVCpu->hwaccm.s.vmx.VMCSCache.Write.cValidEntries=%d\n", pVCpu->hwaccm.s.vmx.VMCSCache.Write.cValidEntries));
