aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Brown <[email protected]>2021-09-13 13:55:03 +0100
committerWill Deacon <[email protected]>2021-09-29 14:40:32 +0100
commit9f7d03a2c5a1e57bb4ec5fddecff4c000f34a786 (patch)
treed084e7f799903d30f7810c51495f1586694eea31
parent8c9eece0bfbf90064470e173c80fe3495f24b397 (diff)
selftests: arm64: Verify interoperation of SVE and FPSIMD register sets
After setting the FPSIMD registers via the SVE register set read them back via the FPSIMD register set, validating that the two register sets are interoperating and that the values we thought we set made it into the child process. Signed-off-by: Mark Brown <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
-rw-r--r--tools/testing/selftests/arm64/fp/sve-ptrace.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/tools/testing/selftests/arm64/fp/sve-ptrace.c b/tools/testing/selftests/arm64/fp/sve-ptrace.c
index 2d130fedc019..31a2c2fc529d 100644
--- a/tools/testing/selftests/arm64/fp/sve-ptrace.c
+++ b/tools/testing/selftests/arm64/fp/sve-ptrace.c
@@ -46,6 +46,15 @@ static int do_child(void)
return EXIT_SUCCESS;
}
+static int get_fpsimd(pid_t pid, struct user_fpsimd_state *fpsimd)
+{
+ struct iovec iov;
+
+ iov.iov_base = fpsimd;
+ iov.iov_len = sizeof(*fpsimd);
+ return ptrace(PTRACE_GETREGSET, pid, NT_PRFPREG, &iov);
+}
+
static struct user_sve_header *get_sve(pid_t pid, void **buf, size_t *size)
{
struct user_sve_header *sve;
@@ -122,7 +131,7 @@ static int do_parent(pid_t child)
void *svebuf = NULL, *newsvebuf;
size_t svebufsz = 0, newsvebufsz;
struct user_sve_header *sve, *new_sve;
- struct user_fpsimd_state *fpsimd;
+ struct user_fpsimd_state *fpsimd, new_fpsimd;
unsigned int i, j;
unsigned char *p;
unsigned int vq;
@@ -221,7 +230,22 @@ static int do_parent(pid_t child)
goto error;
}
- /* Zero the first SVE Z register */
+ /* Verify via the FPSIMD regset */
+ if (get_fpsimd(pid, &new_fpsimd)) {
+ int e = errno;
+
+ ksft_test_result_fail("get_fpsimd(): %s\n",
+ strerror(errno));
+ if (e == ESRCH)
+ goto disappeared;
+
+ goto error;
+ }
+ if (memcmp(fpsimd, &new_fpsimd, sizeof(*fpsimd)) == 0)
+ ksft_test_result_pass("get_fpsimd() gave same state\n");
+ else
+ ksft_test_result_fail("get_fpsimd() gave different state\n");
+
vq = sve_vq_from_vl(sve->vl);
newsvebufsz = SVE_PT_SVE_ZREG_OFFSET(vq, 1);