[tip: timers/ptp] ptp: vmclock: Use hw_cycles from snapshot for precise TSC pairing

From: tip-bot2 for David Woodhouse

Date: Fri Jun 05 2026 - 08:31:04 EST


The following commit has been merged into the timers/ptp branch of tip:

Commit-ID: bc484a5096732cd858771cccd3164ec985bdc03d
Gitweb: https://git.kernel.org/tip/bc484a5096732cd858771cccd3164ec985bdc03d
Author: David Woodhouse <dwmw@xxxxxxxxxxxx>
AuthorDate: Thu, 04 Jun 2026 10:35:18 +01:00
Committer: Thomas Gleixner <tglx@xxxxxxxxxx>
CommitterDate: Fri, 05 Jun 2026 14:25:03 +02:00

ptp: vmclock: Use hw_cycles from snapshot for precise TSC pairing

When the system clocksource is kvmclock or Hyper-V (not the TSC directly),
vmclock_get_crosststamp() falls through to a separate get_cycles() call,
losing the atomic pairing between the system time snapshot and the TSC
reading.

Now that ktime_get_snapshot_id() populates hw_cycles with the underlying
TSC value for derived clocksources, use it when available. This gives a
perfect (system_time, tsc) pairing for the device time calculation.

The SUPPORT_KVMCLOCK wrapper is still needed to convert the TSC into
kvmclock nanoseconds for system_counter->cycles, because otherwise
get_device_system_crosststamp() can't interpret the result against the
system clock.

Signed-off-by: David Woodhouse <dwmw@xxxxxxxxxxxx>
Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxx>
Assisted-by: Kiro:claude-opus-4.6-1m
Link: https://patch.msgid.link/20260604095755.64849-4-dwmw2@xxxxxxxxxxxxx
---
drivers/ptp/ptp_vmclock.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/ptp/ptp_vmclock.c b/drivers/ptp/ptp_vmclock.c
index d6a5a53..eebdcd5 100644
--- a/drivers/ptp/ptp_vmclock.c
+++ b/drivers/ptp/ptp_vmclock.c
@@ -140,6 +140,10 @@ static int vmclock_get_crosststamp(struct vmclock_state *st,
if (sts->pre_sts.cs_id == st->cs_id) {
cycle = sts->pre_sts.cycles;
sts->post_sts = sts->pre_sts;
+ } else if (sts->pre_sts.hw_csid == st->cs_id &&
+ sts->pre_sts.hw_cycles) {
+ cycle = sts->pre_sts.hw_cycles;
+ sts->post_sts = sts->pre_sts;
} else {
cycle = get_cycles();
ptp_read_system_postts(sts);