[PATCH] selftests: riscv: fix flag parsing and argv termination in vector tests

Zongmin Zhou min_halo at 163.com
Wed Oct 28 02:25:08 PDT 2026


From: Zongmin Zhou <zhouzongmin at kylinos.cn>

The xtheadvector support broke both the sending and the parsing side
of the vector-test argv flag protocol, in two independent ways.

First, on the sending side, launch_test() passes a NULL pointer in
argv[1] or argv[2] when the corresponding flag is unset.  A NULL argv
entry terminates the argument list, so when test_inherit is unset, the
xtheadvector flag in argv[2] never reaches the child and the child
always runs the standard V code path.  v_initval always launches its
child with test_inherit unset, so v_exec_initval_nolibc never
received the flag at all.

Second, on the parsing side, the nolibc receivers test the flags with
strcmp(argv[i], "x"), which is true when the argument is *not* "x",
so the branches were never taken even when both flags were passed.
The xtheadvector code path of v_exec_initval_nolibc was therefore
dead code, and in vstate_exec_nolibc test_inherit could never be set
(a plain "if (argc > 1)" did the job before the xtheadvector support
was added), so the inherit re-exec checks launched by vstate_prctl
were never exercised either.

Always pass both flag slots as non-NULL strings ("-" for false), test
the flags with !strcmp(..., "x"), and, when re-exec'ing for the
inherit check, clear the inherit request while preserving the
xtheadvector flag so the exec'd child still exercises the intended
instruction variant.  exec_argv in vstate_exec_nolibc is enlarged to
hold the terminating NULL.

Fixes: c384c5d4a2ae ("selftests: riscv: Support xtheadvector in vector tests")
Signed-off-by: Zongmin Zhou <zhouzongmin at kylinos.cn>
---
 .../riscv/vector/v_exec_initval_nolibc.c         |  2 +-
 tools/testing/selftests/riscv/vector/v_helpers.c | 10 ++++++++--
 .../selftests/riscv/vector/vstate_exec_nolibc.c  | 16 ++++++++++++----
 3 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/tools/testing/selftests/riscv/vector/v_exec_initval_nolibc.c b/tools/testing/selftests/riscv/vector/v_exec_initval_nolibc.c
index 4dde05e45a04..91e31f185b85 100644
--- a/tools/testing/selftests/riscv/vector/v_exec_initval_nolibc.c
+++ b/tools/testing/selftests/riscv/vector/v_exec_initval_nolibc.c
@@ -17,7 +17,7 @@ int main(int argc, char **argv)
 	char value = 0;
 	unsigned long vl;
 
-	if (argc > 2 && strcmp(argv[2], "x"))
+	if (argc > 2 && !strcmp(argv[2], "x"))
 		asm volatile (
 			// 0 | zimm[10:0] | rs1 | 1 1 1 | rd |1010111| vsetvli
 			// vsetvli	t4, x0, e8, m1, d1
diff --git a/tools/testing/selftests/riscv/vector/v_helpers.c b/tools/testing/selftests/riscv/vector/v_helpers.c
index de6da7c8d2f1..7eb157d4fc4b 100644
--- a/tools/testing/selftests/riscv/vector/v_helpers.c
+++ b/tools/testing/selftests/riscv/vector/v_helpers.c
@@ -61,9 +61,15 @@ int launch_test(char *next_program, int test_inherit, int xtheadvector)
 	}
 
 	if (!pid) {
+		/*
+		 * Always pass both flag slots as non-NULL strings ("-" for
+		 * false), otherwise a NULL argv[] entry terminates the
+		 * argument list and the following slots never reach the
+		 * child.
+		 */
 		exec_argv[0] = next_program;
-		exec_argv[1] = test_inherit != 0 ? "x" : NULL;
-		exec_argv[2] = xtheadvector != 0 ? "x" : NULL;
+		exec_argv[1] = test_inherit != 0 ? "x" : "-";
+		exec_argv[2] = xtheadvector != 0 ? "x" : "-";
 		exec_argv[3] = NULL;
 		exec_envp[0] = NULL;
 		/* launch the program again to check inherit */
diff --git a/tools/testing/selftests/riscv/vector/vstate_exec_nolibc.c b/tools/testing/selftests/riscv/vector/vstate_exec_nolibc.c
index 12f1b1b1c7aa..01ba5e5415b4 100644
--- a/tools/testing/selftests/riscv/vector/vstate_exec_nolibc.c
+++ b/tools/testing/selftests/riscv/vector/vstate_exec_nolibc.c
@@ -8,12 +8,12 @@ int main(int argc, char **argv)
 {
 	int rc, pid, status, test_inherit = 0, xtheadvector = 0;
 	long ctrl, ctrl_c;
-	char *exec_argv[2], *exec_envp[2];
+	char *exec_argv[4], *exec_envp[2];
 
-	if (argc > 1 && strcmp(argv[1], "x"))
+	if (argc > 1 && !strcmp(argv[1], "x"))
 		test_inherit = 1;
 
-	if (argc > 2 && strcmp(argv[2], "x"))
+	if (argc > 2 && !strcmp(argv[2], "x"))
 		xtheadvector = 1;
 
 	ctrl = prctl(PR_RISCV_V_GET_CONTROL, 0, 0, 0, 0);
@@ -31,8 +31,16 @@ int main(int argc, char **argv)
 
 		/* child  */
 		if (!pid) {
+			/*
+			 * Re-exec without the inherit request (this stage
+			 * is done) while preserving the xtheadvector flag,
+			 * so the exec'd child still exercises the intended
+			 * instruction variant.
+			 */
 			exec_argv[0] = THIS_PROGRAM;
-			exec_argv[1] = NULL;
+			exec_argv[1] = "-";
+			exec_argv[2] = xtheadvector ? "x" : "-";
+			exec_argv[3] = NULL;
 			exec_envp[0] = NULL;
 			exec_envp[1] = NULL;
 			/* launch the program again to check inherit */
-- 
2.34.1


No virus found
		Checked by Hillstone Network AntiVirus




More information about the linux-riscv mailing list