diff mbox series

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

Message ID 20210917120855.13858-5-broonie@kernel.org
State Superseded
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(+)

-- 
2.20.1

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)