Commit 0ba1ce1e authored by Mark Brown's avatar Mark Brown Committed by Will Deacon
Browse files

selftests: arm64: Add coverage of ptrace flags for SVE VL inheritance



Add a test that covers enabling and disabling of SVE vector length
inheritance via the ptrace interface.

Signed-off-by: default avatarMark Brown <broonie@kernel.org>
Acked-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Link: https://lore.kernel.org/r/20211005123537.976795-1-broonie@kernel.org


Signed-off-by: default avatarWill Deacon <will@kernel.org>
parent 8694e5e6
Loading
Loading
Loading
Loading
+54 −1
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@
#include "../../kselftest.h"

#define VL_TESTS (((SVE_VQ_MAX - SVE_VQ_MIN) + 1) * 3)
#define FPSIMD_TESTS 3
#define FPSIMD_TESTS 5

#define EXPECTED_TESTS (VL_TESTS + FPSIMD_TESTS)

@@ -105,6 +105,56 @@ static int set_sve(pid_t pid, const struct user_sve_header *sve)
	return ptrace(PTRACE_SETREGSET, pid, NT_ARM_SVE, &iov);
}

/* Validate setting and getting the inherit flag */
static void ptrace_set_get_inherit(pid_t child)
{
	struct user_sve_header sve;
	struct user_sve_header *new_sve = NULL;
	size_t new_sve_size = 0;
	int ret;

	/* First set the flag */
	memset(&sve, 0, sizeof(sve));
	sve.size = sizeof(sve);
	sve.vl = sve_vl_from_vq(SVE_VQ_MIN);
	sve.flags = SVE_PT_VL_INHERIT;
	ret = set_sve(child, &sve);
	if (ret != 0) {
		ksft_test_result_fail("Failed to set SVE_PT_VL_INHERIT\n");
		return;
	}

	/*
	 * Read back the new register state and verify that we have
	 * set the flags we expected.
	 */
	if (!get_sve(child, (void **)&new_sve, &new_sve_size)) {
		ksft_test_result_fail("Failed to read SVE flags\n");
		return;
	}

	ksft_test_result(new_sve->flags & SVE_PT_VL_INHERIT,
			 "SVE_PT_VL_INHERIT set\n");

	/* Now clear */
	sve.flags &= ~SVE_PT_VL_INHERIT;
	ret = set_sve(child, &sve);
	if (ret != 0) {
		ksft_test_result_fail("Failed to clear SVE_PT_VL_INHERIT\n");
		return;
	}

	if (!get_sve(child, (void **)&new_sve, &new_sve_size)) {
		ksft_test_result_fail("Failed to read SVE flags\n");
		return;
	}

	ksft_test_result(!(new_sve->flags & SVE_PT_VL_INHERIT),
			 "SVE_PT_VL_INHERIT cleared\n");

	free(new_sve);
}

/* Validate attempting to set the specfied VL via ptrace */
static void ptrace_set_get_vl(pid_t child, unsigned int vl, bool *supported)
{
@@ -452,6 +502,9 @@ static int do_parent(pid_t child)
	/* FPSIMD via SVE regset */
	ptrace_sve_fpsimd(child);

	/* prctl() flags */
	ptrace_set_get_inherit(child);

	/* Step through every possible VQ */
	for (vq = SVE_VQ_MIN; vq <= SVE_VQ_MAX; vq++) {
		vl = sve_vl_from_vq(vq);