From ad909a3d71c6f7db0bd664b3808477a618d331c2 Mon Sep 17 00:00:00 2001 From: Atish Patra Date: Thu, 11 Jun 2026 15:03:46 -0700 Subject: [PATCH] vmm: drive guest clock save/restore through the vm abstraction Currently, VM pause/resume/snapshot paths invoke architecture specific bits for guest clock udpates which ideally belongs to hypervisor layer. Route it through the snapshot_clock()/restore_clock() pair added in the previous commit instead, so the VMM no longer depends on an architecture specific clock API and the upcoming aarch64 backend can hook the same path without a parallel branch in vm.rs. Signed-off-by: Atish Patra --- vmm/src/vm.rs | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index d17b92b71..fc2468d58 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -529,7 +529,7 @@ pub struct Vm { // The hypervisor abstracted virtual machine. vm: Arc, #[cfg(target_arch = "x86_64")] - saved_clock: Option, + saved_clock: Option, #[cfg(not(target_arch = "riscv64"))] numa_nodes: NumaNodes, #[cfg_attr(any(not(feature = "kvm"), target_arch = "aarch64"), allow(dead_code))] @@ -3216,14 +3216,10 @@ impl Pausable for Vm { #[cfg(target_arch = "x86_64")] { - let mut clock = self + self.saved_clock = self .vm - .get_clock() - .map_err(|e| MigratableError::Pause(anyhow!("Could not get VM clock: {e}")))?; - if !clock.has_realtime() { - clock.set_realtime(std::time::SystemTime::now()); - } - self.saved_clock = Some(clock); + .snapshot_clock() + .map_err(|e| MigratableError::Pause(anyhow!("Could not capture guest clock: {e}")))?; } // Before pausing the vCPUs activate any pending virtio devices that might @@ -3254,14 +3250,14 @@ impl Pausable for Vm { .valid_transition(new_state) .map_err(|e| MigratableError::Resume(anyhow!("Invalid transition: {e:?}")))?; - // Restore KVM clock BEFORE vCPUs start running, so they see correct - // TSC/kvmclock from the first instruction after resume. + // Restore the guest clock BEFORE the vCPUs start running, so they see the + // corrected time from the first instruction after resume. #[cfg(target_arch = "x86_64")] { - if let Some(clock) = &self.saved_clock { - self.vm - .set_clock(clock) - .map_err(|e| MigratableError::Resume(anyhow!("Could not set VM clock: {e}")))?; + if let Some(state) = &self.saved_clock { + self.vm.restore_clock(state).map_err(|e| { + MigratableError::Resume(anyhow!("Could not restore guest clock: {e}")) + })?; } } @@ -3284,7 +3280,7 @@ impl Pausable for Vm { #[derive(Serialize, Deserialize)] pub struct VmSnapshot { #[cfg(target_arch = "x86_64")] - pub clock: Option, + pub clock: Option, #[cfg(all(feature = "kvm", target_arch = "x86_64"))] pub common_cpuid: Vec, }