mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 0/8] selftests: vDSO: Stop using libc types for vDSO calls
@ 2026-09-03  7:38 Thomas Weißschuh
  2026-09-03  7:38 ` [PATCH v2 1/8] selftests: vDSO: Introduce vdso_types.h Thomas Weißschuh
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Thomas Weißschuh @ 2026-09-03  7:38 UTC (permalink / raw)
  To: Andy Lutomirski, Vincenzo Frascino, Shuah Khan, Thomas Gleixner
  Cc: Arnd Bergmann, linux-kernel, linux-kselftest, Thomas Weißschuh

Currently the vDSO selftests use the time-related types from libc.
This works on glibc by chance today but will break with other libc
implementations or on distributions which switch to 64-bit times
everywhere.

The kernel's UAPI headers provide the proper types to use with the vDSO
(and raw syscalls) but are not necessarily compatible with libc types.
Introduce a new header which makes the UAPI headers compatible with the
libc.

Also contains some related cleanups.

Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
Changes in v2:
- Rebase on v7.13-rc1.
- Use __kernel_old_time_t in vdso_time_t.
- Add vdso_syscalls.h.
- Add a test for the time() function.
- Use __NR_* over SYS_* syscall constants.
- Drop already applied patches.
- Link to v1: https://lore.kernel.org/r/20251111-vdso-test-types-v1-0-03b31f88c659@linutronix.de

---
Thomas Weißschuh (8):
      selftests: vDSO: Introduce vdso_types.h
      selftests: vDSO: Introduce vdso_syscalls.h
      selftests: vDSO: vdso_test_abi: Use types from vdso_types.h
      selftests: vDSO: vdso_test_abi: Use system call wrappers from vdso_syscalls.h
      selftests: vDSO: vdso_test_gettimeofday: Use types from vdso_types.h
      selftests: vDSO: vdso_test_correctness: Make ts_leq() and tv_leq() more generic
      selftests: vDSO: vdso_test_correctness: Use types from vdso_types.h
      selftests: vDSO: vdso_test_correctness: Use system call wrappers from vdso_syscalls.h

 tools/testing/selftests/vDSO/vdso_syscalls.h       |  92 +++++++++++++++
 tools/testing/selftests/vDSO/vdso_test_abi.c       |  40 +++----
 .../testing/selftests/vDSO/vdso_test_correctness.c | 126 +++++++--------------
 .../selftests/vDSO/vdso_test_gettimeofday.c        |   7 +-
 tools/testing/selftests/vDSO/vdso_types.h          |  75 ++++++++++++
 5 files changed, 225 insertions(+), 115 deletions(-)
---
base-commit: 058d40ae995fbcdd8342ef875c4e94df6b93a8b4
change-id: 20251110-vdso-test-types-68ce0c712b79

Best regards,
--  
Thomas Weißschuh <thomas.weissschuh@linutronix.de>


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

* [PATCH v2 1/8] selftests: vDSO: Introduce vdso_types.h
  2026-09-03  7:38 [PATCH v2 0/8] selftests: vDSO: Stop using libc types for vDSO calls Thomas Weißschuh
@ 2026-09-03  7:38 ` Thomas Weißschuh
  2026-09-03  7:38 ` [PATCH v2 2/8] selftests: vDSO: Introduce vdso_syscalls.h Thomas Weißschuh
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Thomas Weißschuh @ 2026-09-03  7:38 UTC (permalink / raw)
  To: Andy Lutomirski, Vincenzo Frascino, Shuah Khan, Thomas Gleixner
  Cc: Arnd Bergmann, linux-kernel, linux-kselftest, Thomas Weißschuh

Currently the vDSO selftests use the time-related types from libc.
This works on glibc by chance today but will break with other libc
implementations or on distributions which switch to 64-bit times
everywhere.

The kernel's UAPI headers provide the proper types to use with the vDSO
(and raw syscalls) but are not necessarily compatible with libc types.
Introduce a new header which makes the UAPI headers compatible with the
libc.

Tested with glibc, musl and nolibc.

Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
 tools/testing/selftests/vDSO/vdso_types.h | 75 +++++++++++++++++++++++++++++++
 1 file changed, 75 insertions(+)

diff --git a/tools/testing/selftests/vDSO/vdso_types.h b/tools/testing/selftests/vDSO/vdso_types.h
new file mode 100644
index 000000000000..4cb564f3fa94
--- /dev/null
+++ b/tools/testing/selftests/vDSO/vdso_types.h
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2025 Thomas Weißschuh <thomas.weissschuh@linutronix.de>, Linutronix GmbH
+ *
+ * Types to use with vDSO functions.
+ *
+ * The types used by the vDSO functions do not necessarily match the ones used
+ * by libc. The kernel's UAPI headers do provide definitions for those types
+ * but are often not compatible with libc which applications need to use.
+ * As the types differ between platforms listing them manually is a lot of work
+ * and error prone. Instead hack around the incompatibilities of the libc and
+ * UAPI headers and use the UAPI types.
+ */
+#ifndef __VDSO_TYPES_H__
+#define __VDSO_TYPES_H__
+
+/*
+ * Include the headers from libc first to not override any of its types later.
+ */
+#include <time.h>
+#include <sys/time.h>
+
+/*
+ * Avoid collisions.
+ */
+#define timeval kernel_timeval_moved
+#define itimerspec kernel_itimerspec_moved
+#define itimerval kernel_itimerval_moved
+#define timezone kernel_timezone_moved
+
+#ifndef _STRUCT_TIMESPEC
+#define _STRUCT_TIMESPEC
+#endif
+
+/*
+ * Get the UAPI types.
+ */
+#include <linux/time.h>
+
+#undef timeval
+#undef itimerspec
+#undef itimerval
+#undef timezone
+
+/*
+ * The UAPI headers do not provide their own 'struct __kernel_timezone'.
+ * 'struct timezone' is the one from libc.
+ */
+struct kernel_timezone {
+	int	tz_minuteswest;
+	int	tz_dsttime;
+};
+
+#include <linux/version.h>
+
+/*
+ * UAPI headers from the libc may be older and not provide these.
+ */
+#if KERNEL_VERSION(5, 5, 0) > LINUX_VERSION_CODE
+typedef __kernel_long_t		__kernel_old_time_t;
+
+struct __kernel_old_timespec {
+	__kernel_old_time_t	tv_sec;
+	__kernel_long_t		tv_nsec;
+};
+#endif
+
+typedef long (*vdso_gettimeofday_t)(struct __kernel_old_timeval *tv, struct kernel_timezone *tz);
+typedef long (*vdso_clock_gettime_t)(__kernel_clockid_t clk_id, struct __kernel_old_timespec *ts);
+typedef long (*vdso_clock_gettime64_t)(__kernel_clockid_t clk_id, struct __kernel_timespec *ts);
+typedef long (*vdso_clock_getres_t)(__kernel_clockid_t clk_id, struct __kernel_old_timespec *ts);
+typedef long (*vdso_clock_getres_time64_t)(__kernel_clockid_t clk_id, struct __kernel_timespec *ts);
+typedef __kernel_old_time_t (*vdso_time_t)(__kernel_old_time_t *t);
+
+#endif /* __VDSO_TYPES_H__ */

-- 
2.55.0


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

* [PATCH v2 2/8] selftests: vDSO: Introduce vdso_syscalls.h
  2026-09-03  7:38 [PATCH v2 0/8] selftests: vDSO: Stop using libc types for vDSO calls Thomas Weißschuh
  2026-09-03  7:38 ` [PATCH v2 1/8] selftests: vDSO: Introduce vdso_types.h Thomas Weißschuh
@ 2026-09-03  7:38 ` Thomas Weißschuh
  2026-09-03  7:38 ` [PATCH v2 3/8] selftests: vDSO: vdso_test_abi: Use types from vdso_types.h Thomas Weißschuh
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Thomas Weißschuh @ 2026-09-03  7:38 UTC (permalink / raw)
  To: Andy Lutomirski, Vincenzo Frascino, Shuah Khan, Thomas Gleixner
  Cc: Arnd Bergmann, linux-kernel, linux-kselftest, Thomas Weißschuh

The vDSO selftests use raw system call wrapper to validate the
correctness of the vDSO implementation. The exactly available system
calls differ between architectures and kernel configurations.
Raw system calls should not use libc types as these are not necessarily
compatible.

Introduce a helper header which uses the correct types and fallbacks.

Link: https://lore.kernel.org/lkml/29dd9e11-9ae8-415a-acb3-b96af56550b0@app.fastmail.com/
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
 tools/testing/selftests/vDSO/vdso_syscalls.h | 92 ++++++++++++++++++++++++++++
 1 file changed, 92 insertions(+)

diff --git a/tools/testing/selftests/vDSO/vdso_syscalls.h b/tools/testing/selftests/vDSO/vdso_syscalls.h
new file mode 100644
index 000000000000..d4ed95b50eb5
--- /dev/null
+++ b/tools/testing/selftests/vDSO/vdso_syscalls.h
@@ -0,0 +1,92 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2025 Thomas Weißschuh <thomas.weissschuh@linutronix.de>, Linutronix GmbH
+ *
+ * System call wrappers to use for vDSO testing.
+ *
+ * vDSO calls are expected to return the same data as the equivalent system call.
+ * To ensure this the tests need to trigger system calls. Calling into libc may
+ * silently use the vDSO, so explicit system calls are necessary.
+ * Not all system calls are available on all platforms, so some fallback logic
+ * is needed. Use __NR_ constants from the kernel's UAPI headers over SYS_ from
+ * ones from libc to avoid any potential interference from libc.
+ * Always prefer the 64-bit time variants of the system calls as 32-bit ones
+ * may not be present on the platform or disabled in the kernel configuration.
+ * No fallback to the 32-bit ones is necessary, as the vDSO function
+ * availability always mirrors the system call one.
+ */
+#ifndef __VDSO_SYSCALLS_H__
+#define __VDSO_SYSCALLS_H__
+
+#include "vdso_types.h"
+
+#include <stddef.h>
+#include <sys/syscall.h>
+#include <linux/unistd.h>
+
+#define typeof_member(T, m)	typeof(((T *)0)->m)
+#define sizeof_member(T, m)	sizeof(typeof_member(T, m))
+
+/*
+ * To keep the fallback logic simple we assume that, although the types between
+ * the wrapper and the system call are different, they are compatible.
+ * Validate that assumption.
+ */
+#define ASSERT_MEMBER_COMPATIBLE(T1, T2, m)						\
+	do {										\
+		_Static_assert(sizeof_member(T1, m) == sizeof_member(T2, m), "");	\
+		_Static_assert(offsetof(T1, m) == offsetof(T2, m), "");			\
+	} while (0)
+
+#define ASSERT_TIMESPEC_COMPATIBLE(ts1, ts2)					\
+	do {									\
+		_Static_assert(sizeof(ts1) == sizeof(ts2), "");			\
+		ASSERT_MEMBER_COMPATIBLE(typeof(ts1), typeof(ts2), tv_sec);	\
+		ASSERT_MEMBER_COMPATIBLE(typeof(ts1), typeof(ts2), tv_nsec);	\
+	} while (0)
+
+static inline
+int sys_clock_getres(__kernel_clockid_t clock, struct __kernel_timespec *ts)
+{
+#ifdef __NR_clock_getres_time64
+	return syscall(__NR_clock_getres_time64, clock, ts);
+#else
+	ASSERT_TIMESPEC_COMPATIBLE(*ts, struct __kernel_old_timespec);
+	return syscall(__NR_clock_getres, clock, ts);
+#endif
+}
+
+static inline
+int sys_clock_gettime(__kernel_clockid_t clock, struct __kernel_timespec *ts)
+{
+#ifdef __NR_clock_gettime64
+	return syscall(__NR_clock_gettime64, clock, ts);
+#else
+	ASSERT_TIMESPEC_COMPATIBLE(*ts, struct __kernel_old_timespec);
+	return syscall(__NR_clock_gettime, clock, ts);
+#endif
+}
+
+static inline
+int sys_gettimeofday(struct __kernel_old_timeval *tv, struct kernel_timezone *tz)
+{
+#ifdef __NR_gettimeofday
+	return syscall(__NR_gettimeofday, tv, tz);
+#else
+	errno = ENOSYS;
+	return -1;
+#endif
+}
+
+static inline
+__kernel_old_time_t sys_time(__kernel_old_time_t *tloc)
+{
+#ifdef __NR_time
+	return syscall(__NR_time, tloc);
+#else
+	errno = ENOSYS;
+	return -1;
+#endif
+}
+
+#endif /* __VDSO_SYSCALLS_H__ */

-- 
2.55.0


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

* [PATCH v2 3/8] selftests: vDSO: vdso_test_abi: Use types from vdso_types.h
  2026-09-03  7:38 [PATCH v2 0/8] selftests: vDSO: Stop using libc types for vDSO calls Thomas Weißschuh
  2026-09-03  7:38 ` [PATCH v2 1/8] selftests: vDSO: Introduce vdso_types.h Thomas Weißschuh
  2026-09-03  7:38 ` [PATCH v2 2/8] selftests: vDSO: Introduce vdso_syscalls.h Thomas Weißschuh
@ 2026-09-03  7:38 ` Thomas Weißschuh
  2026-09-03  7:38 ` [PATCH v2 4/8] selftests: vDSO: vdso_test_abi: Use system call wrappers from vdso_syscalls.h Thomas Weißschuh
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Thomas Weißschuh @ 2026-09-03  7:38 UTC (permalink / raw)
  To: Andy Lutomirski, Vincenzo Frascino, Shuah Khan, Thomas Gleixner
  Cc: Arnd Bergmann, linux-kernel, linux-kselftest, Thomas Weißschuh

The libc types are not necessarily compatible with the vDSO functions.

Use the dedicated types from vdso_types.h instead.

Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
 tools/testing/selftests/vDSO/vdso_test_abi.c | 35 +++++++++-------------------
 1 file changed, 11 insertions(+), 24 deletions(-)

diff --git a/tools/testing/selftests/vDSO/vdso_test_abi.c b/tools/testing/selftests/vDSO/vdso_test_abi.c
index b162a4ba9c4f..b7590a727f06 100644
--- a/tools/testing/selftests/vDSO/vdso_test_abi.c
+++ b/tools/testing/selftests/vDSO/vdso_test_abi.c
@@ -11,9 +11,7 @@
 #include <stdint.h>
 #include <elf.h>
 #include <stdio.h>
-#include <time.h>
 #include <sys/auxv.h>
-#include <sys/time.h>
 #define _GNU_SOURCE
 #include <unistd.h>
 #include <sys/syscall.h>
@@ -21,24 +19,12 @@
 #include "kselftest.h"
 #include "vdso_config.h"
 #include "vdso_call.h"
+#include "vdso_types.h"
 #include "parse_vdso.h"
 
 static const char *version;
 static const char **name;
 
-/* The same as struct __kernel_timespec */
-struct vdso_timespec64 {
-	uint64_t tv_sec;
-	uint64_t tv_nsec;
-};
-
-typedef long (*vdso_gettimeofday_t)(struct timeval *tv, struct timezone *tz);
-typedef long (*vdso_clock_gettime_t)(clockid_t clk_id, struct timespec *ts);
-typedef long (*vdso_clock_gettime64_t)(clockid_t clk_id, struct vdso_timespec64 *ts);
-typedef long (*vdso_clock_getres_t)(clockid_t clk_id, struct timespec *ts);
-typedef long (*vdso_clock_getres_time64_t)(clockid_t clk_id, struct vdso_timespec64 *ts);
-typedef time_t (*vdso_time_t)(time_t *t);
-
 static const char * const vdso_clock_name[] = {
 	[CLOCK_REALTIME]		= "CLOCK_REALTIME",
 	[CLOCK_MONOTONIC]		= "CLOCK_MONOTONIC",
@@ -66,7 +52,7 @@ static void vdso_test_gettimeofday(void)
 		return;
 	}
 
-	struct timeval tv;
+	struct __kernel_old_timeval tv;
 	long ret = VDSO_CALL(vdso_gettimeofday, 2, &tv, 0);
 
 	if (ret == 0) {
@@ -78,7 +64,7 @@ static void vdso_test_gettimeofday(void)
 	}
 }
 
-static void vdso_test_clock_gettime64(clockid_t clk_id)
+static void vdso_test_clock_gettime64(__kernel_clockid_t clk_id)
 {
 	/* Find clock_gettime64. */
 	vdso_clock_gettime64_t vdso_clock_gettime64 =
@@ -91,7 +77,7 @@ static void vdso_test_clock_gettime64(clockid_t clk_id)
 		return;
 	}
 
-	struct vdso_timespec64 ts;
+	struct __kernel_timespec ts;
 	long ret = VDSO_CALL(vdso_clock_gettime64, 2, clk_id, &ts);
 
 	if (ret == 0) {
@@ -105,7 +91,7 @@ static void vdso_test_clock_gettime64(clockid_t clk_id)
 	}
 }
 
-static void vdso_test_clock_gettime(clockid_t clk_id)
+static void vdso_test_clock_gettime(__kernel_clockid_t clk_id)
 {
 	/* Find clock_gettime. */
 	vdso_clock_gettime_t vdso_clock_gettime =
@@ -118,7 +104,7 @@ static void vdso_test_clock_gettime(clockid_t clk_id)
 		return;
 	}
 
-	struct timespec ts;
+	struct __kernel_old_timespec ts;
 	long ret = VDSO_CALL(vdso_clock_gettime, 2, clk_id, &ts);
 
 	if (ret == 0) {
@@ -155,7 +141,7 @@ static void vdso_test_time(void)
 	}
 }
 
-static void vdso_test_clock_getres(clockid_t clk_id)
+static void vdso_test_clock_getres(__kernel_clockid_t clk_id)
 {
 	int clock_getres_fail = 0;
 
@@ -170,7 +156,8 @@ static void vdso_test_clock_getres(clockid_t clk_id)
 		return;
 	}
 
-	struct timespec ts, sys_ts;
+	struct __kernel_old_timespec ts;
+	struct timespec sys_ts;
 	long ret = VDSO_CALL(vdso_clock_getres, 2, clk_id, &ts);
 
 	if (ret == 0) {
@@ -213,7 +200,7 @@ static void vdso_test_clock_getres_time64(clockid_t clk_id)
 		return;
 	}
 
-	struct vdso_timespec64 ts, sys_ts;
+	struct __kernel_timespec ts, sys_ts;
 	long ret = VDSO_CALL(vdso_clock_getres_time64, 2, clk_id, &ts);
 
 	if (ret == 0) {
@@ -250,7 +237,7 @@ static void vdso_test_clock_getres_time64(clockid_t clk_id)
  * This function calls vdso_test_clock_gettime and vdso_test_clock_getres
  * with different values for clock_id.
  */
-static inline void vdso_test_clock(clockid_t clock_id)
+static inline void vdso_test_clock(__kernel_clockid_t clock_id)
 {
 	ksft_print_msg("clock_id: %s\n", vdso_clock_name[clock_id]);
 

-- 
2.55.0


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

* [PATCH v2 4/8] selftests: vDSO: vdso_test_abi: Use system call wrappers from vdso_syscalls.h
  2026-09-03  7:38 [PATCH v2 0/8] selftests: vDSO: Stop using libc types for vDSO calls Thomas Weißschuh
                   ` (2 preceding siblings ...)
  2026-09-03  7:38 ` [PATCH v2 3/8] selftests: vDSO: vdso_test_abi: Use types from vdso_types.h Thomas Weißschuh
@ 2026-09-03  7:38 ` Thomas Weißschuh
  2026-09-03  7:38 ` [PATCH v2 5/8] selftests: vDSO: vdso_test_gettimeofday: Use types from vdso_types.h Thomas Weißschuh
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Thomas Weißschuh @ 2026-09-03  7:38 UTC (permalink / raw)
  To: Andy Lutomirski, Vincenzo Frascino, Shuah Khan, Thomas Gleixner
  Cc: Arnd Bergmann, linux-kernel, linux-kselftest, Thomas Weißschuh

Using syscall(SYS_getcpu) is problematic for the reasons outlined in
vdso_syscalls.h.

Use the wrappers from the utility header instead.

Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
 tools/testing/selftests/vDSO/vdso_test_abi.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/vDSO/vdso_test_abi.c b/tools/testing/selftests/vDSO/vdso_test_abi.c
index b7590a727f06..4f63582f4e65 100644
--- a/tools/testing/selftests/vDSO/vdso_test_abi.c
+++ b/tools/testing/selftests/vDSO/vdso_test_abi.c
@@ -19,6 +19,7 @@
 #include "kselftest.h"
 #include "vdso_config.h"
 #include "vdso_call.h"
+#include "vdso_syscalls.h"
 #include "vdso_types.h"
 #include "parse_vdso.h"
 
@@ -157,7 +158,7 @@ static void vdso_test_clock_getres(__kernel_clockid_t clk_id)
 	}
 
 	struct __kernel_old_timespec ts;
-	struct timespec sys_ts;
+	struct __kernel_timespec sys_ts;
 	long ret = VDSO_CALL(vdso_clock_getres, 2, clk_id, &ts);
 
 	if (ret == 0) {
@@ -167,7 +168,7 @@ static void vdso_test_clock_getres(__kernel_clockid_t clk_id)
 		clock_getres_fail++;
 	}
 
-	ret = syscall(__NR_clock_getres, clk_id, &sys_ts);
+	ret = sys_clock_getres(clk_id, &sys_ts);
 
 	ksft_print_msg("The syscall resolution is %lld %lld\n",
 			(long long)sys_ts.tv_sec, (long long)sys_ts.tv_nsec);
@@ -210,7 +211,7 @@ static void vdso_test_clock_getres_time64(clockid_t clk_id)
 		clock_getres_fail++;
 	}
 
-	ret = syscall(__NR_clock_getres_time64, clk_id, &sys_ts);
+	ret = sys_clock_getres(clk_id, &sys_ts);
 
 	ksft_print_msg("The syscall resolution is %lld %lld\n",
 			(long long)sys_ts.tv_sec, (long long)sys_ts.tv_nsec);

-- 
2.55.0


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

* [PATCH v2 5/8] selftests: vDSO: vdso_test_gettimeofday: Use types from vdso_types.h
  2026-09-03  7:38 [PATCH v2 0/8] selftests: vDSO: Stop using libc types for vDSO calls Thomas Weißschuh
                   ` (3 preceding siblings ...)
  2026-09-03  7:38 ` [PATCH v2 4/8] selftests: vDSO: vdso_test_abi: Use system call wrappers from vdso_syscalls.h Thomas Weißschuh
@ 2026-09-03  7:38 ` Thomas Weißschuh
  2026-09-03  7:38 ` [PATCH v2 6/8] selftests: vDSO: vdso_test_correctness: Make ts_leq() and tv_leq() more generic Thomas Weißschuh
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Thomas Weißschuh @ 2026-09-03  7:38 UTC (permalink / raw)
  To: Andy Lutomirski, Vincenzo Frascino, Shuah Khan, Thomas Gleixner
  Cc: Arnd Bergmann, linux-kernel, linux-kselftest, Thomas Weißschuh

The libc types are not necessarily compatible with the vDSO functions.

Use the dedicated types from vdso_types.h instead.

Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
 tools/testing/selftests/vDSO/vdso_test_gettimeofday.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/vDSO/vdso_test_gettimeofday.c b/tools/testing/selftests/vDSO/vdso_test_gettimeofday.c
index 990b29e0e272..2119a6429835 100644
--- a/tools/testing/selftests/vDSO/vdso_test_gettimeofday.c
+++ b/tools/testing/selftests/vDSO/vdso_test_gettimeofday.c
@@ -12,12 +12,12 @@
 
 #include <stdio.h>
 #include <sys/auxv.h>
-#include <sys/time.h>
 
 #include "kselftest.h"
 #include "parse_vdso.h"
 #include "vdso_config.h"
 #include "vdso_call.h"
+#include "vdso_types.h"
 
 int main(int argc, char **argv)
 {
@@ -33,15 +33,14 @@ int main(int argc, char **argv)
 	vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR));
 
 	/* Find gettimeofday. */
-	typedef long (*gtod_t)(struct timeval *tv, struct timezone *tz);
-	gtod_t gtod = (gtod_t)vdso_sym(version, name[0]);
+	vdso_gettimeofday_t gtod = (vdso_gettimeofday_t)vdso_sym(version, name[0]);
 
 	if (!gtod) {
 		printf("Could not find %s\n", name[0]);
 		return KSFT_SKIP;
 	}
 
-	struct timeval tv;
+	struct __kernel_old_timeval tv;
 	long ret = VDSO_CALL(gtod, 2, &tv, 0);
 
 	if (ret == 0) {

-- 
2.55.0


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

* [PATCH v2 6/8] selftests: vDSO: vdso_test_correctness: Make ts_leq() and tv_leq() more generic
  2026-09-03  7:38 [PATCH v2 0/8] selftests: vDSO: Stop using libc types for vDSO calls Thomas Weißschuh
                   ` (4 preceding siblings ...)
  2026-09-03  7:38 ` [PATCH v2 5/8] selftests: vDSO: vdso_test_gettimeofday: Use types from vdso_types.h Thomas Weißschuh
@ 2026-09-03  7:38 ` Thomas Weißschuh
  2026-09-03  7:38 ` [PATCH v2 7/8] selftests: vDSO: vdso_test_correctness: Use types from vdso_types.h Thomas Weißschuh
  2026-09-03  7:38 ` [PATCH v2 8/8] selftests: vDSO: vdso_test_correctness: Use system call wrappers from vdso_syscalls.h Thomas Weißschuh
  7 siblings, 0 replies; 9+ messages in thread
From: Thomas Weißschuh @ 2026-09-03  7:38 UTC (permalink / raw)
  To: Andy Lutomirski, Vincenzo Frascino, Shuah Khan, Thomas Gleixner
  Cc: Arnd Bergmann, linux-kernel, linux-kselftest, Thomas Weißschuh

Upcoming changes will shuffle around the timespec and timeval types.
To keep ts_leq() and tv_leq() working with all of those types, transform
them into macros.

Also drop ts64_leq() as it can now be replaced by the regular ts_leq().

Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
 .../testing/selftests/vDSO/vdso_test_correctness.c | 47 ++++++++++------------
 1 file changed, 22 insertions(+), 25 deletions(-)

diff --git a/tools/testing/selftests/vDSO/vdso_test_correctness.c b/tools/testing/selftests/vDSO/vdso_test_correctness.c
index 5c5a07dd1128..537e0030aa16 100644
--- a/tools/testing/selftests/vDSO/vdso_test_correctness.c
+++ b/tools/testing/selftests/vDSO/vdso_test_correctness.c
@@ -226,30 +226,27 @@ static void test_getcpu(void)
 	}
 }
 
-static bool ts_leq(const struct timespec *a, const struct timespec *b)
-{
-	if (a->tv_sec != b->tv_sec)
-		return a->tv_sec < b->tv_sec;
-	else
-		return a->tv_nsec <= b->tv_nsec;
-}
-
-static bool ts64_leq(const struct __kernel_timespec *a,
-		     const struct __kernel_timespec *b)
-{
-	if (a->tv_sec != b->tv_sec)
-		return a->tv_sec < b->tv_sec;
-	else
-		return a->tv_nsec <= b->tv_nsec;
-}
-
-static bool tv_leq(const struct timeval *a, const struct timeval *b)
-{
-	if (a->tv_sec != b->tv_sec)
-		return a->tv_sec < b->tv_sec;
-	else
-		return a->tv_usec <= b->tv_usec;
-}
+#define ts_leq(_a, _b)	({				\
+	bool _ret;					\
+							\
+	if ((_a)->tv_sec != (_b)->tv_sec)		\
+		_ret = (_a)->tv_sec < (_b)->tv_sec;	\
+	else						\
+		_ret = (_a)->tv_nsec <= (_b)->tv_nsec;	\
+							\
+	_ret;						\
+})
+
+#define tv_leq(_a, _b)	({				\
+	bool _ret;					\
+							\
+	if ((_a)->tv_sec != (_b)->tv_sec)		\
+		_ret = (_a)->tv_sec < (_b)->tv_sec;	\
+	else						\
+		_ret = (_a)->tv_usec <= (_b)->tv_usec;	\
+							\
+	_ret;						\
+})
 
 static char const * const clocknames[] = {
 	[0] = "CLOCK_REALTIME",
@@ -365,7 +362,7 @@ static void test_one_clock_gettime64(int clock, const char *name)
 	       (unsigned long long)vdso.tv_sec, vdso.tv_nsec,
 	       (unsigned long long)end.tv_sec, end.tv_nsec);
 
-	if (!ts64_leq(&start, &vdso) || !ts64_leq(&vdso, &end)) {
+	if (!ts_leq(&start, &vdso) || !ts_leq(&vdso, &end)) {
 		printf("[FAIL]\tTimes are out of sequence\n");
 		nerrs++;
 		return;

-- 
2.55.0


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

* [PATCH v2 7/8] selftests: vDSO: vdso_test_correctness: Use types from vdso_types.h
  2026-09-03  7:38 [PATCH v2 0/8] selftests: vDSO: Stop using libc types for vDSO calls Thomas Weißschuh
                   ` (5 preceding siblings ...)
  2026-09-03  7:38 ` [PATCH v2 6/8] selftests: vDSO: vdso_test_correctness: Make ts_leq() and tv_leq() more generic Thomas Weißschuh
@ 2026-09-03  7:38 ` Thomas Weißschuh
  2026-09-03  7:38 ` [PATCH v2 8/8] selftests: vDSO: vdso_test_correctness: Use system call wrappers from vdso_syscalls.h Thomas Weißschuh
  7 siblings, 0 replies; 9+ messages in thread
From: Thomas Weißschuh @ 2026-09-03  7:38 UTC (permalink / raw)
  To: Andy Lutomirski, Vincenzo Frascino, Shuah Khan, Thomas Gleixner
  Cc: Arnd Bergmann, linux-kernel, linux-kselftest, Thomas Weißschuh

The libc types are not necessarily compatible with the vDSO functions.

Use the dedicated types from vdso_types.h instead.

Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
 .../testing/selftests/vDSO/vdso_test_correctness.c | 45 ++++++++--------------
 1 file changed, 15 insertions(+), 30 deletions(-)

diff --git a/tools/testing/selftests/vDSO/vdso_test_correctness.c b/tools/testing/selftests/vDSO/vdso_test_correctness.c
index 537e0030aa16..83cb408c5947 100644
--- a/tools/testing/selftests/vDSO/vdso_test_correctness.c
+++ b/tools/testing/selftests/vDSO/vdso_test_correctness.c
@@ -7,7 +7,6 @@
 #define _GNU_SOURCE
 
 #include <stdio.h>
-#include <sys/time.h>
 #include <time.h>
 #include <stdlib.h>
 #include <unistd.h>
@@ -22,6 +21,7 @@
 #include "parse_vdso.h"
 #include "vdso_config.h"
 #include "vdso_call.h"
+#include "vdso_types.h"
 #include "kselftest.h"
 
 static const char *version;
@@ -31,33 +31,15 @@ static const char **name;
 #define __NR_clock_gettime64	403
 #endif
 
-#ifndef __kernel_timespec
-struct __kernel_timespec {
-	long long	tv_sec;
-	long long	tv_nsec;
-};
-#endif
-
 /* max length of lines in /proc/self/maps - anything longer is skipped here */
 #define MAPS_LINE_LEN 128
 
 int nerrs = 0;
 
-typedef int (*vgettime_t)(clockid_t, struct timespec *);
-
-vgettime_t vdso_clock_gettime;
-
-typedef int (*vgettime64_t)(clockid_t, struct __kernel_timespec *);
-
-vgettime64_t vdso_clock_gettime64;
-
-typedef long (*vgtod_t)(struct timeval *tv, struct timezone *tz);
-
-vgtod_t vdso_gettimeofday;
-
-typedef time_t (*vtime_t)(__kernel_time_t *tloc);
-
-vtime_t vdso_time;
+vdso_clock_gettime_t vdso_clock_gettime;
+vdso_clock_gettime64_t vdso_clock_gettime64;
+vdso_gettimeofday_t vdso_gettimeofday;
+vdso_time_t vdso_time;
 
 typedef long (*getcpu_t)(unsigned *, unsigned *, void *);
 
@@ -123,21 +105,21 @@ static void fill_function_pointers(void)
 
 	vgetcpu = (getcpu_t) vsyscall_getcpu();
 
-	vdso_clock_gettime = (vgettime_t)vdso_sym(version, name[1]);
+	vdso_clock_gettime = (vdso_clock_gettime_t)vdso_sym(version, name[1]);
 	if (!vdso_clock_gettime)
 		printf("Warning: failed to find clock_gettime in vDSO\n");
 
 #if defined(VDSO_32BIT)
-	vdso_clock_gettime64 = (vgettime64_t)vdso_sym(version, name[5]);
+	vdso_clock_gettime64 = (vdso_clock_gettime64_t)vdso_sym(version, name[5]);
 	if (!vdso_clock_gettime64)
 		printf("Warning: failed to find clock_gettime64 in vDSO\n");
 #endif
 
-	vdso_gettimeofday = (vgtod_t)vdso_sym(version, name[0]);
+	vdso_gettimeofday = (vdso_gettimeofday_t)vdso_sym(version, name[0]);
 	if (!vdso_gettimeofday)
 		printf("Warning: failed to find gettimeofday in vDSO\n");
 
-	vdso_time = (vtime_t)vdso_sym(version, name[2]);
+	vdso_time = (vdso_time_t)vdso_sym(version, name[2]);
 	if (!vdso_time)
 		printf("Warning: failed to find time in vDSO\n");
 
@@ -265,7 +247,8 @@ static char const * const clocknames[] = {
 
 static void test_one_clock_gettime(int clock, const char *name)
 {
-	struct timespec start, vdso, end;
+	struct __kernel_old_timespec vdso;
+	struct timespec start, end;
 	int vdso_ret, end_ret;
 
 	printf("[RUN]\tTesting clock_gettime for clock %s (%d)...\n", name, clock);
@@ -389,8 +372,10 @@ static void test_clock_gettime64(void)
 
 static void test_gettimeofday(void)
 {
-	struct timeval start, vdso, end;
-	struct timezone sys_tz, vdso_tz;
+	struct __kernel_old_timeval vdso;
+	struct kernel_timezone vdso_tz;
+	struct timeval start, end;
+	struct timezone sys_tz;
 	int vdso_ret, end_ret;
 
 	if (!vdso_gettimeofday)

-- 
2.55.0


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

* [PATCH v2 8/8] selftests: vDSO: vdso_test_correctness: Use system call wrappers from vdso_syscalls.h
  2026-09-03  7:38 [PATCH v2 0/8] selftests: vDSO: Stop using libc types for vDSO calls Thomas Weißschuh
                   ` (6 preceding siblings ...)
  2026-09-03  7:38 ` [PATCH v2 7/8] selftests: vDSO: vdso_test_correctness: Use types from vdso_types.h Thomas Weißschuh
@ 2026-09-03  7:38 ` Thomas Weißschuh
  7 siblings, 0 replies; 9+ messages in thread
From: Thomas Weißschuh @ 2026-09-03  7:38 UTC (permalink / raw)
  To: Andy Lutomirski, Vincenzo Frascino, Shuah Khan, Thomas Gleixner
  Cc: Arnd Bergmann, linux-kernel, linux-kselftest, Thomas Weißschuh

Using syscall() is problematic for the reasons outlined in vdso_syscalls.h.

Use the wrappers from the utility header instead.

Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
 .../testing/selftests/vDSO/vdso_test_correctness.c | 44 +++++-----------------
 1 file changed, 9 insertions(+), 35 deletions(-)

diff --git a/tools/testing/selftests/vDSO/vdso_test_correctness.c b/tools/testing/selftests/vDSO/vdso_test_correctness.c
index 83cb408c5947..76133566d747 100644
--- a/tools/testing/selftests/vDSO/vdso_test_correctness.c
+++ b/tools/testing/selftests/vDSO/vdso_test_correctness.c
@@ -21,6 +21,7 @@
 #include "parse_vdso.h"
 #include "vdso_config.h"
 #include "vdso_call.h"
+#include "vdso_syscalls.h"
 #include "vdso_types.h"
 #include "kselftest.h"
 
@@ -131,31 +132,6 @@ static long sys_getcpu(unsigned * cpu, unsigned * node,
 	return syscall(__NR_getcpu, cpu, node, cache);
 }
 
-static inline int sys_clock_gettime(clockid_t id, struct timespec *ts)
-{
-	return syscall(__NR_clock_gettime, id, ts);
-}
-
-static inline int sys_clock_gettime64(clockid_t id, struct __kernel_timespec *ts)
-{
-	return syscall(__NR_clock_gettime64, id, ts);
-}
-
-static inline int sys_gettimeofday(struct timeval *tv, struct timezone *tz)
-{
-	return syscall(__NR_gettimeofday, tv, tz);
-}
-
-static inline __kernel_old_time_t sys_time(__kernel_old_time_t *tloc)
-{
-#ifdef __NR_time
-	return syscall(__NR_time, tloc);
-#else
-	errno = ENOSYS;
-	return -1;
-#endif
-}
-
 static void test_getcpu(void)
 {
 	printf("[RUN]\tTesting getcpu...\n");
@@ -247,8 +223,8 @@ static char const * const clocknames[] = {
 
 static void test_one_clock_gettime(int clock, const char *name)
 {
+	struct __kernel_timespec start, end;
 	struct __kernel_old_timespec vdso;
-	struct timespec start, end;
 	int vdso_ret, end_ret;
 
 	printf("[RUN]\tTesting clock_gettime for clock %s (%d)...\n", name, clock);
@@ -279,9 +255,9 @@ static void test_one_clock_gettime(int clock, const char *name)
 	}
 
 	printf("\t%llu.%09ld %llu.%09ld %llu.%09ld\n",
-	       (unsigned long long)start.tv_sec, start.tv_nsec,
-	       (unsigned long long)vdso.tv_sec, vdso.tv_nsec,
-	       (unsigned long long)end.tv_sec, end.tv_nsec);
+	       (unsigned long long)start.tv_sec, (unsigned long)start.tv_nsec,
+	       (unsigned long long)vdso.tv_sec, (unsigned long)vdso.tv_nsec,
+	       (unsigned long long)end.tv_sec, (unsigned long)end.tv_nsec);
 
 	if (!ts_leq(&start, &vdso) || !ts_leq(&vdso, &end)) {
 		printf("[FAIL]\tTimes are out of sequence\n");
@@ -315,7 +291,7 @@ static void test_one_clock_gettime64(int clock, const char *name)
 
 	printf("[RUN]\tTesting clock_gettime64 for clock %s (%d)...\n", name, clock);
 
-	if (sys_clock_gettime64(clock, &start) < 0) {
+	if (sys_clock_gettime(clock, &start) < 0) {
 		if (errno == EINVAL) {
 			vdso_ret = VDSO_CALL(vdso_clock_gettime64, 2, clock, &vdso);
 			if (vdso_ret == -EINVAL) {
@@ -331,7 +307,7 @@ static void test_one_clock_gettime64(int clock, const char *name)
 	}
 
 	vdso_ret = VDSO_CALL(vdso_clock_gettime64, 2, clock, &vdso);
-	end_ret = sys_clock_gettime64(clock, &end);
+	end_ret = sys_clock_gettime(clock, &end);
 
 	if (vdso_ret != 0 || end_ret != 0) {
 		printf("[FAIL]\tvDSO returned %d, syscall errno=%d\n",
@@ -372,10 +348,8 @@ static void test_clock_gettime64(void)
 
 static void test_gettimeofday(void)
 {
-	struct __kernel_old_timeval vdso;
-	struct kernel_timezone vdso_tz;
-	struct timeval start, end;
-	struct timezone sys_tz;
+	struct __kernel_old_timeval start, vdso, end;
+	struct kernel_timezone vdso_tz, sys_tz;
 	int vdso_ret, end_ret;
 
 	if (!vdso_gettimeofday)

-- 
2.55.0


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

end of thread, other threads:[~2026-09-03  7:38 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-03  7:38 [PATCH v2 0/8] selftests: vDSO: Stop using libc types for vDSO calls Thomas Weißschuh
2026-09-03  7:38 ` [PATCH v2 1/8] selftests: vDSO: Introduce vdso_types.h Thomas Weißschuh
2026-09-03  7:38 ` [PATCH v2 2/8] selftests: vDSO: Introduce vdso_syscalls.h Thomas Weißschuh
2026-09-03  7:38 ` [PATCH v2 3/8] selftests: vDSO: vdso_test_abi: Use types from vdso_types.h Thomas Weißschuh
2026-09-03  7:38 ` [PATCH v2 4/8] selftests: vDSO: vdso_test_abi: Use system call wrappers from vdso_syscalls.h Thomas Weißschuh
2026-09-03  7:38 ` [PATCH v2 5/8] selftests: vDSO: vdso_test_gettimeofday: Use types from vdso_types.h Thomas Weißschuh
2026-09-03  7:38 ` [PATCH v2 6/8] selftests: vDSO: vdso_test_correctness: Make ts_leq() and tv_leq() more generic Thomas Weißschuh
2026-09-03  7:38 ` [PATCH v2 7/8] selftests: vDSO: vdso_test_correctness: Use types from vdso_types.h Thomas Weißschuh
2026-09-03  7:38 ` [PATCH v2 8/8] selftests: vDSO: vdso_test_correctness: Use system call wrappers from vdso_syscalls.h Thomas Weißschuh

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

all inboxes | Powered by JetHome®