For consistency with __vdso_clock_gettime64() there should also be a 64-bit variant of clock_getres(). This will allow the extension of CONFIG_COMPAT_32BIT_TIME to the vDSO and finally the removal of 32-bit time types from the kernel and UAPI.
Signed-off-by: Thomas Weißschuh thomas.weissschuh@linutronix.de --- Thomas Weißschuh (9): vdso: Add prototype for __vdso_clock_getres_time64() selftests: vDSO: vdso_config: Add configurations for clock_getres_time64() selftests: vDSO: vdso_test_abi: Use UAPI system call numbers selftests: vDSO: vdso_test_abi: Add test for clock_getres_time64() x86/vdso: Provide clock_getres_time64() for x86-32 ARM: VDSO: also patch out __vdso_clock_getres() if unavailable ARM: VDSO: provide clock_getres_time64() arm64: vdso32: Provide clock_getres_time64() MIPS: vdso: Provide getres_time64() for 32-bit ABIs
arch/arm/kernel/vdso.c | 2 + arch/arm/vdso/vdso.lds.S | 1 + arch/arm/vdso/vgettimeofday.c | 6 +++ arch/arm64/kernel/vdso32/vdso.lds.S | 1 + arch/arm64/kernel/vdso32/vgettimeofday.c | 6 +++ arch/mips/vdso/vdso.lds.S | 1 + arch/mips/vdso/vgettimeofday.c | 6 +++ arch/x86/entry/vdso/vclock_gettime.c | 8 ++++ arch/x86/entry/vdso/vdso32/vdso32.lds.S | 1 + include/vdso/gettime.h | 1 + tools/testing/selftests/vDSO/vdso_config.h | 4 +- tools/testing/selftests/vDSO/vdso_test_abi.c | 55 +++++++++++++++++++++++++++- 12 files changed, 89 insertions(+), 3 deletions(-) --- base-commit: 15a11f3ffb629cbbf6efd272239c04a9eb3180e2 change-id: 20251120-vdso-compat-time32-f4684ff250ba
Best regards,
For consistency with __vdso_clock_gettime64() there should also be a 64-bit variant of clock_getres(). This will allow the extension of CONFIG_COMPAT_32BIT_TIME to the vDSO and finally the removal of 32-bit time types from the kernel and UAPI. The generic vDSO library already provides nearly all necessary building blocks for architectures to provide this function. Only a prototype is missing.
Add the prototype to the generic header so architectures can start providing this function.
Suggested-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Thomas Weißschuh thomas.weissschuh@linutronix.de --- include/vdso/gettime.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/include/vdso/gettime.h b/include/vdso/gettime.h index 9ac161866653..16a0a0556b86 100644 --- a/include/vdso/gettime.h +++ b/include/vdso/gettime.h @@ -20,5 +20,6 @@ int __vdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts); __kernel_old_time_t __vdso_time(__kernel_old_time_t *t); int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz); int __vdso_clock_gettime64(clockid_t clock, struct __kernel_timespec *ts); +int __vdso_clock_getres_time64(clockid_t clock, struct __kernel_timespec *ts);
#endif
Some architectures will start to implement this function. Make sure that tests can be written for it.
Signed-off-by: Thomas Weißschuh thomas.weissschuh@linutronix.de --- tools/testing/selftests/vDSO/vdso_config.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/vDSO/vdso_config.h b/tools/testing/selftests/vDSO/vdso_config.h index 50c261005111..5da223731b81 100644 --- a/tools/testing/selftests/vDSO/vdso_config.h +++ b/tools/testing/selftests/vDSO/vdso_config.h @@ -66,7 +66,7 @@ static const char *versions[7] = { };
__attribute__((unused)) -static const char *names[2][7] = { +static const char *names[2][8] = { { "__kernel_gettimeofday", "__kernel_clock_gettime", @@ -75,6 +75,7 @@ static const char *names[2][7] = { "__kernel_getcpu", "__kernel_clock_gettime64", "__kernel_getrandom", + "__kernel_clock_getres_time64", }, { "__vdso_gettimeofday", @@ -84,6 +85,7 @@ static const char *names[2][7] = { "__vdso_getcpu", "__vdso_clock_gettime64", "__vdso_getrandom", + "__vdso_clock_getres_time64", }, };
SYS_clock_getres might have been redirected by libc to some other system call than the actual clock_getres. In the test we want to make sure to use exactly this system call.
Use the system call number exported by the UAPI headers which is always correct.
Signed-off-by: Thomas Weißschuh thomas.weissschuh@linutronix.de --- tools/testing/selftests/vDSO/vdso_test_abi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/vDSO/vdso_test_abi.c b/tools/testing/selftests/vDSO/vdso_test_abi.c index c620317eaeea..a75c12dcb0f1 100644 --- a/tools/testing/selftests/vDSO/vdso_test_abi.c +++ b/tools/testing/selftests/vDSO/vdso_test_abi.c @@ -179,7 +179,7 @@ static void vdso_test_clock_getres(clockid_t clk_id) clock_getres_fail++; }
- ret = syscall(SYS_clock_getres, clk_id, &sys_ts); + ret = syscall(__NR_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);
For consistency with __vdso_clock_gettime64() there should also be a 64-bit variant of clock_getres(). This will allow the extension of CONFIG_COMPAT_32BIT_TIME to the vDSO and finally the removal of 32-bit time types from the kernel and UAPI.
Signed-off-by: Thomas Weißschuh thomas.weissschuh@linutronix.de --- arch/arm/kernel/vdso.c | 1 + arch/arm/vdso/vdso.lds.S | 1 + arch/arm/vdso/vgettimeofday.c | 6 ++++++ 3 files changed, 8 insertions(+)
diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c index 566c40f0f7c7..0108f33d6bed 100644 --- a/arch/arm/kernel/vdso.c +++ b/arch/arm/kernel/vdso.c @@ -162,6 +162,7 @@ static void __init patch_vdso(void *ehdr) vdso_nullpatch_one(&einfo, "__vdso_clock_gettime"); vdso_nullpatch_one(&einfo, "__vdso_clock_gettime64"); vdso_nullpatch_one(&einfo, "__vdso_clock_getres"); + vdso_nullpatch_one(&einfo, "__vdso_clock_getres_time64"); } }
diff --git a/arch/arm/vdso/vdso.lds.S b/arch/arm/vdso/vdso.lds.S index 7c08371f4400..74d8d8bc8a40 100644 --- a/arch/arm/vdso/vdso.lds.S +++ b/arch/arm/vdso/vdso.lds.S @@ -74,6 +74,7 @@ VERSION __vdso_gettimeofday; __vdso_clock_getres; __vdso_clock_gettime64; + __vdso_clock_getres_time64; local: *; }; } diff --git a/arch/arm/vdso/vgettimeofday.c b/arch/arm/vdso/vgettimeofday.c index 3554aa35f1ba..2874dde7e6cf 100644 --- a/arch/arm/vdso/vgettimeofday.c +++ b/arch/arm/vdso/vgettimeofday.c @@ -34,6 +34,12 @@ int __vdso_clock_getres(clockid_t clock_id, return __cvdso_clock_getres_time32(clock_id, res); }
+int __vdso_clock_getres_time64(clockid_t clock_id, + struct __kernel_timespec *res) +{ + return __cvdso_clock_getres(clock_id, res); +} + /* Avoid unresolved references emitted by GCC */
void __aeabi_unwind_cpp_pr0(void)
Some architectures will start to implement this function. Make sure it works correctly.
Signed-off-by: Thomas Weißschuh thomas.weissschuh@linutronix.de --- tools/testing/selftests/vDSO/vdso_test_abi.c | 53 +++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/vDSO/vdso_test_abi.c b/tools/testing/selftests/vDSO/vdso_test_abi.c index a75c12dcb0f1..b162a4ba9c4f 100644 --- a/tools/testing/selftests/vDSO/vdso_test_abi.c +++ b/tools/testing/selftests/vDSO/vdso_test_abi.c @@ -36,6 +36,7 @@ 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[] = { @@ -196,6 +197,55 @@ static void vdso_test_clock_getres(clockid_t clk_id) } }
+#ifdef __NR_clock_getres_time64 +static void vdso_test_clock_getres_time64(clockid_t clk_id) +{ + int clock_getres_fail = 0; + + /* Find clock_getres. */ + vdso_clock_getres_time64_t vdso_clock_getres_time64 = + (vdso_clock_getres_time64_t)vdso_sym(version, name[7]); + + if (!vdso_clock_getres_time64) { + ksft_print_msg("Couldn't find %s\n", name[7]); + ksft_test_result_skip("%s %s\n", name[7], + vdso_clock_name[clk_id]); + return; + } + + struct vdso_timespec64 ts, sys_ts; + long ret = VDSO_CALL(vdso_clock_getres_time64, 2, clk_id, &ts); + + if (ret == 0) { + ksft_print_msg("The vdso resolution is %lld %lld\n", + (long long)ts.tv_sec, (long long)ts.tv_nsec); + } else { + clock_getres_fail++; + } + + ret = syscall(__NR_clock_getres_time64, 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); + + if ((sys_ts.tv_sec != ts.tv_sec) || (sys_ts.tv_nsec != ts.tv_nsec)) + clock_getres_fail++; + + if (clock_getres_fail > 0) { + ksft_test_result_fail("%s %s\n", name[7], + vdso_clock_name[clk_id]); + } else { + ksft_test_result_pass("%s %s\n", name[7], + vdso_clock_name[clk_id]); + } +} +#else /* !__NR_clock_getres_time64 */ +static void vdso_test_clock_getres_time64(clockid_t clk_id) +{ + ksft_test_result_skip("%s %s\n", name[7], vdso_clock_name[clk_id]); +} +#endif /* __NR_clock_getres_time64 */ + /* * This function calls vdso_test_clock_gettime and vdso_test_clock_getres * with different values for clock_id. @@ -208,9 +258,10 @@ static inline void vdso_test_clock(clockid_t clock_id) vdso_test_clock_gettime64(clock_id);
vdso_test_clock_getres(clock_id); + vdso_test_clock_getres_time64(clock_id); }
-#define VDSO_TEST_PLAN 29 +#define VDSO_TEST_PLAN 38
int main(int argc, char **argv) {
For consistency with __vdso_clock_gettime64() there should also be a 64-bit variant of clock_getres(). This will allow the extension of CONFIG_COMPAT_32BIT_TIME to the vDSO and finally the removal of 32-bit time types from the kernel and UAPI.
Signed-off-by: Thomas Weißschuh thomas.weissschuh@linutronix.de --- arch/x86/entry/vdso/vclock_gettime.c | 8 ++++++++ arch/x86/entry/vdso/vdso32/vdso32.lds.S | 1 + 2 files changed, 9 insertions(+)
diff --git a/arch/x86/entry/vdso/vclock_gettime.c b/arch/x86/entry/vdso/vclock_gettime.c index 0debc194bd78..027b7e88d753 100644 --- a/arch/x86/entry/vdso/vclock_gettime.c +++ b/arch/x86/entry/vdso/vclock_gettime.c @@ -74,4 +74,12 @@ int __vdso_clock_getres(clockid_t clock, struct old_timespec32 *res)
int clock_getres(clockid_t, struct old_timespec32 *) __attribute__((weak, alias("__vdso_clock_getres"))); + +int __vdso_clock_getres_time64(clockid_t clock, struct __kernel_timespec *ts) +{ + return __cvdso_clock_getres(clock, ts); +} + +int clock_getres_time64(clockid_t, struct __kernel_timespec *) + __attribute__((weak, alias("__vdso_clock_getres_time64"))); #endif diff --git a/arch/x86/entry/vdso/vdso32/vdso32.lds.S b/arch/x86/entry/vdso/vdso32/vdso32.lds.S index 8a3be07006bb..6f977c103584 100644 --- a/arch/x86/entry/vdso/vdso32/vdso32.lds.S +++ b/arch/x86/entry/vdso/vdso32/vdso32.lds.S @@ -28,6 +28,7 @@ VERSION __vdso_time; __vdso_clock_getres; __vdso_clock_gettime64; + __vdso_clock_getres_time64; __vdso_getcpu; };
The vDSO code hides symbols which are non-functional. __vdso_clock_getres() was not added to this list when it got introduced.
Fixes: 052e76a31b4a ("ARM: 8931/1: Add clock_getres entry point") Signed-off-by: Thomas Weißschuh thomas.weissschuh@linutronix.de --- arch/arm/kernel/vdso.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c index e38a30477f3d..566c40f0f7c7 100644 --- a/arch/arm/kernel/vdso.c +++ b/arch/arm/kernel/vdso.c @@ -161,6 +161,7 @@ static void __init patch_vdso(void *ehdr) vdso_nullpatch_one(&einfo, "__vdso_gettimeofday"); vdso_nullpatch_one(&einfo, "__vdso_clock_gettime"); vdso_nullpatch_one(&einfo, "__vdso_clock_gettime64"); + vdso_nullpatch_one(&einfo, "__vdso_clock_getres"); } }
For consistency with __vdso_clock_gettime64() there should also be a 64-bit variant of clock_getres(). This will allow the extension of CONFIG_COMPAT_32BIT_TIME to the vDSO and finally the removal of 32-bit time types from the kernel and UAPI.
Signed-off-by: Thomas Weißschuh thomas.weissschuh@linutronix.de --- arch/mips/vdso/vdso.lds.S | 1 + arch/mips/vdso/vgettimeofday.c | 6 ++++++ 2 files changed, 7 insertions(+)
diff --git a/arch/mips/vdso/vdso.lds.S b/arch/mips/vdso/vdso.lds.S index c8bbe56d89cb..5d08be3a6b85 100644 --- a/arch/mips/vdso/vdso.lds.S +++ b/arch/mips/vdso/vdso.lds.S @@ -103,6 +103,7 @@ VERSION __vdso_clock_getres; #if _MIPS_SIM != _MIPS_SIM_ABI64 __vdso_clock_gettime64; + __vdso_clock_getres_time64; #endif #endif local: *; diff --git a/arch/mips/vdso/vgettimeofday.c b/arch/mips/vdso/vgettimeofday.c index 604afea3f336..59627f2f51b7 100644 --- a/arch/mips/vdso/vgettimeofday.c +++ b/arch/mips/vdso/vgettimeofday.c @@ -46,6 +46,12 @@ int __vdso_clock_gettime64(clockid_t clock, return __cvdso_clock_gettime(clock, ts); }
+int __vdso_clock_getres_time64(clockid_t clock, + struct __kernel_timespec *ts) +{ + return __cvdso_clock_getres(clock, ts); +} + #else
int __vdso_clock_gettime(clockid_t clock,
For consistency with __vdso_clock_gettime64() there should also be a 64-bit variant of clock_getres(). This will allow the extension of CONFIG_COMPAT_32BIT_TIME to the vDSO and finally the removal of 32-bit time types from the kernel and UAPI.
Signed-off-by: Thomas Weißschuh thomas.weissschuh@linutronix.de --- arch/arm64/kernel/vdso32/vdso.lds.S | 1 + arch/arm64/kernel/vdso32/vgettimeofday.c | 6 ++++++ 2 files changed, 7 insertions(+)
diff --git a/arch/arm64/kernel/vdso32/vdso.lds.S b/arch/arm64/kernel/vdso32/vdso.lds.S index e02b27487ce8..c374fb0146f3 100644 --- a/arch/arm64/kernel/vdso32/vdso.lds.S +++ b/arch/arm64/kernel/vdso32/vdso.lds.S @@ -86,6 +86,7 @@ VERSION __vdso_gettimeofday; __vdso_clock_getres; __vdso_clock_gettime64; + __vdso_clock_getres_time64; local: *; }; } diff --git a/arch/arm64/kernel/vdso32/vgettimeofday.c b/arch/arm64/kernel/vdso32/vgettimeofday.c index 29b4d8f61e39..d7b39b0a9668 100644 --- a/arch/arm64/kernel/vdso32/vgettimeofday.c +++ b/arch/arm64/kernel/vdso32/vgettimeofday.c @@ -32,6 +32,12 @@ int __vdso_clock_getres(clockid_t clock_id, return __cvdso_clock_getres_time32(clock_id, res); }
+int __vdso_clock_getres_time64(clockid_t clock_id, + struct __kernel_timespec *res) +{ + return __cvdso_clock_getres(clock_id, res); +} + /* Avoid unresolved references emitted by GCC */
void __aeabi_unwind_cpp_pr0(void)
linux-kselftest-mirror@lists.linaro.org