aboutsummaryrefslogtreecommitdiffstats
path: root/tools/testing/selftests/arm64
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2021-09-29 16:19:25 +0100
committerWill Deacon <will@kernel.org>2021-09-29 16:33:04 +0100
commit8694e5e6388695195a32bd5746635ca166a8df56 (patch)
treed1642ad539103a040987d181c9d135b3fe74d4c0 /tools/testing/selftests/arm64
parentselftests: arm64: Fix and enable test for setting current VL in vec-syscfg (diff)
downloadlinux-dev-8694e5e6388695195a32bd5746635ca166a8df56.tar.xz
linux-dev-8694e5e6388695195a32bd5746635ca166a8df56.zip
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 <broonie@kernel.org> Reviewed-by: Tomohiro Misono <misono.tomohiro@jp.fujitsu.com> Link: https://lore.kernel.org/r/20210929151925.9601-5-broonie@kernel.org Signed-off-by: Will Deacon <will@kernel.org>
Diffstat (limited to 'tools/testing/selftests/arm64')
-rw-r--r--tools/testing/selftests/arm64/fp/vec-syscfg.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/tools/testing/selftests/arm64/fp/vec-syscfg.c b/tools/testing/selftests/arm64/fp/vec-syscfg.c
index 9d6ac843e651..272b888e018e 100644
--- a/tools/testing/selftests/arm64/fp/vec-syscfg.c
+++ b/tools/testing/selftests/arm64/fp/vec-syscfg.c
@@ -540,6 +540,82 @@ static void prctl_set_onexec(struct vec_data *data)
file_write_integer(data->default_vl_file, data->default_vl);
}
+/* For each VQ verify that setting via prctl() does the right thing */
+static void prctl_set_all_vqs(struct vec_data *data)
+{
+ int ret, vq, vl, new_vl;
+ int errors = 0;
+
+ if (!data->min_vl || !data->max_vl) {
+ ksft_test_result_skip("%s Failed to enumerate VLs, not testing VL setting\n",
+ data->name);
+ return;
+ }
+
+ for (vq = SVE_VQ_MIN; vq <= SVE_VQ_MAX; vq++) {
+ vl = sve_vl_from_vq(vq);
+
+ /* Attempt to set the VL */
+ ret = prctl(data->prctl_set, vl);
+ if (ret < 0) {
+ errors++;
+ ksft_print_msg("%s prctl set failed for %d: %d (%s)\n",
+ data->name, vl,
+ errno, strerror(errno));
+ continue;
+ }
+
+ new_vl = ret & PR_SVE_VL_LEN_MASK;
+
+ /* Check that we actually have the reported new VL */
+ if (data->rdvl() != new_vl) {
+ ksft_print_msg("Set %s VL %d but RDVL reports %d\n",
+ data->name, new_vl, data->rdvl());
+ errors++;
+ }
+
+ /* Was that the VL we asked for? */
+ if (new_vl == vl)
+ continue;
+
+ /* Should round up to the minimum VL if below it */
+ if (vl < data->min_vl) {
+ if (new_vl != data->min_vl) {
+ ksft_print_msg("%s VL %d returned %d not minimum %d\n",
+ data->name, vl, new_vl,
+ data->min_vl);
+ errors++;
+ }
+
+ continue;
+ }
+
+ /* Should round down to maximum VL if above it */
+ if (vl > data->max_vl) {
+ if (new_vl != data->max_vl) {
+ ksft_print_msg("%s VL %d returned %d not maximum %d\n",
+ data->name, vl, new_vl,
+ data->max_vl);
+ errors++;
+ }
+
+ continue;
+ }
+
+ /* Otherwise we should've rounded down */
+ if (!(new_vl < vl)) {
+ ksft_print_msg("%s VL %d returned %d, did not round down\n",
+ data->name, vl, new_vl);
+ errors++;
+
+ continue;
+ }
+ }
+
+ ksft_test_result(errors == 0, "%s prctl() set all VLs, %d errors\n",
+ data->name, errors);
+}
+
typedef void (*test_type)(struct vec_data *);
static const test_type tests[] = {
@@ -557,6 +633,7 @@ static const test_type tests[] = {
prctl_set_no_child,
prctl_set_for_child,
prctl_set_onexec,
+ prctl_set_all_vqs,
};
int main(void)