Skip to content

Commit eb9df6d

Browse files
brooniectmarinas
authored andcommitted
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>
1 parent 472800c commit eb9df6d

1 file changed

Lines changed: 61 additions & 0 deletions

File tree

tools/testing/selftests/arm64/fp/sve-ptrace.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,58 @@ static void ptrace_sve_fpsimd(pid_t child, const struct vec_type *type)
394394
free(svebuf);
395395
}
396396

397+
/* Write the FPSIMD registers via the SVE regset when SVE is not supported */
398+
static void ptrace_sve_fpsimd_no_sve(pid_t child)
399+
{
400+
void *svebuf;
401+
struct user_sve_header *sve;
402+
struct user_fpsimd_state *fpsimd, new_fpsimd;
403+
unsigned int i, j;
404+
unsigned char *p;
405+
int ret;
406+
407+
svebuf = malloc(SVE_PT_SIZE(0, SVE_PT_REGS_FPSIMD));
408+
if (!svebuf) {
409+
ksft_test_result_fail("Failed to allocate FPSIMD buffer\n");
410+
return;
411+
}
412+
413+
/* On a system without SVE the VL should be set to 0 */
414+
memset(svebuf, 0, SVE_PT_SIZE(0, SVE_PT_REGS_FPSIMD));
415+
sve = svebuf;
416+
sve->flags = SVE_PT_REGS_FPSIMD;
417+
sve->size = SVE_PT_SIZE(0, SVE_PT_REGS_FPSIMD);
418+
sve->vl = 0;
419+
420+
/* Try to set a known FPSIMD state via PT_REGS_SVE */
421+
fpsimd = (struct user_fpsimd_state *)((char *)sve +
422+
SVE_PT_FPSIMD_OFFSET);
423+
for (i = 0; i < 32; ++i) {
424+
p = (unsigned char *)&fpsimd->vregs[i];
425+
426+
for (j = 0; j < sizeof(fpsimd->vregs[i]); ++j)
427+
p[j] = j;
428+
}
429+
430+
ret = set_sve(child, &vec_types[0], sve);
431+
ksft_test_result(ret == 0, "FPSIMD write via SVE\n");
432+
if (ret) {
433+
ksft_test_result_skip("Verify FPSIMD write via SVE\n");
434+
goto out;
435+
}
436+
437+
/* Verify via the FPSIMD regset */
438+
if (get_fpsimd(child, &new_fpsimd)) {
439+
ksft_test_result_skip("Verify FPSIMD write via SVE\n");
440+
goto out;
441+
}
442+
ksft_test_result(memcmp(fpsimd, &new_fpsimd, sizeof(*fpsimd)) == 0,
443+
"Verify FPSIMD write via SVE\n");
444+
445+
out:
446+
free(svebuf);
447+
}
448+
397449
/* Validate attempting to set SVE data and read SVE data */
398450
static void ptrace_set_sve_get_sve_data(pid_t child,
399451
const struct vec_type *type,
@@ -826,6 +878,15 @@ static int do_parent(pid_t child)
826878
}
827879
}
828880

881+
/* We support SVE writes of FPSMID format on SME only systems */
882+
if (!(getauxval(AT_HWCAP) & HWCAP_SVE) &&
883+
(getauxval(AT_HWCAP2) & HWCAP2_SME)) {
884+
ptrace_sve_fpsimd_no_sve(child);
885+
} else {
886+
ksft_test_result_skip("FPSIMD write via SVE\n");
887+
ksft_test_result_skip("Verify FPSIMD write via SVE\n");
888+
}
889+
829890
ret = EXIT_SUCCESS;
830891

831892
error:

0 commit comments

Comments
 (0)