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.
Unified · Split
| @@ -140,6 +140,10 @@ static int vmclock_get_crosststamp(struct vmclock_state *st, · 139 unmodified lines | |||
| 140 | if (sts->pre_sts.cs_id == st->cs_id) { | 140 | if (sts->pre_sts.cs_id == st->cs_id) { |
| 141 | cycle = sts->pre_sts.cycles; | 141 | cycle = sts->pre_sts.cycles; |
| 142 | sts->post_sts = sts->pre_sts; | 142 | sts->post_sts = sts->pre_sts; |
| 143 | } else if (sts->pre_sts.hw_csid == st->cs_id && | ||
| 144 | sts->pre_sts.hw_cycles) { | ||
| 145 | cycle = sts->pre_sts.hw_cycles; | ||
| 146 | sts->post_sts = sts->pre_sts; | ||
| 143 | } else { | 147 | } else { |
| 144 | cycle = get_cycles(); | 148 | cycle = get_cycles(); |
| 145 | ptp_read_system_postts(sts); | 149 | ptp_read_system_postts(sts); |