The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH] clocksource: stop monitoring TSC in VMs
@ 2026-07-15 12:59 Maksim Davydov
  2026-07-21 19:35 ` Sean Christopherson
  0 siblings, 1 reply; 2+ messages in thread
From: Maksim Davydov @ 2026-07-15 12:59 UTC (permalink / raw)
  To: linux-kernel; +Cc: davydov-max, tglx, mingo, peterz, bp, dave.hansen, x86, hpa

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@yandex-team.ru>
---
 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();
 
 	clocksource_register_khz(&clocksource_tsc_early, tsc_khz);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] clocksource: stop monitoring TSC in VMs
  2026-07-15 12:59 [PATCH] clocksource: stop monitoring TSC in VMs Maksim Davydov
@ 2026-07-21 19:35 ` Sean Christopherson
  0 siblings, 0 replies; 2+ messages in thread
From: Sean Christopherson @ 2026-07-21 19:35 UTC (permalink / raw)
  To: Maksim Davydov
  Cc: linux-kernel, tglx, mingo, peterz, bp, dave.hansen, x86, hpa

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@yandex-team.ru>
> ---
>  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@google.com

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

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-07-21 19:35 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-15 12:59 [PATCH] clocksource: stop monitoring TSC in VMs Maksim Davydov
2026-07-21 19:35 ` Sean Christopherson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox