1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2021 ARM Limited.
4 * Original author: Mark Brown <broonie@kernel.org>
16 #include <sys/prctl.h>
17 #include <sys/types.h>
19 #include <asm/sigcontext.h>
20 #include <asm/hwcap.h>
22 #include "../../kselftest.h"
25 #define ARCH_MIN_VL SVE_VL_MIN
29 unsigned long hwcap_type
;
31 const char *rdvl_binary
;
36 const char *default_vl_file
;
46 static struct vec_data vec_data
[] = {
49 .hwcap_type
= AT_HWCAP
,
52 .rdvl_binary
= "./rdvl-sve",
53 .prctl_get
= PR_SVE_GET_VL
,
54 .prctl_set
= PR_SVE_SET_VL
,
55 .default_vl_file
= "/proc/sys/abi/sve_default_vector_length",
59 .hwcap_type
= AT_HWCAP2
,
62 .rdvl_binary
= "./rdvl-sme",
63 .prctl_get
= PR_SME_GET_VL
,
64 .prctl_set
= PR_SME_SET_VL
,
65 .default_vl_file
= "/proc/sys/abi/sme_default_vector_length",
69 static bool vec_type_supported(struct vec_data
*data
)
71 return getauxval(data
->hwcap_type
) & data
->hwcap
;
74 static int stdio_read_integer(FILE *f
, const char *what
, int *val
)
79 ret
= fscanf(f
, "%d%*1[\n]%n", val
, &n
);
80 if (ret
< 1 || n
< 1) {
81 ksft_print_msg("failed to parse integer from %s\n", what
);
88 /* Start a new process and return the vector length it sees */
89 static int get_child_rdvl(struct vec_data
*data
)
98 ksft_print_msg("pipe() failed: %d (%s)\n",
99 errno
, strerror(errno
));
107 ksft_print_msg("fork() failed: %d (%s)\n",
108 errno
, strerror(errno
));
114 /* Child: put vector length on the pipe */
117 * Replace stdout with the pipe, errors to stderr from
118 * here as kselftest prints to stdout.
120 ret
= dup2(pipefd
[1], 1);
122 fprintf(stderr
, "dup2() %d\n", errno
);
126 /* exec() a new binary which puts the VL on stdout */
127 ret
= execl(data
->rdvl_binary
, data
->rdvl_binary
, NULL
);
128 fprintf(stderr
, "execl(%s) failed: %d (%s)\n",
129 data
->rdvl_binary
, errno
, strerror(errno
));
136 /* Parent; wait for the exit status from the child & verify it */
140 ksft_print_msg("wait() failed: %d (%s)\n",
141 errno
, strerror(errno
));
145 } while (pid
!= child
);
147 assert(pid
== child
);
149 if (!WIFEXITED(ret
)) {
150 ksft_print_msg("child exited abnormally\n");
155 if (WEXITSTATUS(ret
) != 0) {
156 ksft_print_msg("child returned error %d\n",
162 out
= fdopen(pipefd
[0], "r");
164 ksft_print_msg("failed to open child stdout\n");
169 ret
= stdio_read_integer(out
, "child", &read_vl
);
177 static int file_read_integer(const char *name
, int *val
)
182 f
= fopen(name
, "r");
184 ksft_test_result_fail("Unable to open %s: %d (%s)\n",
190 ret
= stdio_read_integer(f
, name
, val
);
196 static int file_write_integer(const char *name
, int val
)
200 f
= fopen(name
, "w");
202 ksft_test_result_fail("Unable to open %s: %d (%s)\n",
208 fprintf(f
, "%d", val
);
215 * Verify that we can read the default VL via proc, checking that it
216 * is set in a freshly spawned child.
218 static void proc_read_default(struct vec_data
*data
)
220 int default_vl
, child_vl
, ret
;
222 ret
= file_read_integer(data
->default_vl_file
, &default_vl
);
226 /* Is this the actual default seen by new processes? */
227 child_vl
= get_child_rdvl(data
);
228 if (child_vl
!= default_vl
) {
229 ksft_test_result_fail("%s is %d but child VL is %d\n",
230 data
->default_vl_file
,
231 default_vl
, child_vl
);
235 ksft_test_result_pass("%s default vector length %d\n", data
->name
,
237 data
->default_vl
= default_vl
;
240 /* Verify that we can write a minimum value and have it take effect */
241 static void proc_write_min(struct vec_data
*data
)
243 int ret
, new_default
, child_vl
;
245 if (geteuid() != 0) {
246 ksft_test_result_skip("Need to be root to write to /proc\n");
250 ret
= file_write_integer(data
->default_vl_file
, ARCH_MIN_VL
);
254 /* What was the new value? */
255 ret
= file_read_integer(data
->default_vl_file
, &new_default
);
259 /* Did it take effect in a new process? */
260 child_vl
= get_child_rdvl(data
);
261 if (child_vl
!= new_default
) {
262 ksft_test_result_fail("%s is %d but child VL is %d\n",
263 data
->default_vl_file
,
264 new_default
, child_vl
);
268 ksft_test_result_pass("%s minimum vector length %d\n", data
->name
,
270 data
->min_vl
= new_default
;
272 file_write_integer(data
->default_vl_file
, data
->default_vl
);
275 /* Verify that we can write a maximum value and have it take effect */
276 static void proc_write_max(struct vec_data
*data
)
278 int ret
, new_default
, child_vl
;
280 if (geteuid() != 0) {
281 ksft_test_result_skip("Need to be root to write to /proc\n");
285 /* -1 is accepted by the /proc interface as the maximum VL */
286 ret
= file_write_integer(data
->default_vl_file
, -1);
290 /* What was the new value? */
291 ret
= file_read_integer(data
->default_vl_file
, &new_default
);
295 /* Did it take effect in a new process? */
296 child_vl
= get_child_rdvl(data
);
297 if (child_vl
!= new_default
) {
298 ksft_test_result_fail("%s is %d but child VL is %d\n",
299 data
->default_vl_file
,
300 new_default
, child_vl
);
304 ksft_test_result_pass("%s maximum vector length %d\n", data
->name
,
306 data
->max_vl
= new_default
;
308 file_write_integer(data
->default_vl_file
, data
->default_vl
);
311 /* Can we read back a VL from prctl? */
312 static void prctl_get(struct vec_data
*data
)
316 ret
= prctl(data
->prctl_get
);
318 ksft_test_result_fail("%s prctl() read failed: %d (%s)\n",
319 data
->name
, errno
, strerror(errno
));
323 /* Mask out any flags */
324 ret
&= PR_SVE_VL_LEN_MASK
;
326 /* Is that what we can read back directly? */
327 if (ret
== data
->rdvl())
328 ksft_test_result_pass("%s current VL is %d\n",
331 ksft_test_result_fail("%s prctl() VL %d but RDVL is %d\n",
332 data
->name
, ret
, data
->rdvl());
335 /* Does the prctl let us set the VL we already have? */
336 static void prctl_set_same(struct vec_data
*data
)
338 int cur_vl
= data
->rdvl();
341 ret
= prctl(data
->prctl_set
, cur_vl
);
343 ksft_test_result_fail("%s prctl set failed: %d (%s)\n",
344 data
->name
, errno
, strerror(errno
));
348 ksft_test_result(cur_vl
== data
->rdvl(),
349 "%s set VL %d and have VL %d\n",
350 data
->name
, cur_vl
, data
->rdvl());
353 /* Can we set a new VL for this process? */
354 static void prctl_set(struct vec_data
*data
)
358 if (data
->min_vl
== data
->max_vl
) {
359 ksft_test_result_skip("%s only one VL supported\n",
364 /* Try to set the minimum VL */
365 ret
= prctl(data
->prctl_set
, data
->min_vl
);
367 ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n",
368 data
->name
, data
->min_vl
,
369 errno
, strerror(errno
));
373 if ((ret
& PR_SVE_VL_LEN_MASK
) != data
->min_vl
) {
374 ksft_test_result_fail("%s prctl set %d but return value is %d\n",
375 data
->name
, data
->min_vl
, data
->rdvl());
379 if (data
->rdvl() != data
->min_vl
) {
380 ksft_test_result_fail("%s set %d but RDVL is %d\n",
381 data
->name
, data
->min_vl
, data
->rdvl());
385 /* Try to set the maximum VL */
386 ret
= prctl(data
->prctl_set
, data
->max_vl
);
388 ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n",
389 data
->name
, data
->max_vl
,
390 errno
, strerror(errno
));
394 if ((ret
& PR_SVE_VL_LEN_MASK
) != data
->max_vl
) {
395 ksft_test_result_fail("%s prctl() set %d but return value is %d\n",
396 data
->name
, data
->max_vl
, data
->rdvl());
400 /* The _INHERIT flag should not be present when we read the VL */
401 ret
= prctl(data
->prctl_get
);
403 ksft_test_result_fail("%s prctl() read failed: %d (%s)\n",
404 data
->name
, errno
, strerror(errno
));
408 if (ret
& PR_SVE_VL_INHERIT
) {
409 ksft_test_result_fail("%s prctl() reports _INHERIT\n",
414 ksft_test_result_pass("%s prctl() set min/max\n", data
->name
);
417 /* If we didn't request it a new VL shouldn't affect the child */
418 static void prctl_set_no_child(struct vec_data
*data
)
422 if (data
->min_vl
== data
->max_vl
) {
423 ksft_test_result_skip("%s only one VL supported\n",
428 ret
= prctl(data
->prctl_set
, data
->min_vl
);
430 ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n",
431 data
->name
, data
->min_vl
,
432 errno
, strerror(errno
));
436 /* Ensure the default VL is different */
437 ret
= file_write_integer(data
->default_vl_file
, data
->max_vl
);
441 /* Check that the child has the default we just set */
442 child_vl
= get_child_rdvl(data
);
443 if (child_vl
!= data
->max_vl
) {
444 ksft_test_result_fail("%s is %d but child VL is %d\n",
445 data
->default_vl_file
,
446 data
->max_vl
, child_vl
);
450 ksft_test_result_pass("%s vector length used default\n", data
->name
);
452 file_write_integer(data
->default_vl_file
, data
->default_vl
);
455 /* If we didn't request it a new VL shouldn't affect the child */
456 static void prctl_set_for_child(struct vec_data
*data
)
460 if (data
->min_vl
== data
->max_vl
) {
461 ksft_test_result_skip("%s only one VL supported\n",
466 ret
= prctl(data
->prctl_set
, data
->min_vl
| PR_SVE_VL_INHERIT
);
468 ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n",
469 data
->name
, data
->min_vl
,
470 errno
, strerror(errno
));
474 /* The _INHERIT flag should be present when we read the VL */
475 ret
= prctl(data
->prctl_get
);
477 ksft_test_result_fail("%s prctl() read failed: %d (%s)\n",
478 data
->name
, errno
, strerror(errno
));
481 if (!(ret
& PR_SVE_VL_INHERIT
)) {
482 ksft_test_result_fail("%s prctl() does not report _INHERIT\n",
487 /* Ensure the default VL is different */
488 ret
= file_write_integer(data
->default_vl_file
, data
->max_vl
);
492 /* Check that the child inherited our VL */
493 child_vl
= get_child_rdvl(data
);
494 if (child_vl
!= data
->min_vl
) {
495 ksft_test_result_fail("%s is %d but child VL is %d\n",
496 data
->default_vl_file
,
497 data
->min_vl
, child_vl
);
501 ksft_test_result_pass("%s vector length was inherited\n", data
->name
);
503 file_write_integer(data
->default_vl_file
, data
->default_vl
);
506 /* _ONEXEC takes effect only in the child process */
507 static void prctl_set_onexec(struct vec_data
*data
)
511 if (data
->min_vl
== data
->max_vl
) {
512 ksft_test_result_skip("%s only one VL supported\n",
517 /* Set a known value for the default and our current VL */
518 ret
= file_write_integer(data
->default_vl_file
, data
->max_vl
);
522 ret
= prctl(data
->prctl_set
, data
->max_vl
);
524 ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n",
525 data
->name
, data
->min_vl
,
526 errno
, strerror(errno
));
530 /* Set a different value for the child to have on exec */
531 ret
= prctl(data
->prctl_set
, data
->min_vl
| PR_SVE_SET_VL_ONEXEC
);
533 ksft_test_result_fail("%s prctl set failed for %d: %d (%s)\n",
534 data
->name
, data
->min_vl
,
535 errno
, strerror(errno
));
539 /* Our current VL should stay the same */
540 if (data
->rdvl() != data
->max_vl
) {
541 ksft_test_result_fail("%s VL changed by _ONEXEC prctl()\n",
546 /* Check that the child inherited our VL */
547 child_vl
= get_child_rdvl(data
);
548 if (child_vl
!= data
->min_vl
) {
549 ksft_test_result_fail("Set %d _ONEXEC but child VL is %d\n",
550 data
->min_vl
, child_vl
);
554 ksft_test_result_pass("%s vector length set on exec\n", data
->name
);
556 file_write_integer(data
->default_vl_file
, data
->default_vl
);
559 /* For each VQ verify that setting via prctl() does the right thing */
560 static void prctl_set_all_vqs(struct vec_data
*data
)
562 int ret
, vq
, vl
, new_vl
, i
;
563 int orig_vls
[ARRAY_SIZE(vec_data
)];
566 if (!data
->min_vl
|| !data
->max_vl
) {
567 ksft_test_result_skip("%s Failed to enumerate VLs, not testing VL setting\n",
572 for (i
= 0; i
< ARRAY_SIZE(vec_data
); i
++) {
573 if (!vec_type_supported(&vec_data
[i
]))
575 orig_vls
[i
] = vec_data
[i
].rdvl();
578 for (vq
= SVE_VQ_MIN
; vq
<= SVE_VQ_MAX
; vq
++) {
579 vl
= sve_vl_from_vq(vq
);
581 /* Attempt to set the VL */
582 ret
= prctl(data
->prctl_set
, vl
);
585 ksft_print_msg("%s prctl set failed for %d: %d (%s)\n",
587 errno
, strerror(errno
));
591 new_vl
= ret
& PR_SVE_VL_LEN_MASK
;
593 /* Check that we actually have the reported new VL */
594 if (data
->rdvl() != new_vl
) {
595 ksft_print_msg("Set %s VL %d but RDVL reports %d\n",
596 data
->name
, new_vl
, data
->rdvl());
600 /* Did any other VLs change? */
601 for (i
= 0; i
< ARRAY_SIZE(vec_data
); i
++) {
602 if (&vec_data
[i
] == data
)
605 if (!vec_type_supported(&vec_data
[i
]))
608 if (vec_data
[i
].rdvl() != orig_vls
[i
]) {
609 ksft_print_msg("%s VL changed from %d to %d\n",
610 vec_data
[i
].name
, orig_vls
[i
],
616 /* Was that the VL we asked for? */
620 /* Should round up to the minimum VL if below it */
621 if (vl
< data
->min_vl
) {
622 if (new_vl
!= data
->min_vl
) {
623 ksft_print_msg("%s VL %d returned %d not minimum %d\n",
624 data
->name
, vl
, new_vl
,
632 /* Should round down to maximum VL if above it */
633 if (vl
> data
->max_vl
) {
634 if (new_vl
!= data
->max_vl
) {
635 ksft_print_msg("%s VL %d returned %d not maximum %d\n",
636 data
->name
, vl
, new_vl
,
644 /* Otherwise we should've rounded down */
645 if (!(new_vl
< vl
)) {
646 ksft_print_msg("%s VL %d returned %d, did not round down\n",
647 data
->name
, vl
, new_vl
);
654 ksft_test_result(errors
== 0, "%s prctl() set all VLs, %d errors\n",
658 typedef void (*test_type
)(struct vec_data
*);
660 static const test_type tests
[] = {
662 * The default/min/max tests must be first and in this order
663 * to provide data for other tests.
678 static inline void smstart(void)
680 asm volatile("msr S0_3_C4_C7_3, xzr");
683 static inline void smstart_sm(void)
685 asm volatile("msr S0_3_C4_C3_3, xzr");
688 static inline void smstop(void)
690 asm volatile("msr S0_3_C4_C6_3, xzr");
695 * Verify we can change the SVE vector length while SME is active and
696 * continue to use SME afterwards.
698 static void change_sve_with_za(void)
700 struct vec_data
*sve_data
= &vec_data
[VEC_SVE
];
704 if (sve_data
->min_vl
== sve_data
->max_vl
) {
705 ksft_print_msg("Only one SVE VL supported, can't change\n");
706 ksft_test_result_skip("change_sve_while_sme\n");
710 /* Ensure we will trigger a change when we set the maximum */
711 ret
= prctl(sve_data
->prctl_set
, sve_data
->min_vl
);
712 if (ret
!= sve_data
->min_vl
) {
713 ksft_print_msg("Failed to set SVE VL %d: %d\n",
714 sve_data
->min_vl
, ret
);
718 /* Enable SM and ZA */
721 /* Trigger another VL change */
722 ret
= prctl(sve_data
->prctl_set
, sve_data
->max_vl
);
723 if (ret
!= sve_data
->max_vl
) {
724 ksft_print_msg("Failed to set SVE VL %d: %d\n",
725 sve_data
->max_vl
, ret
);
730 * Spin for a bit with SM enabled to try to trigger another
731 * save/restore. We can't use syscalls without exiting
734 for (i
= 0; i
< 100000000; i
++)
738 * TODO: Verify that ZA was preserved over the VL change and
742 /* Clean up after ourselves */
744 ret
= prctl(sve_data
->prctl_set
, sve_data
->default_vl
);
745 if (ret
!= sve_data
->default_vl
) {
746 ksft_print_msg("Failed to restore SVE VL %d: %d\n",
747 sve_data
->default_vl
, ret
);
751 ksft_test_result(pass
, "change_sve_with_za\n");
754 typedef void (*test_all_type
)(void);
756 static const struct {
759 } all_types_tests
[] = {
760 { "change_sve_with_za", change_sve_with_za
},
765 bool all_supported
= true;
769 ksft_set_plan(ARRAY_SIZE(tests
) * ARRAY_SIZE(vec_data
) +
770 ARRAY_SIZE(all_types_tests
));
772 for (i
= 0; i
< ARRAY_SIZE(vec_data
); i
++) {
773 struct vec_data
*data
= &vec_data
[i
];
774 unsigned long supported
;
776 supported
= vec_type_supported(data
);
778 all_supported
= false;
780 for (j
= 0; j
< ARRAY_SIZE(tests
); j
++) {
784 ksft_test_result_skip("%s not supported\n",
789 for (i
= 0; i
< ARRAY_SIZE(all_types_tests
); i
++) {
791 all_types_tests
[i
].test();
793 ksft_test_result_skip("%s\n", all_types_tests
[i
].name
);