This patch modifies vmstate for PL031 RTC. It removes querying of the rtc and virtual clocks while saving and restoring VM state, because in replay mode these clocks are stopped while saving. And reading the clock while restoring the VM state may lead to read of the incorrect values, because clocks cache in replay module could not be loaded yet.
Signed-off-by: Pavel Dovgalyuk <pavel.dovga...@ispras.ru> --- hw/timer/pl031.c | 22 +++++++++++++++------- 1 files changed, 15 insertions(+), 7 deletions(-) diff --git a/hw/timer/pl031.c b/hw/timer/pl031.c index 02c814f..017b1ce 100644 --- a/hw/timer/pl031.c +++ b/hw/timer/pl031.c @@ -220,19 +220,27 @@ static void pl031_pre_save(void *opaque) { PL031State *s = opaque; - /* tick_offset is base_time - rtc_clock base time. Instead, we want to - * store the base time relative to the QEMU_CLOCK_VIRTUAL for backwards-compatibility. */ - int64_t delta = qemu_clock_get_ns(rtc_clock) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - s->tick_offset_vmstate = s->tick_offset + delta / get_ticks_per_sec(); + if (replay_mode == REPLAY_NONE) { + /* tick_offset is base_time - rtc_clock base time. Instead, we want to + * store the base time relative to the QEMU_CLOCK_VIRTUAL for backwards-compatibility. */ + int64_t delta = qemu_clock_get_ns(rtc_clock) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + s->tick_offset_vmstate = s->tick_offset + delta / get_ticks_per_sec(); + } else { + s->tick_offset_vmstate = s->tick_offset; + } } static int pl031_post_load(void *opaque, int version_id) { PL031State *s = opaque; - int64_t delta = qemu_clock_get_ns(rtc_clock) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - s->tick_offset = s->tick_offset_vmstate - delta / get_ticks_per_sec(); - pl031_set_alarm(s); + if (replay_mode == REPLAY_NONE) { + int64_t delta = qemu_clock_get_ns(rtc_clock) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + s->tick_offset = s->tick_offset_vmstate - delta / get_ticks_per_sec(); + pl031_set_alarm(s); + } else { + s->tick_offset = s->tick_offset_vmstate; + } return 0; }