[tip: timers/core] x86/tsc: Handle CLOCK_SOURCE_VALID_FOR_HRES correctly
From: tip-bot2 for Thomas Gleixner
Date: Thu Mar 12 2026 - 07:26:58 EST
The following commit has been merged into the timers/core branch of tip:
Commit-ID: 79ccb0693a99e1b91eba95c6bd32a3e02be156ae
Gitweb: https://git.kernel.org/tip/79ccb0693a99e1b91eba95c6bd32a3e02be156ae
Author: Thomas Gleixner <tglx@xxxxxxxxxx>
AuthorDate: Sat, 24 Jan 2026 00:17:55 +01:00
Committer: Thomas Gleixner <tglx@xxxxxxxxxx>
CommitterDate: Thu, 12 Mar 2026 12:23:27 +01:00
x86/tsc: Handle CLOCK_SOURCE_VALID_FOR_HRES correctly
Unconditionally setting the CLOCK_SOURCE_VALID_FOR_HRES for the real TSC
clocksource is wrong as there is no guarantee that the early TSC was
validated for high resolution mode.
Set the flag only when the early TSC was validated as otherwise the
clocksource selection might enable high resolution mode with a TSC of
unknown quality and possibly no way to back out once it is discovered to be
unsuitable.
Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxx>
Link: https://patch.msgid.link/20260123231521.790598171@xxxxxxxxxx
---
arch/x86/kernel/tsc.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index f31046f..9ccd58c 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -1200,7 +1200,6 @@ static struct clocksource clocksource_tsc = {
.read = read_tsc,
.mask = CLOCKSOURCE_MASK(64),
.flags = CLOCK_SOURCE_IS_CONTINUOUS |
- CLOCK_SOURCE_VALID_FOR_HRES |
CLOCK_SOURCE_CAN_INLINE_READ |
CLOCK_SOURCE_MUST_VERIFY |
CLOCK_SOURCE_VERIFY_PERCPU |
@@ -1411,6 +1410,15 @@ out:
have_art = true;
clocksource_tsc.base = &art_base_clk;
}
+
+ /*
+ * Transfer the valid for high resolution flag if it was set on the
+ * early TSC already. That guarantees that there is no intermediate
+ * clocksource selected once the early TSC is unregistered.
+ */
+ if (clocksource_tsc_early.flags & CLOCK_SOURCE_VALID_FOR_HRES)
+ clocksource_tsc.flags |= CLOCK_SOURCE_VALID_FOR_HRES;
+
clocksource_register_khz(&clocksource_tsc, tsc_khz);
unreg:
clocksource_unregister(&clocksource_tsc_early);