about summary refs log tree commit diff
path: root/arch/arm
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2022-09-12 08:38:03 -0400
committerRich Felker <dalias@aerifal.cx>2022-09-19 13:21:54 -0400
commitbf14ef193b4203aa9a8b173faeeea06d98397f65 (patch)
tree350a72f59d6afe649814bb65106c2e51c49ce0b5 /arch/arm
parent6f3ead0ae16deb9f0004b275e29a276c9712ee3c (diff)
downloadmusl-bf14ef193b4203aa9a8b173faeeea06d98397f65.tar.gz
musl-bf14ef193b4203aa9a8b173faeeea06d98397f65.tar.xz
musl-bf14ef193b4203aa9a8b173faeeea06d98397f65.zip
re-enable vdso clock_gettime on arm (32-bit) with workaround
commit 4486c579cbf0d989080705f515d08cb48636ba88 disabled vdso
clock_gettime on arm due to a Linux kernel bug that was not understood
at the time, whereby the vdso function silently produced
catastrophically wrong results on some systems.

since then, the bug was tracked down to the way the arm kernel
disabled use of vdso clock_gettime on kernels where the necessary
timer was not available or was disabled. it simply patched out the
symbols, but it only did this for the legacy time32 functions, and
left the time64 function in place but non-operational. kernel commit
4405bdf3c57ec28d606bdf5325f1167505bfdcd4 (first present in 5.8)
provided the fix.

if this were a bug that impacted all users of the broken kernel
versions, we could probably ignore it and assume it had been patched
or replaced. however, it's very possible that these kernels appear in
the wild in devices running time32 userspace (glibc, musl 1.1.x, or
some other environment) where they appear to work fine, but where our
new binaries would fail catastrophically if we used the time64 vdso
function.

since the kernel has not (yet?) given us a way to probe for the
working time64 vdso function semantically, we work around the problem
by refusing to use the time64 one unless the time32 one is also
present. this will revert to not using vdso at all if the time32 one
is ever removed, but at least that's safe against wrong results and is
just a missed optimization.
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/syscall_arch.h7
1 files changed, 7 insertions, 0 deletions
diff --git a/arch/arm/syscall_arch.h b/arch/arm/syscall_arch.h
index a877b2cf..624e992e 100644
--- a/arch/arm/syscall_arch.h
+++ b/arch/arm/syscall_arch.h
@@ -101,3 +101,10 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo
 #define SYSCALL_FADVISE_6_ARG
 
 #define SYSCALL_IPC_BROKEN_MODE
+
+#define VDSO_USEFUL
+#define VDSO_CGT32_SYM "__vdso_clock_gettime"
+#define VDSO_CGT32_VER "LINUX_2.6"
+#define VDSO_CGT_SYM "__vdso_clock_gettime64"
+#define VDSO_CGT_VER "LINUX_2.6"
+#define VDSO_CGT_WORKAROUND 1