@@ -343,7 +343,7 @@ int cpu_exec(CPUArchState *env)
what we have to do is sleep until it is 0. As for the
advance/delay we gain here, we try to fix it next time. */
diff_clk = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
- qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
+ qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + clocks_offset;
original_instr_counter = cpu->icount_extra + cpu->icount_decr.u16.low;
}
#endif
@@ -62,6 +62,7 @@
#endif /* CONFIG_LINUX */
static CPUState *next_cpu;
+int64_t clocks_offset = -1;
bool cpu_is_stopped(CPUState *cpu)
{
@@ -336,6 +337,16 @@ static void icount_warp_rt(void *opaque)
warp_delta = MIN(warp_delta, delta);
}
qemu_icount_bias += warp_delta;
+ /* On x86 target architecture, the PIT reset function (called
+ by qemu_system_reset) will end up calling qemu_clock_warp
+ and then icount_warp_rt changing vm_clock_warp_start from 0 (initial
+ value) to -1. This in turn will make us skip the initial offset
+ between the real and virtual clocks (initially virtual clock is 0).
+ Therefore we save it in clocks_offset. On ARM, we don't have this
+ problem and clocks_offset will be 0. */
+ if (clocks_offset == -1 && icount_align_option) {
+ clocks_offset = vm_clock_warp_start;
+ }
}
vm_clock_warp_start = -1;
seqlock_write_unlock(&timers_state.vm_clock_seqlock);
@@ -110,6 +110,7 @@ void configure_icount(QemuOpts *opts, Error **errp);
extern int use_icount;
extern int icount_time_shift;
extern int icount_align_option;
+extern int64_t clocks_offset;
#include "qemu/osdep.h"
#include "qemu/bswap.h"