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

tip-bot2 for David Woodhouse posted 1 patch 2 days, 15 hours ago
drivers/ptp/ptp_vmclock.c | 4 ++++
1 file changed, 4 insertions(+)
[tip: timers/ptp] ptp: vmclock: Use hw_cycles from snapshot for precise TSC pairing
Posted by tip-bot2 for David Woodhouse 2 days, 15 hours ago
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@amazon.co.uk>
AuthorDate:    Thu, 04 Jun 2026 10:35:18 +01:00
Committer:     Thomas Gleixner <tglx@kernel.org>
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@amazon.co.uk>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Assisted-by: Kiro:claude-opus-4.6-1m
Link: https://patch.msgid.link/20260604095755.64849-4-dwmw2@infradead.org
---
 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);