Re: [PATCH] clocksource: stop monitoring TSC in VMs

From: Sean Christopherson

Date: Tue Jul 21 2026 - 15:44:26 EST


On Wed, Jul 15, 2026, Maksim Davydov wrote:
> It seems that in a virtual machine hardware clocks shouldn't be monitored
> by software (paravirtualized or emulated) clocks because they have
> different behaviour. For example, a VM can be live-migrated to another
> host or it can be paused. Both of them can cause false positive marking of
> TSC as unstable:
>
> w/ kvm-clock:
> clocksource: Marking clocksource tsc unstable due to frequency skew
> clocksource: Watchdog kvm-clock interval: 301338133ns
> clocksource: Clocksource tsc interval: 620070548ns
> tsc: Marking TSC unstable due to clocksource watchdog
> clocksource: Switched to clocksource kvm-clock
>
> w/o kvm-clock:
> clocksource: Marking clocksource tsc unstable due to frequency skew
> clocksource: Watchdog hpet interval: 248411930ns
> clocksource: Clocksource tsc interval: 480045119ns
> tsc: Marking TSC unstable due to clocksource watchdog
> TSC found unstable after boot, most likely due to broken BIOS. Use 'tsc=unstable'.
> sched_clock: Marking unstable (302400491443, 145482655)<-(302687230264, -141256934)
> clocksource: Switched to clocksource hpet
>
> Both examples were created in the VM with invariant TSC, but without
> TSC_ADJUST MSR in order to fail check in check_system_tsc_reliable(). So,
> it is stable enough to be the best clocksource but not reliable enough
> to be without a watchdog.
>
> The reason why TSC can be marked as unstable is the different way of
> saving and restoring state of clocks. In virtualized environment TSC is a
> "hardware" clock that QEMU doesn't stop during VM pause. On the other hand,
> QEMU stops hpet and kvm-clock. So live-migration to paused state (e.g. in
> order to hot-plug some devices) or short stop+cont can cause divergence
> of TSC and any other "software" clocks. (The point to have the same
> behaviour for all clocks will be discussed later in qemu-devel.)
>
> Nevertheless, it is important to point out, kvm_clock_read() used to touch
> watchdog and that prevents false positive marking TSC as unstable,
> because a hypervisor usually notifies a VM about clocks interference and
> a guest OS usually checks the appropriate flags. This behaviour was changed
> in 8739c6811572. But still, this issue has also existed (and now exists)
> with other clocks.
>
> Thus, it seems that the clocksource watchdog has to be disabled for TSC
> in VMs unless the opposite is explicitly requested by `tsc=watchdog`.
> "Hardware" stable TSC is more realible than "software" clocks that
> usually use host's TSC inside.
>
> Fixes: 8739c6811572 ("sched/clock/x86: Mark sched_clock() noinstr")
> Signed-off-by: Maksim Davydov <davydov-max@xxxxxxxxxxxxxx>
> ---
> arch/x86/kernel/tsc.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
> index ce10ae4b298b..11b24f0c19bd 100644
> --- a/arch/x86/kernel/tsc.c
> +++ b/arch/x86/kernel/tsc.c
> @@ -1553,7 +1553,8 @@ void __init tsc_init(void)
> return;
> }
>
> - if (tsc_clocksource_reliable || tsc_watchdog == TSC_WATCHDOG_OFF)
> + if (tsc_clocksource_reliable || tsc_watchdog == TSC_WATCHDOG_OFF ||
> + boot_cpu_has(X86_FEATURE_HYPERVISOR))
> tsc_disable_clocksource_watchdog();

I've been working on fixing this issue, along with a whole pile of other TSC-related
virtualization issues, for ~1.5 years (yikes!). I'm hoping to land the series
"soon', ideally in 7.3. Any testing/review you can provide that series would be
much appreciated!

https://lore.kernel.org/all/20260701193212.749551-23-seanjc@xxxxxxxxxx

>
> clocksource_register_khz(&clocksource_tsc_early, tsc_khz);
> --
> 2.34.1
>