[PATCH] selftests: riscv: fix flag parsing and argv termination in vector tests
From: Zongmin Zhou
Date: Wed Oct 28 2026 - 05:27:11 EST
From: Zongmin Zhou <zhouzongmin@xxxxxxxxxx>
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@xxxxxxxxxx>
---
.../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