Index: trunk/src/VBox/VMM/EM.cpp
===================================================================
--- trunk/src/VBox/VMM/EM.cpp	(revision 32910)
+++ trunk/src/VBox/VMM/EM.cpp	(revision 32912)
@@ -64,4 +64,5 @@
 #include <iprt/string.h>
 #include <iprt/stream.h>
+#include <iprt/thread.h>
 
 
@@ -144,4 +145,7 @@
         pVCpu->em.s.pPatmGCState = PATMR3QueryGCStateHC(pVM);
         AssertMsg(pVCpu->em.s.pPatmGCState, ("PATMR3QueryGCStateHC failed!\n"));
+
+        /* Force reset of the time slice. */
+        pVCpu->em.s.u64TimeSliceStart = 0;
 
 # define EM_REG_COUNTER(a, b, c) \
@@ -388,4 +392,5 @@
         EM_REG_COUNTER(&pVCpu->em.s.StatForcedActions,     "/PROF/CPU%d/EM/ForcedActions",     "Profiling forced action execution.");
         EM_REG_COUNTER(&pVCpu->em.s.StatHalted,            "/PROF/CPU%d/EM/Halted",            "Profiling halted state (VMR3WaitHalted).");
+        EM_REG_COUNTER(&pVCpu->em.s.StatCapped,            "/PROF/CPU%d/EM/Capped",            "Profiling capped state (sleep).");
         EM_REG_COUNTER(&pVCpu->em.s.StatREMTotal,          "/PROF/CPU%d/EM/REMTotal",          "Profiling emR3RemExecute (excluding FFs).");
         EM_REG_COUNTER(&pVCpu->em.s.StatRAWTotal,          "/PROF/CPU%d/EM/RAWTotal",          "Profiling emR3RawExecute (excluding FFs).");
@@ -1659,4 +1664,36 @@
     Assert(rcIrq == VINF_SUCCESS || rcIrq == rc);
     return rc;
+}
+
+
+/**
+ * Check if the preset execution time cap restricts guest execution scheduling.
+ *
+ * @returns true if allowed, false otherwise
+ * @param   pVM         The VM to operate on.
+ * @param   pVCpu       The VMCPU to operate on.
+ *
+ */
+bool emR3IsExecutionAllowed(PVM pVM, PVMCPU pVCpu)
+{
+    uint64_t u64UserTime, u64KernelTime;
+
+    if (    pVM->uCpuExecutionCap != 100
+        &&  RT_SUCCESS(RTThreadGetExecutionTimeMilli(RTThreadSelf(), &u64KernelTime, &u64UserTime)))
+    {
+        uint64_t u64TimeNow = RTTimeMilliTS();
+        if (pVCpu->em.s.u64TimeSliceStart + EM_TIME_SLICE < u64TimeNow)
+        {
+            /* New time slice. */
+            pVCpu->em.s.u64TimeSliceStart     = u64TimeNow;
+            pVCpu->em.s.u64TimeSliceStartExec = u64KernelTime + u64UserTime;
+            pVCpu->em.s.u64TimeSliceExec      = 0;
+        }
+        pVCpu->em.s.u64TimeSliceExec = u64KernelTime + u64UserTime - pVCpu->em.s.u64TimeSliceStartExec;
+
+        if (pVCpu->em.s.u64TimeSliceExec >= (EM_TIME_SLICE * 100) / pVM->uCpuExecutionCap)
+            return false;
+    }
+    return true;
 }
 
@@ -1963,5 +2000,16 @@
                  */
                 case EMSTATE_RAW:
-                    rc = emR3RawExecute(pVM, pVCpu, &fFFDone);
+                    if (emR3IsExecutionAllowed(pVM, pVCpu))
+                    {
+                        rc = emR3RawExecute(pVM, pVCpu, &fFFDone);
+                    }
+                    else
+                    {
+                        /* Give up this time slice; virtual time continues */
+                        STAM_REL_PROFILE_START(&pVCpu->em.s.StatCapped, u);
+                        RTThreadSleep(2);
+                        STAM_REL_PROFILE_STOP(&pVCpu->em.s.StatCapped, u);
+                        rc = VINF_SUCCESS;
+                    }
                     break;
 
@@ -1970,5 +2018,16 @@
                  */
                 case EMSTATE_HWACC:
-                    rc = emR3HwAccExecute(pVM, pVCpu, &fFFDone);
+                    if (emR3IsExecutionAllowed(pVM, pVCpu))
+                    {
+                        rc = emR3HwAccExecute(pVM, pVCpu, &fFFDone);
+                    }
+                    else
+                    {
+                        /* Give up this time slice; virtual time continues */
+                        STAM_REL_PROFILE_START(&pVCpu->em.s.StatCapped, u);
+                        RTThreadSleep(2);
+                        STAM_REL_PROFILE_STOP(&pVCpu->em.s.StatCapped, u);
+                        rc = VINF_SUCCESS;
+                    }
                     break;
 
@@ -1977,6 +2036,17 @@
                  */
                 case EMSTATE_REM:
-                    rc = emR3RemExecute(pVM, pVCpu, &fFFDone);
-                    Log2(("EMR3ExecuteVM: emR3RemExecute -> %Rrc\n", rc));
+                    if (emR3IsExecutionAllowed(pVM, pVCpu))
+                    {
+                        rc = emR3RemExecute(pVM, pVCpu, &fFFDone);
+                        Log2(("EMR3ExecuteVM: emR3RemExecute -> %Rrc\n", rc));
+                    }
+                    else
+                    {
+                        /* Give up this time slice; virtual time continues */
+                        STAM_REL_PROFILE_START(&pVCpu->em.s.StatCapped, u);
+                        RTThreadSleep(2);
+                        STAM_REL_PROFILE_STOP(&pVCpu->em.s.StatCapped, u);
+                        rc = VINF_SUCCESS;
+                    }
                     break;
 
Index: trunk/src/VBox/VMM/EMInternal.h
===================================================================
--- trunk/src/VBox/VMM/EMInternal.h	(revision 32910)
+++ trunk/src/VBox/VMM/EMInternal.h	(revision 32912)
@@ -54,4 +54,6 @@
 #define EMMWAIT_FLAG_MONITOR_ACTIVE     RT_BIT(2)
 
+/** EM time slice in ms; used for capping execution time. */
+#define EM_TIME_SLICE                   1000
 
 /**
@@ -352,4 +354,12 @@
 #endif
 
+    /** Start of the current time slice in ms. */
+    uint64_t                u64TimeSliceStart;
+    /** Start of the current time slice in thread execution time (ms). */
+    uint64_t                u64TimeSliceStartExec;
+    /** Current time slice value. */
+    uint64_t                u64TimeSliceExec;
+    uint64_t                u64Alignment;
+
     /* MWait halt state. */
     struct
@@ -391,4 +401,5 @@
     STAMPROFILE             StatForcedActions;
     STAMPROFILE             StatHalted;
+    STAMPROFILE             StatCapped;
     STAMPROFILEADV          StatHwAccEntry;
     STAMPROFILE             StatHwAccExec;
Index: trunk/src/VBox/VMM/include/internal/em.h
===================================================================
--- trunk/src/VBox/VMM/include/internal/em.h	(revision 32910)
+++ trunk/src/VBox/VMM/include/internal/em.h	(revision 32912)
@@ -21,6 +21,6 @@
 #include <VBox/em.h>
 
-VMMR3DECL(int) EMR3NotifyResume(PVM pVM);
-VMMR3DECL(int) EMR3NotifySuspend(PVM pVM);
+VMMR3DECL(int)  EMR3NotifyResume(PVM pVM);
+VMMR3DECL(int)  EMR3NotifySuspend(PVM pVM);
 
 #endif
