diff mbox series

[v2,4/4] selftests: arm64: Verify that all possible vector lengths are handled

Message ID 20210917120855.13858-5-broonie@kernel.org (mailing list archive)
State New
Headers show
Series selftests: arm64: vec-syscfg updates | expand

Commit Message

Mark Brown Sept. 17, 2021, 12:08 p.m. UTC
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>
---
 tools/testing/selftests/arm64/fp/vec-syscfg.c | 71 +++++++++++++++++++
 1 file changed, 71 insertions(+)

Comments

Tomohiro Misono (Fujitsu) Sept. 17, 2021, 12:26 p.m. UTC | #1
Reviewed-by: Tomohiro Misono <misono.tomohiro@jp.fujitsu.com>

Thanks,
Misono

> Subject: [PATCH v2 4/4] 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>
> ---
>  tools/testing/selftests/arm64/fp/vec-syscfg.c | 71
> +++++++++++++++++++
>  1 file changed, 71 insertions(+)
> 
> diff --git a/tools/testing/selftests/arm64/fp/vec-syscfg.c
> b/tools/testing/selftests/arm64/fp/vec-syscfg.c
> index 9d6ac843e651..de11cd2f5d79 100644
> --- a/tools/testing/selftests/arm64/fp/vec-syscfg.c
> +++ b/tools/testing/selftests/arm64/fp/vec-syscfg.c
> @@ -540,6 +540,76 @@ 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;
> +
> +	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 +627,7 @@ static const test_type tests[] = {
>  	prctl_set_no_child,
>  	prctl_set_for_child,
>  	prctl_set_onexec,
> +	prctl_set_all_vqs,
>  };
> 
>  int main(void)
> --
> 2.20.1
diff mbox series

Patch

diff --git a/tools/testing/selftests/arm64/fp/vec-syscfg.c b/tools/testing/selftests/arm64/fp/vec-syscfg.c
index 9d6ac843e651..de11cd2f5d79 100644
--- a/tools/testing/selftests/arm64/fp/vec-syscfg.c
+++ b/tools/testing/selftests/arm64/fp/vec-syscfg.c
@@ -540,6 +540,76 @@  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;
+
+	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 +627,7 @@  static const test_type tests[] = {
 	prctl_set_no_child,
 	prctl_set_for_child,
 	prctl_set_onexec,
+	prctl_set_all_vqs,
 };
 
 int main(void)