Problem
After live migration, the guest monotonic clock may jump forward on the target.

Cause
kvmclock (the guest’s time base) is derived from host wall time and keeps
advancing while the VM is paused. During STOP_COPY, QEMU reads kvmclock twice:
1) immediately after the VM is paused, and
2) when final CPU state is collected.
Only the second (later) value is migrated. The gap between the two reads is
roughly the downtime, so the target restores from a later time and the guest
monotonic clock jumps ahead.

Fix
Migrate the kvmclock value captured at pause time (the first read) so the target
restores from the actual pause point.

Signed-off-by: Peng Ju Zhou <[email protected]>
---
 hw/i386/kvm/clock.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c
index 40aa9a32c3..cd6f7e1315 100644
--- a/hw/i386/kvm/clock.c
+++ b/hw/i386/kvm/clock.c
@@ -43,6 +43,7 @@ struct KVMClockState {
 
     /* whether the 'clock' value was obtained in the 'paused' state */
     bool runstate_paused;
+    RunState state;
 
     /* whether machine type supports reliable KVM_GET_CLOCK */
     bool mach_use_reliable_get_clock;
@@ -108,7 +109,10 @@ static void kvm_update_clock(KVMClockState *s)
         fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(-ret));
                 abort();
     }
-    s->clock = data.clock;
+
+    if (s->state != RUN_STATE_FINISH_MIGRATE) {
+        s->clock = data.clock;
+    }
 
     /* If kvm_has_adjust_clock_stable() is false, KVM_GET_CLOCK returns
      * essentially CLOCK_MONOTONIC plus a guest-specific adjustment.  This
@@ -217,6 +221,8 @@ static void kvmclock_vm_state_change(void *opaque, bool 
running,
          */
         s->clock_valid = true;
     }
+
+    s->state = state;
 }
 
 static void kvmclock_realize(DeviceState *dev, Error **errp)
-- 
2.33.1


Reply via email to