From 6eda706a535c3d0119eaefaad5fc119609639ed2 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Fri, 30 Aug 2024 14:28:38 +0200 Subject: selftests: vDSO: fix the way vDSO functions are called for powerpc vdso_test_correctness test fails on powerpc: ~ # ./vdso_test_correctness ... [RUN] Testing clock_gettime for clock CLOCK_REALTIME_ALARM (8)... [FAIL] No such clock, but __vdso_clock_gettime returned 22 [RUN] Testing clock_gettime for clock CLOCK_BOOTTIME_ALARM (9)... [FAIL] No such clock, but __vdso_clock_gettime returned 22 [RUN] Testing clock_gettime for clock CLOCK_SGI_CYCLE (10)... [FAIL] No such clock, but __vdso_clock_gettime returned 22 ... [RUN] Testing clock_gettime for clock invalid (-1)... [FAIL] No such clock, but __vdso_clock_gettime returned 22 [RUN] Testing clock_gettime for clock invalid (-2147483648)... [FAIL] No such clock, but __vdso_clock_gettime returned 22 [RUN] Testing clock_gettime for clock invalid (2147483647)... [FAIL] No such clock, but __vdso_clock_gettime returned 22 On powerpc, a call to a VDSO function is not an ordinary C function call. Unlike several architectures which returns a negative error code in case of an error, powerpc sets CR[SO] and returns the error code as a positive value. Define and use a macro called VDSO_CALL() which takes a pointer to the function to call, the number of arguments and the arguments. Also update ABI vdso documentation to reflect this subtlety. Provide a specific version of VDSO_CALL() for powerpc that negates the error code on return when CR[SO] is set. Fixes: c7e5789b24d3 ("kselftest: Move test_vdso to the vDSO test suite") Fixes: 2e9a97256616 ("selftests: vdso: Add a selftest for vDSO getcpu()") Fixes: 693f5ca08ca0 ("kselftest: Extend vDSO selftest") Fixes: b2f1c3db2887 ("kselftest: Extend vdso correctness test to clock_gettime64") Fixes: 4920a2590e91 ("selftests/vDSO: add tests for vgetrandom") Signed-off-by: Christophe Leroy Acked-by: Shuah Khan Signed-off-by: Jason A. Donenfeld --- tools/testing/selftests/vDSO/vdso_test_correctness.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'tools/testing/selftests/vDSO/vdso_test_correctness.c') diff --git a/tools/testing/selftests/vDSO/vdso_test_correctness.c b/tools/testing/selftests/vDSO/vdso_test_correctness.c index cdb697ae8343..5fb97ad67eea 100644 --- a/tools/testing/selftests/vDSO/vdso_test_correctness.c +++ b/tools/testing/selftests/vDSO/vdso_test_correctness.c @@ -20,6 +20,7 @@ #include #include "vdso_config.h" +#include "vdso_call.h" #include "../kselftest.h" static const char **name; @@ -186,7 +187,7 @@ static void test_getcpu(void) ret_sys = sys_getcpu(&cpu_sys, &node_sys, 0); if (vdso_getcpu) - ret_vdso = vdso_getcpu(&cpu_vdso, &node_vdso, 0); + ret_vdso = VDSO_CALL(vdso_getcpu, 3, &cpu_vdso, &node_vdso, 0); if (vgetcpu) ret_vsys = vgetcpu(&cpu_vsys, &node_vsys, 0); @@ -269,7 +270,7 @@ static void test_one_clock_gettime(int clock, const char *name) if (sys_clock_gettime(clock, &start) < 0) { if (errno == EINVAL) { - vdso_ret = vdso_clock_gettime(clock, &vdso); + vdso_ret = VDSO_CALL(vdso_clock_gettime, 2, clock, &vdso); if (vdso_ret == -EINVAL) { printf("[OK]\tNo such clock.\n"); } else { @@ -282,7 +283,7 @@ static void test_one_clock_gettime(int clock, const char *name) return; } - vdso_ret = vdso_clock_gettime(clock, &vdso); + vdso_ret = VDSO_CALL(vdso_clock_gettime, 2, clock, &vdso); end_ret = sys_clock_gettime(clock, &end); if (vdso_ret != 0 || end_ret != 0) { @@ -331,7 +332,7 @@ static void test_one_clock_gettime64(int clock, const char *name) if (sys_clock_gettime64(clock, &start) < 0) { if (errno == EINVAL) { - vdso_ret = vdso_clock_gettime64(clock, &vdso); + vdso_ret = VDSO_CALL(vdso_clock_gettime64, 2, clock, &vdso); if (vdso_ret == -EINVAL) { printf("[OK]\tNo such clock.\n"); } else { @@ -344,7 +345,7 @@ static void test_one_clock_gettime64(int clock, const char *name) return; } - vdso_ret = vdso_clock_gettime64(clock, &vdso); + vdso_ret = VDSO_CALL(vdso_clock_gettime64, 2, clock, &vdso); end_ret = sys_clock_gettime64(clock, &end); if (vdso_ret != 0 || end_ret != 0) { @@ -401,7 +402,7 @@ static void test_gettimeofday(void) return; } - vdso_ret = vdso_gettimeofday(&vdso, &vdso_tz); + vdso_ret = VDSO_CALL(vdso_gettimeofday, 2, &vdso, &vdso_tz); end_ret = sys_gettimeofday(&end, NULL); if (vdso_ret != 0 || end_ret != 0) { @@ -431,7 +432,7 @@ static void test_gettimeofday(void) } /* And make sure that passing NULL for tz doesn't crash. */ - vdso_gettimeofday(&vdso, NULL); + VDSO_CALL(vdso_gettimeofday, 2, &vdso, NULL); } int main(int argc, char **argv) -- cgit v1.2.3