diff mbox series

kselftest: Fix vdso_test_abi return status

Message ID 20220126122608.54061-1-vincenzo.frascino@arm.com
State New
Headers show
Series kselftest: Fix vdso_test_abi return status | expand

Commit Message

Vincenzo Frascino Jan. 26, 2022, 12:26 p.m. UTC
vdso_test_abi contains a batch of tests that verify the validity of the
vDSO ABI.

When a vDSO symbol is not found the relevant test is skipped reporting
KSFT_SKIP. All the tests return values are then added in a single
variable which is checked to verify failures. This approach can have
side effects which result in reporting the wrong kselftest exit status.

Fix vdso_test_abi verifying the return code of each test separately.

Cc: Shuah Khan <shuah@kernel.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Reported-by: Cristian Marussi <cristian.marussi@arm.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
---
 tools/testing/selftests/vDSO/vdso_test_abi.c | 27 +++++++++++---------
 1 file changed, 15 insertions(+), 12 deletions(-)

Comments

Shuah Khan Jan. 27, 2022, 11:18 p.m. UTC | #1
On 1/26/22 5:26 AM, Vincenzo Frascino wrote:
> vdso_test_abi contains a batch of tests that verify the validity of the
> vDSO ABI.
> 
> When a vDSO symbol is not found the relevant test is skipped reporting
> KSFT_SKIP. All the tests return values are then added in a single
> variable which is checked to verify failures. This approach can have
> side effects which result in reporting the wrong kselftest exit status.
> 
> Fix vdso_test_abi verifying the return code of each test separately.
> 
> Cc: Shuah Khan <shuah@kernel.org>
> Cc: Andy Lutomirski <luto@kernel.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Reported-by: Cristian Marussi <cristian.marussi@arm.com>
> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
> ---
>   tools/testing/selftests/vDSO/vdso_test_abi.c | 27 +++++++++++---------
>   1 file changed, 15 insertions(+), 12 deletions(-)
> 
> diff --git a/tools/testing/selftests/vDSO/vdso_test_abi.c b/tools/testing/selftests/vDSO/vdso_test_abi.c
> index 3d603f1394af..3a4efb91b9b2 100644
> --- a/tools/testing/selftests/vDSO/vdso_test_abi.c
> +++ b/tools/testing/selftests/vDSO/vdso_test_abi.c
> @@ -184,10 +184,12 @@ static inline int vdso_test_clock(clockid_t clock_id)
>   	return ret0;
>   }
>   
> +#define VDSO_TESTS_MAX	9
> +
>   int main(int argc, char **argv)
>   {
>   	unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
> -	int ret;
> +	int ret[VDSO_TESTS_MAX] = {0};
>   
>   	if (!sysinfo_ehdr) {
>   		printf("AT_SYSINFO_EHDR is not present!\n");
> @@ -201,44 +203,45 @@ int main(int argc, char **argv)
>   
>   	vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR));
>   
> -	ret = vdso_test_gettimeofday();
> +	ret[0] = vdso_test_gettimeofday();
>   
>   #if _POSIX_TIMERS > 0
>   
>   #ifdef CLOCK_REALTIME
> -	ret += vdso_test_clock(CLOCK_REALTIME);
> +	ret[1] = vdso_test_clock(CLOCK_REALTIME);
>   #endif
>   
>   #ifdef CLOCK_BOOTTIME
> -	ret += vdso_test_clock(CLOCK_BOOTTIME);
> +	ret[2] = vdso_test_clock(CLOCK_BOOTTIME);
>   #endif
>   
>   #ifdef CLOCK_TAI
> -	ret += vdso_test_clock(CLOCK_TAI);
> +	ret[3] = vdso_test_clock(CLOCK_TAI);
>   #endif
>   
>   #ifdef CLOCK_REALTIME_COARSE
> -	ret += vdso_test_clock(CLOCK_REALTIME_COARSE);
> +	ret[4] = vdso_test_clock(CLOCK_REALTIME_COARSE);
>   #endif
>   
>   #ifdef CLOCK_MONOTONIC
> -	ret += vdso_test_clock(CLOCK_MONOTONIC);
> +	ret[5] = vdso_test_clock(CLOCK_MONOTONIC);
>   #endif
>   
>   #ifdef CLOCK_MONOTONIC_RAW
> -	ret += vdso_test_clock(CLOCK_MONOTONIC_RAW);
> +	ret[6] = vdso_test_clock(CLOCK_MONOTONIC_RAW);
>   #endif
>   
>   #ifdef CLOCK_MONOTONIC_COARSE
> -	ret += vdso_test_clock(CLOCK_MONOTONIC_COARSE);
> +	ret[7] = vdso_test_clock(CLOCK_MONOTONIC_COARSE);
>   #endif
>   
>   #endif
>   
> -	ret += vdso_test_time();
> +	ret[8] = vdso_test_time();
>   
> -	if (ret > 0)
> -		return KSFT_FAIL;
> +	for (int i = 0; i < VDSO_TESTS_MAX; i++)
> +		if (ret[i] == KSFT_FAIL)
> +			return KSFT_FAIL;
>   
>   	return KSFT_PASS;
>   }
> 

You can use the ksft_* counts interfaces for this instead of adding
counts here. ksft_test_result_*() can be used to increment the right
result counters and then print counts at the end.

Either if there is a failure in any of the tests it will be fail with
clear indication on which tests failed. vdso_test_clock() test for
example is reporting false positives by overriding the Skip return
with a pass.

thanks,
-- Shuah
Vincenzo Frascino Jan. 28, 2022, 11:09 a.m. UTC | #2
Hi Shuah,

On 1/27/22 11:18 PM, Shuah Khan wrote:
> 
> You can use the ksft_* counts interfaces for this instead of adding
> counts here. ksft_test_result_*() can be used to increment the right
> result counters and then print counts at the end.
> 
> Either if there is a failure in any of the tests it will be fail with
> clear indication on which tests failed. vdso_test_clock() test for
> example is reporting false positives by overriding the Skip return
> with a pass.
> 

Good point. I missed one condition in updating the test. I will post v2 that
will be compliant with the interface you mentioned.

Thanks.

> thanks,
> -- Shuah
diff mbox series

Patch

diff --git a/tools/testing/selftests/vDSO/vdso_test_abi.c b/tools/testing/selftests/vDSO/vdso_test_abi.c
index 3d603f1394af..3a4efb91b9b2 100644
--- a/tools/testing/selftests/vDSO/vdso_test_abi.c
+++ b/tools/testing/selftests/vDSO/vdso_test_abi.c
@@ -184,10 +184,12 @@  static inline int vdso_test_clock(clockid_t clock_id)
 	return ret0;
 }
 
+#define VDSO_TESTS_MAX	9
+
 int main(int argc, char **argv)
 {
 	unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
-	int ret;
+	int ret[VDSO_TESTS_MAX] = {0};
 
 	if (!sysinfo_ehdr) {
 		printf("AT_SYSINFO_EHDR is not present!\n");
@@ -201,44 +203,45 @@  int main(int argc, char **argv)
 
 	vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR));
 
-	ret = vdso_test_gettimeofday();
+	ret[0] = vdso_test_gettimeofday();
 
 #if _POSIX_TIMERS > 0
 
 #ifdef CLOCK_REALTIME
-	ret += vdso_test_clock(CLOCK_REALTIME);
+	ret[1] = vdso_test_clock(CLOCK_REALTIME);
 #endif
 
 #ifdef CLOCK_BOOTTIME
-	ret += vdso_test_clock(CLOCK_BOOTTIME);
+	ret[2] = vdso_test_clock(CLOCK_BOOTTIME);
 #endif
 
 #ifdef CLOCK_TAI
-	ret += vdso_test_clock(CLOCK_TAI);
+	ret[3] = vdso_test_clock(CLOCK_TAI);
 #endif
 
 #ifdef CLOCK_REALTIME_COARSE
-	ret += vdso_test_clock(CLOCK_REALTIME_COARSE);
+	ret[4] = vdso_test_clock(CLOCK_REALTIME_COARSE);
 #endif
 
 #ifdef CLOCK_MONOTONIC
-	ret += vdso_test_clock(CLOCK_MONOTONIC);
+	ret[5] = vdso_test_clock(CLOCK_MONOTONIC);
 #endif
 
 #ifdef CLOCK_MONOTONIC_RAW
-	ret += vdso_test_clock(CLOCK_MONOTONIC_RAW);
+	ret[6] = vdso_test_clock(CLOCK_MONOTONIC_RAW);
 #endif
 
 #ifdef CLOCK_MONOTONIC_COARSE
-	ret += vdso_test_clock(CLOCK_MONOTONIC_COARSE);
+	ret[7] = vdso_test_clock(CLOCK_MONOTONIC_COARSE);
 #endif
 
 #endif
 
-	ret += vdso_test_time();
+	ret[8] = vdso_test_time();
 
-	if (ret > 0)
-		return KSFT_FAIL;
+	for (int i = 0; i < VDSO_TESTS_MAX; i++)
+		if (ret[i] == KSFT_FAIL)
+			return KSFT_FAIL;
 
 	return KSFT_PASS;
 }