[PATCH v10 20/21] KVM: x86: Use kernel timekeeping snapshot for monotonic clock

From: Sean Christopherson

Date: Wed Aug 26 2026 - 17:39:46 EST


Replace the KVM-private vgettsc()+/do_monotonic() timekeeping
reimplementation with calls to the recently crafted, generic
ktime_get_snapshot_id() interface. As noted previously, the snapshot
provides both the system time and the raw_cycles (TSC), atomically paired
using a sequence counter.

Signed-off-by: David Woodhouse <dwmw@xxxxxxxxxxxx>
[sean: separate from other conversions]
Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>
---
arch/x86/kvm/x86.c | 33 ++++++---------------------------
1 file changed, 6 insertions(+), 27 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 32390b20a2b4..0352bd147c40 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1438,29 +1438,6 @@ static inline u64 vgettsc(struct pvclock_clock *clock, u64 *tsc_timestamp,
return v * clock->mult;
}

-/*
- * This calculates CLOCK_MONOTONIC at the time of the TSC snapshot, with
- * no boot time offset.
- */
-static int do_monotonic(s64 *t, u64 *tsc_timestamp)
-{
- struct pvclock_gtod_data *gtod = &pvclock_gtod_data;
- unsigned long seq;
- int mode;
- u64 ns;
-
- do {
- seq = read_seqcount_begin(&gtod->seq);
- ns = gtod->clock.base_cycles;
- ns += vgettsc(&gtod->clock, tsc_timestamp, &mode);
- ns >>= gtod->clock.shift;
- ns += ktime_to_ns(gtod->clock.offset);
- } while (unlikely(read_seqcount_retry(&gtod->seq, seq)));
- *t = ns;
-
- return mode;
-}
-
static int do_realtime(struct timespec64 *ts, u64 *tsc_timestamp)
{
struct pvclock_gtod_data *gtod = &pvclock_gtod_data;
@@ -1528,12 +1505,14 @@ static bool kvm_get_time_and_clockread(s64 *kernel_ns, u64 *tsc_timestamp)
*/
bool kvm_get_monotonic_and_clockread(s64 *kernel_ns, u64 *tsc_timestamp)
{
- /* checked again under seqlock below */
- if (!gtod_is_based_on_tsc(pvclock_gtod_data.clock.vclock_mode))
+ struct system_time_snapshot snap = {};
+
+ ktime_get_snapshot_id(CLOCK_MONOTONIC, &snap);
+ if (!kvm_snapshot_has_tsc(&snap, tsc_timestamp))
return false;

- return gtod_is_based_on_tsc(do_monotonic(kernel_ns,
- tsc_timestamp));
+ *kernel_ns = ktime_to_ns(snap.systime);
+ return true;
}

/*
--
2.55.0.887.g758fc8c411-goog