mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-25 23:02:51 -04:00
kselftst/arm64: Test NT_ARM_SVE FPSIMD format writes on non-SVE systems
In order to allow exiting streaming mode on systems with SME but not SVE we allow writes of FPSIMD format data via NT_ARM_SVE even when SVE is not supported, add a test case that covers this to sve-ptrace. We do not support reads. Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
This commit is contained in:
committed by
Catalin Marinas
parent
472800cd5e
commit
eb9df6d69a
@@ -394,6 +394,58 @@ static void ptrace_sve_fpsimd(pid_t child, const struct vec_type *type)
|
||||
free(svebuf);
|
||||
}
|
||||
|
||||
/* Write the FPSIMD registers via the SVE regset when SVE is not supported */
|
||||
static void ptrace_sve_fpsimd_no_sve(pid_t child)
|
||||
{
|
||||
void *svebuf;
|
||||
struct user_sve_header *sve;
|
||||
struct user_fpsimd_state *fpsimd, new_fpsimd;
|
||||
unsigned int i, j;
|
||||
unsigned char *p;
|
||||
int ret;
|
||||
|
||||
svebuf = malloc(SVE_PT_SIZE(0, SVE_PT_REGS_FPSIMD));
|
||||
if (!svebuf) {
|
||||
ksft_test_result_fail("Failed to allocate FPSIMD buffer\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* On a system without SVE the VL should be set to 0 */
|
||||
memset(svebuf, 0, SVE_PT_SIZE(0, SVE_PT_REGS_FPSIMD));
|
||||
sve = svebuf;
|
||||
sve->flags = SVE_PT_REGS_FPSIMD;
|
||||
sve->size = SVE_PT_SIZE(0, SVE_PT_REGS_FPSIMD);
|
||||
sve->vl = 0;
|
||||
|
||||
/* Try to set a known FPSIMD state via PT_REGS_SVE */
|
||||
fpsimd = (struct user_fpsimd_state *)((char *)sve +
|
||||
SVE_PT_FPSIMD_OFFSET);
|
||||
for (i = 0; i < 32; ++i) {
|
||||
p = (unsigned char *)&fpsimd->vregs[i];
|
||||
|
||||
for (j = 0; j < sizeof(fpsimd->vregs[i]); ++j)
|
||||
p[j] = j;
|
||||
}
|
||||
|
||||
ret = set_sve(child, &vec_types[0], sve);
|
||||
ksft_test_result(ret == 0, "FPSIMD write via SVE\n");
|
||||
if (ret) {
|
||||
ksft_test_result_skip("Verify FPSIMD write via SVE\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Verify via the FPSIMD regset */
|
||||
if (get_fpsimd(child, &new_fpsimd)) {
|
||||
ksft_test_result_skip("Verify FPSIMD write via SVE\n");
|
||||
goto out;
|
||||
}
|
||||
ksft_test_result(memcmp(fpsimd, &new_fpsimd, sizeof(*fpsimd)) == 0,
|
||||
"Verify FPSIMD write via SVE\n");
|
||||
|
||||
out:
|
||||
free(svebuf);
|
||||
}
|
||||
|
||||
/* Validate attempting to set SVE data and read SVE data */
|
||||
static void ptrace_set_sve_get_sve_data(pid_t child,
|
||||
const struct vec_type *type,
|
||||
@@ -826,6 +878,15 @@ static int do_parent(pid_t child)
|
||||
}
|
||||
}
|
||||
|
||||
/* We support SVE writes of FPSMID format on SME only systems */
|
||||
if (!(getauxval(AT_HWCAP) & HWCAP_SVE) &&
|
||||
(getauxval(AT_HWCAP2) & HWCAP2_SME)) {
|
||||
ptrace_sve_fpsimd_no_sve(child);
|
||||
} else {
|
||||
ksft_test_result_skip("FPSIMD write via SVE\n");
|
||||
ksft_test_result_skip("Verify FPSIMD write via SVE\n");
|
||||
}
|
||||
|
||||
ret = EXIT_SUCCESS;
|
||||
|
||||
error:
|
||||
|
||||
Reference in New Issue
Block a user