[PATCH 0/3] vdso: Keep the CLOCK_AUX base at full precision
From: Zhan Xusheng
Date: Mon Aug 31 2026 - 08:59:03 EST
Thomas confirmed the CLOCK_AUX base precision loss was unintentional and
asked for the fix in this shape:
https://lore.kernel.org/all/20260831102924-5f7570f6-7dc4-4996-9a35-db9c9f577dd2@xxxxxxxxxxxxx
1/3 adds __iter_div64_u64_rem() instead of open-coding the iterative
division a third time, and converts the two existing sites.
2/3 is the fix. Adding the offset in scaled nanoseconds needs the
normalisation to happen against NSEC_PER_SEC << shift in the tick, so that
the stored base stays below one second and the userspace fast-path does not
iterate more.
3/3 is independent and can be dropped on its own. The assert is on a
parameter, so it depends on the compiler deriving the range from the
vdso_clockid_valid() bail-out; gcc 13 and clang 18 both manage it, and it
does fire once MAX_AUX_CLOCKS goes past the limit, so it is not vacuous.
Checked under QEMU with an auxiliary clock enabled through
/sys/kernel/time/aux_clocks/0/aux_clock_enable, comparing CLOCK_AUX via
the vDSO against the raw syscall at offset 0, at +5.123456789 s, and with
offs_aux driven negative. The two agree within read latency in all three,
and over 100000 interleaved pairs each the vDSO reading is never ahead of
a syscall reading taken after it.
The 1 ns bias itself is not measurable that way: a pair of reads costs
several hundred nanoseconds, so it cannot be separated from read latency.
The argument for it is the algebra in 2/3, plus a sweep over
(xtime_nsec, delta) which puts the 1 ns case at 60% for shift 24.
Zhan Xusheng (3):
vdso/math64: Add and use __iter_div64_u64_rem()
vdso/vsyscall: Keep the CLOCK_AUX base scaled
vdso/gettimeofday: Assert that the clock id fits the dispatch mask
include/vdso/math64.h | 21 +++++++++++++++++++++
kernel/time/vsyscall.c | 28 ++++++++++++----------------
lib/vdso/gettimeofday.c | 2 ++
3 files changed, 35 insertions(+), 16 deletions(-)
base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
--
2.43.0