Skip to content

Commit 8694e5e

Browse files
brooniewilldeacon
authored andcommitted
selftests: arm64: Verify that all possible vector lengths are handled
As part of the enumeration interface for setting vector lengths it is valid to set vector lengths not supported in the system, these will be rounded to a supported vector length and returned from the prctl(). Add a test which exercises this for every valid vector length and makes sure that the return value is as expected and that this is reflected in the actual system state. Signed-off-by: Mark Brown <[email protected]> Reviewed-by: Tomohiro Misono <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent e423911 commit 8694e5e

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

tools/testing/selftests/arm64/fp/vec-syscfg.c

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,82 @@ static void prctl_set_onexec(struct vec_data *data)
540540
file_write_integer(data->default_vl_file, data->default_vl);
541541
}
542542

543+
/* For each VQ verify that setting via prctl() does the right thing */
544+
static void prctl_set_all_vqs(struct vec_data *data)
545+
{
546+
int ret, vq, vl, new_vl;
547+
int errors = 0;
548+
549+
if (!data->min_vl || !data->max_vl) {
550+
ksft_test_result_skip("%s Failed to enumerate VLs, not testing VL setting\n",
551+
data->name);
552+
return;
553+
}
554+
555+
for (vq = SVE_VQ_MIN; vq <= SVE_VQ_MAX; vq++) {
556+
vl = sve_vl_from_vq(vq);
557+
558+
/* Attempt to set the VL */
559+
ret = prctl(data->prctl_set, vl);
560+
if (ret < 0) {
561+
errors++;
562+
ksft_print_msg("%s prctl set failed for %d: %d (%s)\n",
563+
data->name, vl,
564+
errno, strerror(errno));
565+
continue;
566+
}
567+
568+
new_vl = ret & PR_SVE_VL_LEN_MASK;
569+
570+
/* Check that we actually have the reported new VL */
571+
if (data->rdvl() != new_vl) {
572+
ksft_print_msg("Set %s VL %d but RDVL reports %d\n",
573+
data->name, new_vl, data->rdvl());
574+
errors++;
575+
}
576+
577+
/* Was that the VL we asked for? */
578+
if (new_vl == vl)
579+
continue;
580+
581+
/* Should round up to the minimum VL if below it */
582+
if (vl < data->min_vl) {
583+
if (new_vl != data->min_vl) {
584+
ksft_print_msg("%s VL %d returned %d not minimum %d\n",
585+
data->name, vl, new_vl,
586+
data->min_vl);
587+
errors++;
588+
}
589+
590+
continue;
591+
}
592+
593+
/* Should round down to maximum VL if above it */
594+
if (vl > data->max_vl) {
595+
if (new_vl != data->max_vl) {
596+
ksft_print_msg("%s VL %d returned %d not maximum %d\n",
597+
data->name, vl, new_vl,
598+
data->max_vl);
599+
errors++;
600+
}
601+
602+
continue;
603+
}
604+
605+
/* Otherwise we should've rounded down */
606+
if (!(new_vl < vl)) {
607+
ksft_print_msg("%s VL %d returned %d, did not round down\n",
608+
data->name, vl, new_vl);
609+
errors++;
610+
611+
continue;
612+
}
613+
}
614+
615+
ksft_test_result(errors == 0, "%s prctl() set all VLs, %d errors\n",
616+
data->name, errors);
617+
}
618+
543619
typedef void (*test_type)(struct vec_data *);
544620

545621
static const test_type tests[] = {
@@ -557,6 +633,7 @@ static const test_type tests[] = {
557633
prctl_set_no_child,
558634
prctl_set_for_child,
559635
prctl_set_onexec,
636+
prctl_set_all_vqs,
560637
};
561638

562639
int main(void)

0 commit comments

Comments
 (0)