Commit 9f7d03a2 authored by Mark Brown's avatar Mark Brown Committed by Will Deacon
Browse files

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: default avatarMark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20210913125505.52619-7-broonie@kernel.org


Signed-off-by: default avatarWill Deacon <will@kernel.org>
parent 8c9eece0
Loading
Loading
Loading
Loading
+26 −2
Original line number Diff line number Diff line
@@ -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);