From 3576902fd657940446d0bfbd2819aeec933a28fe Mon Sep 17 00:00:00 2001
From: Anders Roxell <anders.roxell@linaro.org>
Date: Fri, 7 Nov 2025 13:56:28 +0100
Subject: [PATCH 3/5] selftests: vdso: Add libc wrapper tests for time
 interfaces

Add tests for libc time interface wrappers to complement the existing
direct vDSO tests. This ensures both the kernel vDSO implementation and
the libc wrappers that applications actually use are tested.

New test functions:
- libc_test_clock_gettime(): Tests standard clock_gettime() using libc's
  struct timespec. This is the interface most applications use.

- libc_test_clock_gettime64(): Tests the 64-bit time interface via
  __NR_clock_gettime64 syscall with struct __kernel_timespec. This is
  critical for y2038 safety on 32-bit systems. Gracefully skips if the
  syscall is not available.

Both functions are called for each clock type tested (CLOCK_REALTIME,
CLOCK_MONOTONIC, etc.), providing coverage of:
- Kernel vDSO (32-bit time_t)
- Kernel vDSO (64-bit time_t)
- libc wrapper (standard timespec)
- libc wrapper (64-bit time_t)

This increases test coverage, ensuring both kernel and userspace time
interfaces work correctly on 32-bit and 64-bit ARM architectures.

Signed-off-by: Anders Roxell <anders.roxell@linaro.org>
---
 tools/testing/selftests/vDSO/vdso_test_abi.c | 46 +++++++++++++++++++-
 1 file changed, 45 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/vDSO/vdso_test_abi.c b/tools/testing/selftests/vDSO/vdso_test_abi.c
index c620317eaeea..819e0593f955 100644
--- a/tools/testing/selftests/vDSO/vdso_test_abi.c
+++ b/tools/testing/selftests/vDSO/vdso_test_abi.c
@@ -196,6 +196,45 @@ static void vdso_test_clock_getres(clockid_t clk_id)
 	}
 }
 
+/* Test libc wrappers for clock_gettime */
+static void libc_test_clock_gettime(clockid_t clk_id)
+{
+	struct timespec ts;
+	int ret = clock_gettime(clk_id, &ts);
+
+	if (ret == 0) {
+		ksft_print_msg("libc clock_gettime: %ld.%09ld\n",
+			       (long)ts.tv_sec, (long)ts.tv_nsec);
+		ksft_test_result_pass("libc_clock_gettime %s\n",
+				      vdso_clock_name[clk_id]);
+	} else {
+		ksft_test_result_fail("libc_clock_gettime %s\n",
+				      vdso_clock_name[clk_id]);
+	}
+}
+
+/* Test libc wrappers for clock_gettime64 (if available) */
+static void libc_test_clock_gettime64(clockid_t clk_id)
+{
+#ifdef __NR_clock_gettime64
+	struct __kernel_timespec ts;
+	int ret = syscall(__NR_clock_gettime64, clk_id, &ts);
+
+	if (ret == 0) {
+		ksft_print_msg("libc clock_gettime64: %lld.%09lld\n",
+			       (long long)ts.tv_sec, (long long)ts.tv_nsec);
+		ksft_test_result_pass("libc_clock_gettime64 %s\n",
+				      vdso_clock_name[clk_id]);
+	} else {
+		ksft_test_result_skip("libc_clock_gettime64 %s (errno=%d)\n",
+				      vdso_clock_name[clk_id], errno);
+	}
+#else
+	ksft_test_result_skip("libc_clock_gettime64 %s (not available)\n",
+			      vdso_clock_name[clk_id]);
+#endif
+}
+
 /*
  * This function calls vdso_test_clock_gettime and vdso_test_clock_getres
  * with different values for clock_id.
@@ -204,13 +243,18 @@ static inline void vdso_test_clock(clockid_t clock_id)
 {
 	ksft_print_msg("clock_id: %s\n", vdso_clock_name[clock_id]);
 
+	/* Test vDSO functions directly */
 	vdso_test_clock_gettime(clock_id);
 	vdso_test_clock_gettime64(clock_id);
 
 	vdso_test_clock_getres(clock_id);
+
+	/* Test libc wrappers */
+	libc_test_clock_gettime(clock_id);
+	libc_test_clock_gettime64(clock_id);
 }
 
-#define VDSO_TEST_PLAN	29
+#define VDSO_TEST_PLAN	47
 
 int main(int argc, char **argv)
 {
-- 
2.51.0

