Skip to content

Commit b84d2b2

Browse files
brooniectmarinas
authored andcommitted
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 <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Catalin Marinas <[email protected]>
1 parent b5cebb5 commit b84d2b2

File tree

1 file changed

+64
-2
lines changed

1 file changed

+64
-2
lines changed

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

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,23 @@ static bool sve_write_supported(struct test_config *config)
10661066
return true;
10671067
}
10681068

1069+
static bool sve_write_fpsimd_supported(struct test_config *config)
1070+
{
1071+
if (!sve_supported())
1072+
return false;
1073+
1074+
if ((config->svcr_in & SVCR_ZA) != (config->svcr_expected & SVCR_ZA))
1075+
return false;
1076+
1077+
if (config->svcr_expected & SVCR_SM)
1078+
return false;
1079+
1080+
if (config->sme_vl_in != config->sme_vl_expected)
1081+
return false;
1082+
1083+
return true;
1084+
}
1085+
10691086
static void fpsimd_write_expected(struct test_config *config)
10701087
{
10711088
int vl;
@@ -1152,7 +1169,7 @@ static void sve_write_expected(struct test_config *config)
11521169
}
11531170
}
11541171

1155-
static void sve_write(pid_t child, struct test_config *config)
1172+
static void sve_write_sve(pid_t child, struct test_config *config)
11561173
{
11571174
struct user_sve_header *sve;
11581175
struct iovec iov;
@@ -1195,6 +1212,45 @@ static void sve_write(pid_t child, struct test_config *config)
11951212
free(iov.iov_base);
11961213
}
11971214

1215+
static void sve_write_fpsimd(pid_t child, struct test_config *config)
1216+
{
1217+
struct user_sve_header *sve;
1218+
struct user_fpsimd_state *fpsimd;
1219+
struct iovec iov;
1220+
int ret, vl, vq;
1221+
1222+
vl = vl_expected(config);
1223+
vq = __sve_vq_from_vl(vl);
1224+
1225+
if (!vl)
1226+
return;
1227+
1228+
iov.iov_len = SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq,
1229+
SVE_PT_REGS_FPSIMD);
1230+
iov.iov_base = malloc(iov.iov_len);
1231+
if (!iov.iov_base) {
1232+
ksft_print_msg("Failed allocating %lu byte SVE write buffer\n",
1233+
iov.iov_len);
1234+
return;
1235+
}
1236+
memset(iov.iov_base, 0, iov.iov_len);
1237+
1238+
sve = iov.iov_base;
1239+
sve->size = iov.iov_len;
1240+
sve->flags = SVE_PT_REGS_FPSIMD;
1241+
sve->vl = vl;
1242+
1243+
fpsimd = iov.iov_base + SVE_PT_REGS_OFFSET;
1244+
memcpy(&fpsimd->vregs, v_expected, sizeof(v_expected));
1245+
1246+
ret = ptrace(PTRACE_SETREGSET, child, NT_ARM_SVE, &iov);
1247+
if (ret != 0)
1248+
ksft_print_msg("Failed to write SVE: %s (%d)\n",
1249+
strerror(errno), errno);
1250+
1251+
free(iov.iov_base);
1252+
}
1253+
11981254
static bool za_write_supported(struct test_config *config)
11991255
{
12001256
if ((config->svcr_in & SVCR_SM) != (config->svcr_expected & SVCR_SM))
@@ -1386,7 +1442,13 @@ static struct test_definition sve_test_defs[] = {
13861442
.name = "SVE write",
13871443
.supported = sve_write_supported,
13881444
.set_expected_values = sve_write_expected,
1389-
.modify_values = sve_write,
1445+
.modify_values = sve_write_sve,
1446+
},
1447+
{
1448+
.name = "SVE write FPSIMD format",
1449+
.supported = sve_write_fpsimd_supported,
1450+
.set_expected_values = fpsimd_write_expected,
1451+
.modify_values = sve_write_fpsimd,
13901452
},
13911453
};
13921454

0 commit comments

Comments
 (0)