diff --git a/cpus.c b/cpus.c
index 85d0f87..3ab9e04 100644
--- a/cpus.c
+++ b/cpus.c
@@ -373,6 +373,7 @@ static void icount_warp_rt(void)
 static void icount_dummy_timer(void *opaque)
 {
     (void)opaque;
+    icount_warp_rt();
 }
 
 void qtest_clock_warp(int64_t dest)
@@ -396,17 +397,12 @@ void qtest_clock_warp(int64_t dest)
     qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
 }
 
-void qemu_clock_warp(QEMUClockType type)
+void qemu_start_warp_timer(void)
 {
     int64_t clock;
     int64_t deadline;
 
-    /*
-     * There are too many global variables to make the "warp" behavior
-     * applicable to other clocks.  But a clock argument removes the
-     * need for if statements all over the place.
-     */
-    if (type != QEMU_CLOCK_VIRTUAL || !use_icount) {
+    if (!use_icount) {
         return;
     }
 
@@ -418,29 +414,17 @@ void qemu_clock_warp(QEMUClockType type)
     }
 
     /* warp clock deterministically in record/replay mode */
-    if (!replay_checkpoint(CHECKPOINT_CLOCK_WARP)) {
+    if (!replay_checkpoint(CHECKPOINT_CLOCK_WARP_START)) {
         return;
     }
 
-    if (icount_sleep) {
-        /*
-         * If the CPUs have been sleeping, advance QEMU_CLOCK_VIRTUAL timer now.
-         * This ensures that the deadline for the timer is computed correctly
-         * below.
-         * This also makes sure that the insn counter is synchronized before
-         * the CPU starts running, in case the CPU is woken by an event other
-         * than the earliest QEMU_CLOCK_VIRTUAL timer.
-         */
-        icount_warp_rt();
-        timer_del(icount_warp_timer);
-    }
     if (!all_cpu_threads_idle()) {
         return;
     }
 
     if (qtest_enabled()) {
         /* When testing, qtest commands advance icount.  */
-	return;
+        return;
     }
 
     /* We want to use the earliest deadline from ALL vm_clocks */
@@ -496,6 +480,31 @@ void qemu_clock_warp(QEMUClockType type)
     }
 }
 
+void qemu_account_warp_timer(void)
+{
+    int64_t clock;
+    int64_t warp_delta;
+
+    if (!use_icount || !icount_sleep) {
+        return;
+    }
+
+    /* Nothing to do if the VM is stopped: QEMU_CLOCK_VIRTUAL timers
+     * do not fire, so computing the deadline does not make sense.
+     */
+    if (!runstate_is_running()) {
+        return;
+    }
+
+    /* warp clock deterministically in record/replay mode */
+    if (!replay_checkpoint(CHECKPOINT_CLOCK_WARP_ACCOUNT)) {
+        return;
+    }
+
+    timer_del(icount_warp_timer);
+    icount_warp_rt();
+}
+
 static bool icount_state_needed(void *opaque)
 {
     return use_icount;
@@ -1496,7 +1505,7 @@ static void tcg_exec_all(void)
     int r;
 
     /* Account partial waits to QEMU_CLOCK_VIRTUAL.  */
-    qemu_clock_warp(QEMU_CLOCK_VIRTUAL);
+    qemu_account_warp_timer();
 
     if (next_cpu == NULL) {
         next_cpu = first_cpu;
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index d0946cb..21ffec6 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -210,12 +210,18 @@ void qemu_clock_notify(QEMUClockType type);
 void qemu_clock_enable(QEMUClockType type, bool enabled);
 
 /**
- * qemu_clock_warp:
- * @type: the clock type
+ * qemu_start_warp_timer:
+ *
+ * Starts a timer for virtual clock update
+ */
+void qemu_start_warp_timer(void);
+
+/**
+ * qemu_account_warp_timer:
  *
- * Warp a clock to a new value
+ * Updates virtual clock for the time CPU was sleeping
  */
-void qemu_clock_warp(QEMUClockType type);
+void qemu_account_warp_timer(void);
 
 /**
  * qemu_clock_register_reset_notifier:
diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h
index 4763e56..6c332e5 100644
--- a/include/sysemu/replay.h
+++ b/include/sysemu/replay.h
@@ -27,7 +27,8 @@ typedef enum ReplayClockKind ReplayClockKind;
 
 /* IDs of the checkpoints */
 enum ReplayCheckpoint {
-    CHECKPOINT_CLOCK_WARP,
+    CHECKPOINT_CLOCK_WARP_START,
+    CHECKPOINT_CLOCK_WARP_ACCOUNT,
     CHECKPOINT_RESET_REQUESTED,
     CHECKPOINT_SUSPEND_REQUESTED,
     CHECKPOINT_CLOCK_VIRTUAL,
diff --git a/main-loop.c b/main-loop.c
index 19beae7..3a7f4cd 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -509,7 +509,7 @@ int main_loop_wait(int nonblocking)
 
     /* CPU thread can infinitely wait for event after
        missing the warp */
-    qemu_clock_warp(QEMU_CLOCK_VIRTUAL);
+    qemu_start_warp_timer();
     qemu_clock_run_all_timers();
 
     return ret;
diff --git a/qemu-timer.c b/qemu-timer.c
index e98ecc9..4441fe6 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -394,7 +394,9 @@ static bool timer_mod_ns_locked(QEMUTimerList *timer_list,
 static void timerlist_rearm(QEMUTimerList *timer_list)
 {
     /* Interrupt execution to force deadline recalculation.  */
-    qemu_clock_warp(timer_list->clock->type);
+    if (timer_list->clock->type == QEMU_CLOCK_VIRTUAL) {
+        qemu_start_warp_timer();
+    }
     timerlist_notify(timer_list);
 }
 
diff --git a/stubs/clock-warp.c b/stubs/clock-warp.c
index 5ae32b9..8acb58a 100644
--- a/stubs/clock-warp.c
+++ b/stubs/clock-warp.c
@@ -2,7 +2,7 @@
 #include "qemu-common.h"
 #include "qemu/timer.h"
 
-void qemu_clock_warp(QEMUClockType type)
+void qemu_start_warp_timer(void)
 {
 }
 
