mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-04 20:19:47 +08:00
kselftest/arm64: Test FPSIMD format data writes via NT_ARM_SVE in fp-ptrace
The NT_ARM_SVE register set supports two data formats, the native SVE one and an alternative format where we embed a copy of user_fpsimd_data as used for NT_PRFPREG in the SVE register set. The register data is set as for a write to NT_PRFPREG and changes in vector length and streaming mode are handled as for any NT_ARM_SVE write. This has not previously been tested by fp-ptrace, add coverage of it. We do not support writes in FPSIMD format for NT_ARM_SSVE so we skip the test for anything that would leave us in streaming mode. Signed-off-by: Mark Brown <broonie@kernel.org> Link: https://lore.kernel.org/r/20250718-arm64-fp-ptrace-sve-fpsimd-v1-1-7ecda32aa297@kernel.org Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
This commit is contained in:
parent
b5cebb5de9
commit
b84d2b2795
@ -1066,6 +1066,23 @@ static bool sve_write_supported(struct test_config *config)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool sve_write_fpsimd_supported(struct test_config *config)
|
||||||
|
{
|
||||||
|
if (!sve_supported())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ((config->svcr_in & SVCR_ZA) != (config->svcr_expected & SVCR_ZA))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (config->svcr_expected & SVCR_SM)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (config->sme_vl_in != config->sme_vl_expected)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void fpsimd_write_expected(struct test_config *config)
|
static void fpsimd_write_expected(struct test_config *config)
|
||||||
{
|
{
|
||||||
int vl;
|
int vl;
|
||||||
@ -1152,7 +1169,7 @@ static void sve_write_expected(struct test_config *config)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sve_write(pid_t child, struct test_config *config)
|
static void sve_write_sve(pid_t child, struct test_config *config)
|
||||||
{
|
{
|
||||||
struct user_sve_header *sve;
|
struct user_sve_header *sve;
|
||||||
struct iovec iov;
|
struct iovec iov;
|
||||||
@ -1195,6 +1212,45 @@ static void sve_write(pid_t child, struct test_config *config)
|
|||||||
free(iov.iov_base);
|
free(iov.iov_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sve_write_fpsimd(pid_t child, struct test_config *config)
|
||||||
|
{
|
||||||
|
struct user_sve_header *sve;
|
||||||
|
struct user_fpsimd_state *fpsimd;
|
||||||
|
struct iovec iov;
|
||||||
|
int ret, vl, vq;
|
||||||
|
|
||||||
|
vl = vl_expected(config);
|
||||||
|
vq = __sve_vq_from_vl(vl);
|
||||||
|
|
||||||
|
if (!vl)
|
||||||
|
return;
|
||||||
|
|
||||||
|
iov.iov_len = SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq,
|
||||||
|
SVE_PT_REGS_FPSIMD);
|
||||||
|
iov.iov_base = malloc(iov.iov_len);
|
||||||
|
if (!iov.iov_base) {
|
||||||
|
ksft_print_msg("Failed allocating %lu byte SVE write buffer\n",
|
||||||
|
iov.iov_len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memset(iov.iov_base, 0, iov.iov_len);
|
||||||
|
|
||||||
|
sve = iov.iov_base;
|
||||||
|
sve->size = iov.iov_len;
|
||||||
|
sve->flags = SVE_PT_REGS_FPSIMD;
|
||||||
|
sve->vl = vl;
|
||||||
|
|
||||||
|
fpsimd = iov.iov_base + SVE_PT_REGS_OFFSET;
|
||||||
|
memcpy(&fpsimd->vregs, v_expected, sizeof(v_expected));
|
||||||
|
|
||||||
|
ret = ptrace(PTRACE_SETREGSET, child, NT_ARM_SVE, &iov);
|
||||||
|
if (ret != 0)
|
||||||
|
ksft_print_msg("Failed to write SVE: %s (%d)\n",
|
||||||
|
strerror(errno), errno);
|
||||||
|
|
||||||
|
free(iov.iov_base);
|
||||||
|
}
|
||||||
|
|
||||||
static bool za_write_supported(struct test_config *config)
|
static bool za_write_supported(struct test_config *config)
|
||||||
{
|
{
|
||||||
if ((config->svcr_in & SVCR_SM) != (config->svcr_expected & SVCR_SM))
|
if ((config->svcr_in & SVCR_SM) != (config->svcr_expected & SVCR_SM))
|
||||||
@ -1386,7 +1442,13 @@ static struct test_definition sve_test_defs[] = {
|
|||||||
.name = "SVE write",
|
.name = "SVE write",
|
||||||
.supported = sve_write_supported,
|
.supported = sve_write_supported,
|
||||||
.set_expected_values = sve_write_expected,
|
.set_expected_values = sve_write_expected,
|
||||||
.modify_values = sve_write,
|
.modify_values = sve_write_sve,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "SVE write FPSIMD format",
|
||||||
|
.supported = sve_write_fpsimd_supported,
|
||||||
|
.set_expected_values = fpsimd_write_expected,
|
||||||
|
.modify_values = sve_write_fpsimd,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user