Index: trunk/src/VBox/VMM/HWACCMInternal.h
===================================================================
--- trunk/src/VBox/VMM/HWACCMInternal.h	(revision 15851)
+++ trunk/src/VBox/VMM/HWACCMInternal.h	(revision 15852)
@@ -435,4 +435,7 @@
 typedef struct HWACCMCPU
 {
+    /** Time of entry into the ring 0 world switcher code. */
+    uint64_t                    u64TimeEntry;
+
     /** Old style FPU reporting trap mask override performed (optimization) */
     bool                        fFPUOldStyleOverride;
Index: trunk/src/VBox/VMM/VMM.cpp
===================================================================
--- trunk/src/VBox/VMM/VMM.cpp	(revision 15851)
+++ trunk/src/VBox/VMM/VMM.cpp	(revision 15852)
@@ -1426,4 +1426,11 @@
             LogRel((pVM->vmm.s.szRing0AssertMsg2));
             return VERR_VMM_RING0_ASSERTION;
+
+        /* 
+         * A forced switch to ring 0 for preemption purposes. 
+         */
+        case VMMCALLHOST_VM_R0_PREEMPT:
+            pVM->vmm.s.rcCallHost = VINF_SUCCESS;
+            break;
 
         default:
Index: trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp	(revision 15851)
+++ trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp	(revision 15852)
@@ -39,4 +39,5 @@
 #include <iprt/asm.h>
 #include <iprt/string.h>
+#include <iprt/time.h>
 #include "HWVMXR0.h"
 
@@ -1893,4 +1894,5 @@
     RTGCUINTPTR errCode, instrInfo;
     bool        fSyncTPR = false;
+    bool        fPreemptPending = false;
     PHWACCM_CPUINFO pCpu = 0;
     unsigned    cResume = 0;
@@ -1966,4 +1968,7 @@
     }
 #endif
+
+    /* Fetch the current time so we can bail out when necessary. */
+    pVCpu->hwaccm.s.u64TimeEntry = RTTimeNanoTS();
 
     /* We can jump to this point to resume execution after determining that a VM-exit is innocent.
@@ -1980,5 +1985,6 @@
 
     /* Safety precaution; looping for too long here can have a very bad effect on the host */
-    if (++cResume > HWACCM_MAX_RESUME_LOOPS)
+    if (    ++cResume > HWACCM_MAX_RESUME_LOOPS
+        ||  RTTimeNanoTS() - pVCpu->hwaccm.s.u64TimeEntry >= 2000000)
     {
         STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitMaxResume);
@@ -2157,9 +2163,12 @@
     STAM_PROFILE_ADV_START(&pVCpu->hwaccm.s.StatExit1, v);
 
-    if (rc != VINF_SUCCESS)
+    if (VBOX_FAILURE(rc))
     {
         VMXR0ReportWorldSwitchError(pVM, pVCpu, rc, pCtx);
         goto end;
     }
+    if (rc == VINF_VMX_PREEMPT_PENDING)
+        fPreemptPending = true;
+
     /* Success. Query the guest state and figure out what has happened. */
 
@@ -2236,4 +2245,11 @@
     {
         rc = PDMApicSetTPR(pVM, pVM->hwaccm.s.vmx.pAPIC[0x80] >> 4);
+        AssertRC(rc);
+    }
+
+    if (fPreemptPending)
+    {
+        fPreemptPending = false;
+        rc = VMMR0CallHost(pVM, VMMCALLHOST_VM_R0_PREEMPT, 0);
         AssertRC(rc);
     }
@@ -3009,9 +3025,5 @@
 
     case VMX_EXIT_PREEMPTION_TIMER:     /* 52 VMX-preemption timer expired. The preemption timer counted down to zero. */
-#ifdef RT_OS_WINDOWS
         goto ResumeExecution;
-#else
-        break; /* enable interrupts again */
-#endif
 
     default:
@@ -3583,31 +3595,5 @@
     aParam[5] = 0;
 
-    if (pVM->hwaccm.s.vmx.msr.vmx_pin_ctls.n.allowed1 & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER)
-    {
-        uint32_t uBit, val;
-
-        rc = VMXReadVMCS32(VMX_VMCS_CTRL_PIN_EXEC_CONTROLS, &val);
-        AssertRC(rc);
-        val  = val | VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER;
-        rc = VMXWriteVMCS(VMX_VMCS_CTRL_PIN_EXEC_CONTROLS, val);
-        AssertRC(rc);
-
-        uBit = MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(pVM->hwaccm.s.vmx.msr.vmx_misc);
-        val = 1000000 / RT_BIT(uBit);
-        VMXWriteVMCS(VMX_VMCS32_GUEST_PREEMPTION_TIMER_VALUE, val);
-    }
-
     rc = VMXR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hwaccm.s.pfnVMXGCStartVM64, 6, &aParam[0]);
-
-    if (pVM->hwaccm.s.vmx.msr.vmx_pin_ctls.n.allowed1 & VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER)
-    {
-        uint32_t val;
-
-        rc = VMXReadVMCS32(VMX_VMCS_CTRL_PIN_EXEC_CONTROLS, &val);
-        AssertRC(rc);
-        val  = val & ~VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER;
-        rc = VMXWriteVMCS(VMX_VMCS_CTRL_PIN_EXEC_CONTROLS, val);
-        AssertRC(rc);
-    }
 
 #ifdef DEBUG
@@ -3621,4 +3607,10 @@
 #endif
 
+    /* Check if we've been running too long. */
+    if (    rc == VINF_SUCCESS
+        &&  RTTimeNanoTS() - pVM->hwaccm.s.u64TimeEntry >= 2000000
+    {
+        return VINF_VMX_PREEMPT_PENDING;
+    }
     return rc;
 }
