From: Abdalla Eldoumani <aamsdoumani@gmail.com>
To: Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>, Shuah Khan <shuah@kernel.org>
Cc: Mark Brown <broonie@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
linux-arm-kernel@lists.infradead.org,
linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org,
Abdalla Eldoumani <abdalla.eldoumani@ucalgary.ca>
Subject: [PATCH 2/2] kselftest/arm64: Check that PR_SVE_VL_INHERIT survives a second exec
Date: Sat, 17 Oct 2026 12:24:54 -0600 [thread overview]
Message-ID: <20261017182455.1884-3-aamsdoumani@gmail.com> (raw)
In-Reply-To: <20261017182455.1884-1-aamsdoumani@gmail.com>
From: Abdalla Eldoumani <abdalla.eldoumani@ucalgary.ca>
The prctl_set_for_child test sets a vector length with
PR_SVE_VL_INHERIT and checks that a forked and exec()ed child sees it.
That only covers the first exec(). The kernel keeps the inherit flag
and the on-exec VL across exec() so that later descendants keep the VL
too, and nothing checks that part, which the fp TODO list notes as
testing PR_SVE_VL_INHERIT after a double fork.
Extend the test to also read the VL in a grandchild. The child
re-executes vec-syscfg in a mode that forks and execs the rdvl helper,
so the VL is read after two fork() and exec() generations. Both SVE and
SME are covered since the test runs for each vector type.
With a kernel modified to clear the inherit flag on exec() the existing
check still passes and the new check fails for both vector types, with
the grandchild getting the default VL. Drop the item from the TODO list.
Assisted-by: LLM
Signed-off-by: Abdalla Eldoumani <abdalla.eldoumani@ucalgary.ca>
---
tools/testing/selftests/arm64/fp/TODO | 1 -
tools/testing/selftests/arm64/fp/vec-syscfg.c | 62 ++++++++++++++++++-
2 files changed, 59 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/arm64/fp/TODO b/tools/testing/selftests/arm64/fp/TODO
index 44004e5..90ee128 100644
--- a/tools/testing/selftests/arm64/fp/TODO
+++ b/tools/testing/selftests/arm64/fp/TODO
@@ -4,4 +4,3 @@
- Ensure ptraced processes actually see the register state visible through
the ptrace interface.
- Big endian.
-- Test PR_SVE_VL_INHERIT after a double fork.
diff --git a/tools/testing/selftests/arm64/fp/vec-syscfg.c b/tools/testing/selftests/arm64/fp/vec-syscfg.c
index 2c8ccbe..b441dbf 100644
--- a/tools/testing/selftests/arm64/fp/vec-syscfg.c
+++ b/tools/testing/selftests/arm64/fp/vec-syscfg.c
@@ -24,6 +24,8 @@
#define ARCH_MIN_VL SVE_VL_MIN
+#define FORK_EXEC_ARG "--fork-exec"
+
struct vec_data {
const char *name;
unsigned long hwcap_type;
@@ -85,8 +87,12 @@ static int stdio_read_integer(FILE *f, const char *what, int *val)
return 0;
}
-/* Start a new process and return the vector length it sees */
-static int get_child_rdvl(struct vec_data *data)
+/*
+ * Start a new process and return the vector length it sees. With
+ * grandchild set the child re-executes this program, which forks and
+ * execs once more, so the VL is read two fork()/exec() generations down.
+ */
+static int get_descendant_rdvl(struct vec_data *data, bool grandchild)
{
FILE *out;
int pipefd[2];
@@ -123,6 +129,14 @@ static int get_child_rdvl(struct vec_data *data)
exit(EXIT_FAILURE);
}
+ if (grandchild) {
+ execl("/proc/self/exe", "vec-syscfg", FORK_EXEC_ARG,
+ data->rdvl_binary, NULL);
+ fprintf(stderr, "execl(/proc/self/exe) failed: %d (%s)\n",
+ errno, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
/* exec() a new binary which puts the VL on stdout */
ret = execl(data->rdvl_binary, data->rdvl_binary, NULL);
fprintf(stderr, "execl(%s) failed: %d (%s)\n",
@@ -174,6 +188,37 @@ static int get_child_rdvl(struct vec_data *data)
return read_vl;
}
+static int get_child_rdvl(struct vec_data *data)
+{
+ return get_descendant_rdvl(data, false);
+}
+
+/* FORK_EXEC_ARG mode: fork, exec path and pass on its exit status */
+static int fork_exec(const char *path)
+{
+ pid_t child;
+ int status;
+
+ child = fork();
+ if (child == -1) {
+ fprintf(stderr, "fork() failed: %d (%s)\n",
+ errno, strerror(errno));
+ return EXIT_FAILURE;
+ }
+
+ if (child == 0) {
+ execl(path, path, NULL);
+ fprintf(stderr, "execl(%s) failed: %d (%s)\n",
+ path, errno, strerror(errno));
+ _exit(EXIT_FAILURE);
+ }
+
+ if (waitpid(child, &status, 0) != child || !WIFEXITED(status))
+ return EXIT_FAILURE;
+
+ return WEXITSTATUS(status);
+}
+
static int file_read_integer(const char *name, int *val)
{
FILE *f;
@@ -498,6 +543,14 @@ static void prctl_set_for_child(struct vec_data *data)
return;
}
+ /* _INHERIT must survive the child's exec(), check a grandchild */
+ child_vl = get_descendant_rdvl(data, true);
+ if (child_vl != data->min_vl) {
+ ksft_test_result_fail("%s set %d _INHERIT but grandchild VL is %d\n",
+ data->name, data->min_vl, child_vl);
+ return;
+ }
+
ksft_test_result_pass("%s vector length was inherited\n", data->name);
file_write_integer(data->default_vl_file, data->default_vl);
@@ -759,11 +812,14 @@ static const struct {
{ "change_sve_with_za", change_sve_with_za },
};
-int main(void)
+int main(int argc, char **argv)
{
bool all_supported = true;
int i, j;
+ if (argc == 3 && strcmp(argv[1], FORK_EXEC_ARG) == 0)
+ return fork_exec(argv[2]);
+
ksft_print_header();
ksft_set_plan(ARRAY_SIZE(tests) * ARRAY_SIZE(vec_data) +
ARRAY_SIZE(all_types_tests));
--
2.49.0.windows.1
prev parent reply other threads:[~2026-10-17 18:26 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-17 18:24 [PATCH 0/2] kselftest/arm64: vec-syscfg exit status and VL inheritance coverage Abdalla Eldoumani
2026-10-17 18:24 ` [PATCH 1/2] kselftest/arm64: Report test failures in vec-syscfg's exit status Abdalla Eldoumani
2026-10-17 18:24 ` Abdalla Eldoumani [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261017182455.1884-3-aamsdoumani@gmail.com \
--to=aamsdoumani@gmail.com \
--cc=abdalla.eldoumani@ucalgary.ca \
--cc=broonie@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=shuah@kernel.org \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox