From: David Woodhouse Implement the read_raw() callback for the kvmclock clocksource. This returns the kvmclock nanosecond value (for timekeeping) while also providing the raw TSC value that was used to compute it. The TSC is read inside the pvclock seqlock-protected region, ensuring the raw TSC and derived kvmclock value are atomically paired. This enables ktime_get_snapshot_id() to provide the raw TSC to consumers like the vmclock PTP driver, which currently has to do a separate call to get_cycles() to obtain the value to feed through the vmclock calculation. Signed-off-by: David Woodhouse Assisted-by: Kiro:claude-opus-4.6-1m --- arch/x86/kernel/kvmclock.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index 74aca22dc726..ef86635433f9 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c @@ -87,6 +87,25 @@ static u64 kvm_clock_get_cycles(struct clocksource *cs) return kvm_clock_read(); } +static u64 kvm_clock_get_cycles_raw(struct clocksource *cs, u64 *raw) +{ + struct pvclock_vcpu_time_info *src; + unsigned version; + u64 ret, tsc; + + preempt_disable_notrace(); + src = this_cpu_pvti(); + do { + version = pvclock_read_begin(src); + tsc = rdtsc_ordered(); + ret = __pvclock_read_cycles(src, tsc); + } while (pvclock_read_retry(src, version)); + preempt_enable_notrace(); + + *raw = tsc; + return ret; +} + static noinstr u64 kvm_sched_clock_read(void) { return pvclock_clocksource_read_nowd(this_cpu_pvti()) - kvm_sched_clock_offset; @@ -163,6 +182,8 @@ static int kvm_cs_enable(struct clocksource *cs) static struct clocksource kvm_clock = { .name = "kvm-clock", .read = kvm_clock_get_cycles, + .read_raw = kvm_clock_get_cycles_raw, + .raw_csid = CSID_X86_TSC, .rating = 400, .mask = CLOCKSOURCE_MASK(64), .flags = CLOCK_SOURCE_IS_CONTINUOUS, -- 2.54.0