xref: /linux/tools/testing/selftests/arm64/fp/fp-ptrace.c (revision 303bff3637d13f0ecbb280c7cb403470c440a2a6)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2023 ARM Limited.
4  * Original author: Mark Brown <broonie@kernel.org>
5  */
6 
7 #define _GNU_SOURCE
8 
9 #include <errno.h>
10 #include <stdbool.h>
11 #include <stddef.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <unistd.h>
16 
17 #include <sys/auxv.h>
18 #include <sys/prctl.h>
19 #include <sys/ptrace.h>
20 #include <sys/types.h>
21 #include <sys/uio.h>
22 #include <sys/wait.h>
23 
24 #include <linux/kernel.h>
25 
26 #include <asm/sigcontext.h>
27 #include <asm/sve_context.h>
28 #include <asm/ptrace.h>
29 
30 #include "kselftest.h"
31 
32 #include "fp-ptrace.h"
33 
34 #include <linux/bits.h>
35 
36 #define FPMR_LSCALE2_MASK                               GENMASK(37, 32)
37 #define FPMR_NSCALE_MASK                                GENMASK(31, 24)
38 #define FPMR_LSCALE_MASK                                GENMASK(22, 16)
39 #define FPMR_OSC_MASK                                   GENMASK(15, 15)
40 #define FPMR_OSM_MASK                                   GENMASK(14, 14)
41 
42 /* <linux/elf.h> and <sys/auxv.h> don't like each other, so: */
43 #ifndef NT_ARM_SVE
44 #define NT_ARM_SVE 0x405
45 #endif
46 
47 #ifndef NT_ARM_SSVE
48 #define NT_ARM_SSVE 0x40b
49 #endif
50 
51 #ifndef NT_ARM_ZA
52 #define NT_ARM_ZA 0x40c
53 #endif
54 
55 #ifndef NT_ARM_ZT
56 #define NT_ARM_ZT 0x40d
57 #endif
58 
59 #ifndef NT_ARM_FPMR
60 #define NT_ARM_FPMR 0x40e
61 #endif
62 
63 #define ARCH_VQ_MAX 256
64 
65 /* VL 128..2048 in powers of 2 */
66 #define MAX_NUM_VLS 5
67 
68 /* Sentinel for detecting buffer bytes the kernel did not write */
69 #define REGSET_SENTINEL 0xa5
70 
71 /*
72  * FPMR bits we can set without doing feature checks to see if values
73  * are valid.
74  */
75 #define FPMR_SAFE_BITS (FPMR_LSCALE2_MASK | FPMR_NSCALE_MASK | \
76 			FPMR_LSCALE_MASK | FPMR_OSC_MASK | FPMR_OSM_MASK)
77 
78 #define NUM_FPR 32
79 __uint128_t v_in[NUM_FPR];
80 __uint128_t v_expected[NUM_FPR];
81 __uint128_t v_out[NUM_FPR];
82 
83 char z_in[__SVE_ZREGS_SIZE(ARCH_VQ_MAX)];
84 char z_expected[__SVE_ZREGS_SIZE(ARCH_VQ_MAX)];
85 char z_out[__SVE_ZREGS_SIZE(ARCH_VQ_MAX)];
86 
87 char p_in[__SVE_PREGS_SIZE(ARCH_VQ_MAX)];
88 char p_expected[__SVE_PREGS_SIZE(ARCH_VQ_MAX)];
89 char p_out[__SVE_PREGS_SIZE(ARCH_VQ_MAX)];
90 
91 char ffr_in[__SVE_PREG_SIZE(ARCH_VQ_MAX)];
92 char ffr_expected[__SVE_PREG_SIZE(ARCH_VQ_MAX)];
93 char ffr_out[__SVE_PREG_SIZE(ARCH_VQ_MAX)];
94 
95 char za_in[ZA_SIG_REGS_SIZE(ARCH_VQ_MAX)];
96 char za_expected[ZA_SIG_REGS_SIZE(ARCH_VQ_MAX)];
97 char za_out[ZA_SIG_REGS_SIZE(ARCH_VQ_MAX)];
98 
99 char zt_in[ZT_SIG_REG_BYTES];
100 char zt_expected[ZT_SIG_REG_BYTES];
101 char zt_out[ZT_SIG_REG_BYTES];
102 
103 uint64_t fpmr_in, fpmr_expected, fpmr_out;
104 
105 uint64_t sve_vl_out;
106 uint64_t sme_vl_out;
107 uint64_t svcr_in, svcr_expected, svcr_out;
108 
109 void load_and_save(int flags);
110 
111 static bool got_alarm;
112 
113 static void handle_alarm(int sig, siginfo_t *info, void *context)
114 {
115 	got_alarm = true;
116 }
117 
118 static bool sve_supported(void)
119 {
120 	return getauxval(AT_HWCAP) & HWCAP_SVE;
121 }
122 
123 static bool sme_supported(void)
124 {
125 	return getauxval(AT_HWCAP2) & HWCAP2_SME;
126 }
127 
128 static bool sme2_supported(void)
129 {
130 	return getauxval(AT_HWCAP2) & HWCAP2_SME2;
131 }
132 
133 static bool fa64_supported(void)
134 {
135 	return getauxval(AT_HWCAP2) & HWCAP2_SME_FA64;
136 }
137 
138 static bool fpmr_supported(void)
139 {
140 	return getauxval(AT_HWCAP2) & HWCAP2_FPMR;
141 }
142 
143 static bool compare_buffer(const char *name, void *out,
144 			   void *expected, size_t size)
145 {
146 	void *tmp;
147 
148 	if (memcmp(out, expected, size) == 0)
149 		return true;
150 
151 	ksft_print_msg("Mismatch in %s\n", name);
152 
153 	/* Did we just get zeros back? */
154 	tmp = malloc(size);
155 	if (!tmp) {
156 		ksft_print_msg("OOM allocating %lu bytes for %s\n",
157 			       size, name);
158 		ksft_exit_fail();
159 	}
160 	memset(tmp, 0, size);
161 
162 	if (memcmp(out, tmp, size) == 0)
163 		ksft_print_msg("%s is zero\n", name);
164 
165 	free(tmp);
166 
167 	return false;
168 }
169 
170 static bool buffer_is_filled(const void *buffer, size_t size,
171 			     unsigned char value)
172 {
173 	const unsigned char *bytes = buffer;
174 	size_t i;
175 
176 	for (i = 0; i < size; i++) {
177 		if (bytes[i] != value)
178 			return false;
179 	}
180 
181 	return true;
182 }
183 
184 struct test_config {
185 	int sve_vl_in;
186 	int sve_vl_expected;
187 	int sme_vl_in;
188 	int sme_vl_expected;
189 	int svcr_in;
190 	int svcr_expected;
191 };
192 
193 struct test_definition {
194 	const char *name;
195 	bool sve_vl_change;
196 	bool (*supported)(struct test_config *config);
197 	void (*set_expected_values)(struct test_config *config);
198 	void (*modify_values)(pid_t child, struct test_config *test_config);
199 };
200 
201 static int vl_in(struct test_config *config)
202 {
203 	int vl;
204 
205 	if (config->svcr_in & SVCR_SM)
206 		vl = config->sme_vl_in;
207 	else
208 		vl = config->sve_vl_in;
209 
210 	return vl;
211 }
212 
213 static int vl_expected(struct test_config *config)
214 {
215 	int vl;
216 
217 	if (config->svcr_expected & SVCR_SM)
218 		vl = config->sme_vl_expected;
219 	else
220 		vl = config->sve_vl_expected;
221 
222 	return vl;
223 }
224 
225 static void run_child(struct test_config *config)
226 {
227 	int ret, flags;
228 
229 	/* Let the parent attach to us */
230 	ret = ptrace(PTRACE_TRACEME, 0, 0, 0);
231 	if (ret < 0)
232 		ksft_exit_fail_msg("PTRACE_TRACEME failed: %s (%d)\n",
233 				   strerror(errno), errno);
234 
235 	/* VL setup */
236 	if (sve_supported()) {
237 		ret = prctl(PR_SVE_SET_VL, config->sve_vl_in);
238 		if (ret != config->sve_vl_in) {
239 			ksft_print_msg("Failed to set SVE VL %d: %d\n",
240 				       config->sve_vl_in, ret);
241 		}
242 	}
243 
244 	if (sme_supported()) {
245 		ret = prctl(PR_SME_SET_VL, config->sme_vl_in);
246 		if (ret != config->sme_vl_in) {
247 			ksft_print_msg("Failed to set SME VL %d: %d\n",
248 				       config->sme_vl_in, ret);
249 		}
250 	}
251 
252 	/* Load values and wait for the parent */
253 	flags = 0;
254 	if (sve_supported())
255 		flags |= HAVE_SVE;
256 	if (sme_supported())
257 		flags |= HAVE_SME;
258 	if (sme2_supported())
259 		flags |= HAVE_SME2;
260 	if (fa64_supported())
261 		flags |= HAVE_FA64;
262 	if (fpmr_supported())
263 		flags |= HAVE_FPMR;
264 
265 	load_and_save(flags);
266 
267 	exit(0);
268 }
269 
270 static void read_one_child_regs(pid_t child, char *name,
271 				struct iovec *iov_parent,
272 				struct iovec *iov_child)
273 {
274 	int len = iov_parent->iov_len;
275 	int ret;
276 
277 	ret = process_vm_readv(child, iov_parent, 1, iov_child, 1, 0);
278 	if (ret == -1)
279 		ksft_print_msg("%s read failed: %s (%d)\n",
280 			       name, strerror(errno), errno);
281 	else if (ret != len)
282 		ksft_print_msg("Short read of %s: %d\n", name, ret);
283 }
284 
285 static void read_child_regs(pid_t child)
286 {
287 	struct iovec iov_parent, iov_child;
288 
289 	/*
290 	 * Since the child fork()ed from us the buffer addresses are
291 	 * the same in parent and child.
292 	 */
293 	iov_parent.iov_base = &v_out;
294 	iov_parent.iov_len = sizeof(v_out);
295 	iov_child.iov_base = &v_out;
296 	iov_child.iov_len = sizeof(v_out);
297 	read_one_child_regs(child, "FPSIMD", &iov_parent, &iov_child);
298 
299 	if (sve_supported() || sme_supported()) {
300 		iov_parent.iov_base = &sve_vl_out;
301 		iov_parent.iov_len = sizeof(sve_vl_out);
302 		iov_child.iov_base = &sve_vl_out;
303 		iov_child.iov_len = sizeof(sve_vl_out);
304 		read_one_child_regs(child, "SVE VL", &iov_parent, &iov_child);
305 
306 		iov_parent.iov_base = &z_out;
307 		iov_parent.iov_len = sizeof(z_out);
308 		iov_child.iov_base = &z_out;
309 		iov_child.iov_len = sizeof(z_out);
310 		read_one_child_regs(child, "Z", &iov_parent, &iov_child);
311 
312 		iov_parent.iov_base = &p_out;
313 		iov_parent.iov_len = sizeof(p_out);
314 		iov_child.iov_base = &p_out;
315 		iov_child.iov_len = sizeof(p_out);
316 		read_one_child_regs(child, "P", &iov_parent, &iov_child);
317 
318 		iov_parent.iov_base = &ffr_out;
319 		iov_parent.iov_len = sizeof(ffr_out);
320 		iov_child.iov_base = &ffr_out;
321 		iov_child.iov_len = sizeof(ffr_out);
322 		read_one_child_regs(child, "FFR", &iov_parent, &iov_child);
323 	}
324 
325 	if (sme_supported()) {
326 		iov_parent.iov_base = &sme_vl_out;
327 		iov_parent.iov_len = sizeof(sme_vl_out);
328 		iov_child.iov_base = &sme_vl_out;
329 		iov_child.iov_len = sizeof(sme_vl_out);
330 		read_one_child_regs(child, "SME VL", &iov_parent, &iov_child);
331 
332 		iov_parent.iov_base = &svcr_out;
333 		iov_parent.iov_len = sizeof(svcr_out);
334 		iov_child.iov_base = &svcr_out;
335 		iov_child.iov_len = sizeof(svcr_out);
336 		read_one_child_regs(child, "SVCR", &iov_parent, &iov_child);
337 
338 		iov_parent.iov_base = &za_out;
339 		iov_parent.iov_len = sizeof(za_out);
340 		iov_child.iov_base = &za_out;
341 		iov_child.iov_len = sizeof(za_out);
342 		read_one_child_regs(child, "ZA", &iov_parent, &iov_child);
343 	}
344 
345 	if (sme2_supported()) {
346 		iov_parent.iov_base = &zt_out;
347 		iov_parent.iov_len = sizeof(zt_out);
348 		iov_child.iov_base = &zt_out;
349 		iov_child.iov_len = sizeof(zt_out);
350 		read_one_child_regs(child, "ZT", &iov_parent, &iov_child);
351 	}
352 
353 	if (fpmr_supported()) {
354 		iov_parent.iov_base = &fpmr_out;
355 		iov_parent.iov_len = sizeof(fpmr_out);
356 		iov_child.iov_base = &fpmr_out;
357 		iov_child.iov_len = sizeof(fpmr_out);
358 		read_one_child_regs(child, "FPMR", &iov_parent, &iov_child);
359 	}
360 }
361 
362 static bool continue_breakpoint(pid_t child,
363 				enum __ptrace_request restart_type)
364 {
365 	struct user_pt_regs pt_regs;
366 	struct iovec iov;
367 	int ret;
368 
369 	/* Get PC */
370 	iov.iov_base = &pt_regs;
371 	iov.iov_len = sizeof(pt_regs);
372 	ret = ptrace(PTRACE_GETREGSET, child, NT_PRSTATUS, &iov);
373 	if (ret < 0) {
374 		ksft_print_msg("Failed to get PC: %s (%d)\n",
375 			       strerror(errno), errno);
376 		return false;
377 	}
378 
379 	/* Skip over the BRK */
380 	pt_regs.pc += 4;
381 	ret = ptrace(PTRACE_SETREGSET, child, NT_PRSTATUS, &iov);
382 	if (ret < 0) {
383 		ksft_print_msg("Failed to skip BRK: %s (%d)\n",
384 			       strerror(errno), errno);
385 		return false;
386 	}
387 
388 	/* Restart */
389 	ret = ptrace(restart_type, child, 0, 0);
390 	if (ret < 0) {
391 		ksft_print_msg("Failed to restart child: %s (%d)\n",
392 			       strerror(errno), errno);
393 		return false;
394 	}
395 
396 	return true;
397 }
398 
399 static bool check_ptrace_values_sve(pid_t child, struct test_config *config)
400 {
401 	struct user_sve_header *sve;
402 	struct user_fpsimd_state *fpsimd;
403 	struct iovec iov;
404 	size_t buf_size;
405 	int ret, vq;
406 	bool pass = true;
407 
408 	if (!sve_supported())
409 		return true;
410 
411 	vq = __sve_vq_from_vl(config->sve_vl_in);
412 
413 	buf_size = SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, SVE_PT_REGS_SVE);
414 	iov.iov_len = buf_size;
415 	iov.iov_base = malloc(buf_size);
416 	if (!iov.iov_base) {
417 		ksft_print_msg("OOM allocating %lu byte SVE buffer\n",
418 			       iov.iov_len);
419 		return false;
420 	}
421 
422 	memset(iov.iov_base, REGSET_SENTINEL, buf_size);
423 	ret = ptrace(PTRACE_GETREGSET, child, NT_ARM_SVE, &iov);
424 	if (ret != 0) {
425 		ksft_print_msg("Failed to read initial SVE: %s (%d)\n",
426 			       strerror(errno), errno);
427 		pass = false;
428 		goto out;
429 	}
430 
431 	sve = iov.iov_base;
432 
433 	if (sve->vl != config->sve_vl_in) {
434 		ksft_print_msg("Mismatch in initial SVE VL: %d != %d\n",
435 			       sve->vl, config->sve_vl_in);
436 		pass = false;
437 	}
438 
439 	/* If we are in streaming mode we should just read FPSIMD */
440 	if ((config->svcr_in & SVCR_SM) && (sve->flags & SVE_PT_REGS_SVE)) {
441 		ksft_print_msg("NT_ARM_SVE reports SVE with PSTATE.SM\n");
442 		pass = false;
443 	}
444 
445 	if (svcr_in & SVCR_SM) {
446 		if (sve->size != sizeof(*sve)) {
447 			ksft_print_msg("NT_ARM_SVE reports data with PSTATE.SM\n");
448 			pass = false;
449 		}
450 		if (!buffer_is_filled(iov.iov_base + sizeof(*sve),
451 				      buf_size - sizeof(*sve), REGSET_SENTINEL)) {
452 			ksft_print_msg("NT_ARM_SVE wrote beyond its header with PSTATE.SM\n");
453 			pass = false;
454 		}
455 		goto out;
456 	} else {
457 		if (sve->size != SVE_PT_SIZE(vq, sve->flags)) {
458 			ksft_print_msg("Mismatch in SVE header size: %d != %lu\n",
459 				       sve->size, SVE_PT_SIZE(vq, sve->flags));
460 			pass = false;
461 		}
462 	}
463 
464 	/* The registers might be in completely different formats! */
465 	if (sve->flags & SVE_PT_REGS_SVE) {
466 		if (!compare_buffer("initial SVE Z",
467 				    iov.iov_base + SVE_PT_SVE_ZREG_OFFSET(vq, 0),
468 				    z_in, SVE_PT_SVE_ZREGS_SIZE(vq)))
469 			pass = false;
470 
471 		if (!compare_buffer("initial SVE P",
472 				    iov.iov_base + SVE_PT_SVE_PREG_OFFSET(vq, 0),
473 				    p_in, SVE_PT_SVE_PREGS_SIZE(vq)))
474 			pass = false;
475 
476 		if (!compare_buffer("initial SVE FFR",
477 				    iov.iov_base + SVE_PT_SVE_FFR_OFFSET(vq),
478 				    ffr_in, SVE_PT_SVE_PREG_SIZE(vq)))
479 			pass = false;
480 	} else {
481 		fpsimd = iov.iov_base + SVE_PT_FPSIMD_OFFSET;
482 		if (!compare_buffer("initial V via SVE", &fpsimd->vregs[0],
483 				    v_in, sizeof(v_in)))
484 			pass = false;
485 	}
486 
487 out:
488 	free(iov.iov_base);
489 	return pass;
490 }
491 
492 static bool check_ptrace_values_ssve(pid_t child, struct test_config *config)
493 {
494 	struct user_sve_header *sve;
495 	struct user_fpsimd_state *fpsimd;
496 	struct iovec iov;
497 	size_t buf_size;
498 	int ret, vq;
499 	bool pass = true;
500 
501 	if (!sme_supported())
502 		return true;
503 
504 	vq = __sve_vq_from_vl(config->sme_vl_in);
505 
506 	buf_size = SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, SVE_PT_REGS_SVE);
507 	iov.iov_len = buf_size;
508 	iov.iov_base = malloc(buf_size);
509 	if (!iov.iov_base) {
510 		ksft_print_msg("OOM allocating %lu byte SSVE buffer\n",
511 			       iov.iov_len);
512 		return false;
513 	}
514 
515 	memset(iov.iov_base, REGSET_SENTINEL, buf_size);
516 	ret = ptrace(PTRACE_GETREGSET, child, NT_ARM_SSVE, &iov);
517 	if (ret != 0) {
518 		ksft_print_msg("Failed to read initial SSVE: %s (%d)\n",
519 			       strerror(errno), errno);
520 		pass = false;
521 		goto out;
522 	}
523 
524 	sve = iov.iov_base;
525 
526 	if (sve->vl != config->sme_vl_in) {
527 		ksft_print_msg("Mismatch in initial SSVE VL: %d != %d\n",
528 			       sve->vl, config->sme_vl_in);
529 		pass = false;
530 	}
531 
532 	if ((config->svcr_in & SVCR_SM) && !(sve->flags & SVE_PT_REGS_SVE)) {
533 		ksft_print_msg("NT_ARM_SSVE reports FPSIMD with PSTATE.SM\n");
534 		pass = false;
535 	}
536 
537 	if (!(svcr_in & SVCR_SM)) {
538 		if (sve->size != sizeof(*sve)) {
539 			ksft_print_msg("NT_ARM_SSVE reports data without PSTATE.SM\n");
540 			pass = false;
541 		}
542 		if (!buffer_is_filled(iov.iov_base + sizeof(*sve),
543 				      buf_size - sizeof(*sve), REGSET_SENTINEL)) {
544 			ksft_print_msg("NT_ARM_SSVE wrote beyond its header without PSTATE.SM\n");
545 			pass = false;
546 		}
547 		goto out;
548 	} else {
549 		if (sve->size != SVE_PT_SIZE(vq, sve->flags)) {
550 			ksft_print_msg("Mismatch in SSVE header size: %d != %lu\n",
551 				       sve->size, SVE_PT_SIZE(vq, sve->flags));
552 			pass = false;
553 		}
554 	}
555 
556 	/* The registers might be in completely different formats! */
557 	if (sve->flags & SVE_PT_REGS_SVE) {
558 		if (!compare_buffer("initial SSVE Z",
559 				    iov.iov_base + SVE_PT_SVE_ZREG_OFFSET(vq, 0),
560 				    z_in, SVE_PT_SVE_ZREGS_SIZE(vq)))
561 			pass = false;
562 
563 		if (!compare_buffer("initial SSVE P",
564 				    iov.iov_base + SVE_PT_SVE_PREG_OFFSET(vq, 0),
565 				    p_in, SVE_PT_SVE_PREGS_SIZE(vq)))
566 			pass = false;
567 
568 		if (!compare_buffer("initial SSVE FFR",
569 				    iov.iov_base + SVE_PT_SVE_FFR_OFFSET(vq),
570 				    ffr_in, SVE_PT_SVE_PREG_SIZE(vq)))
571 			pass = false;
572 	} else {
573 		fpsimd = iov.iov_base + SVE_PT_FPSIMD_OFFSET;
574 		if (!compare_buffer("initial V via SSVE",
575 				    &fpsimd->vregs[0], v_in, sizeof(v_in)))
576 			pass = false;
577 	}
578 
579 out:
580 	free(iov.iov_base);
581 	return pass;
582 }
583 
584 static bool check_ptrace_values_za(pid_t child, struct test_config *config)
585 {
586 	struct user_za_header *za;
587 	struct iovec iov;
588 	int ret, vq;
589 	bool pass = true;
590 
591 	if (!sme_supported())
592 		return true;
593 
594 	vq = __sve_vq_from_vl(config->sme_vl_in);
595 
596 	iov.iov_len = ZA_SIG_CONTEXT_SIZE(vq);
597 	iov.iov_base = malloc(iov.iov_len);
598 	if (!iov.iov_base) {
599 		ksft_print_msg("OOM allocating %lu byte ZA buffer\n",
600 			       iov.iov_len);
601 		return false;
602 	}
603 
604 	ret = ptrace(PTRACE_GETREGSET, child, NT_ARM_ZA, &iov);
605 	if (ret != 0) {
606 		ksft_print_msg("Failed to read initial ZA: %s (%d)\n",
607 			       strerror(errno), errno);
608 		pass = false;
609 		goto out;
610 	}
611 
612 	za = iov.iov_base;
613 
614 	if (za->vl != config->sme_vl_in) {
615 		ksft_print_msg("Mismatch in initial SME VL: %d != %d\n",
616 			       za->vl, config->sme_vl_in);
617 		pass = false;
618 	}
619 
620 	/* If PSTATE.ZA is not set we should just read the header */
621 	if (config->svcr_in & SVCR_ZA) {
622 		if (za->size != ZA_PT_SIZE(vq)) {
623 			ksft_print_msg("Unexpected ZA ptrace read size: %d != %lu\n",
624 				       za->size, ZA_PT_SIZE(vq));
625 			pass = false;
626 		}
627 
628 		if (!compare_buffer("initial ZA",
629 				    iov.iov_base + ZA_PT_ZA_OFFSET,
630 				    za_in, ZA_PT_ZA_SIZE(vq)))
631 			pass = false;
632 	} else {
633 		if (za->size != sizeof(*za)) {
634 			ksft_print_msg("Unexpected ZA ptrace read size: %d != %lu\n",
635 				       za->size, sizeof(*za));
636 			pass = false;
637 		}
638 	}
639 
640 out:
641 	free(iov.iov_base);
642 	return pass;
643 }
644 
645 static bool check_ptrace_values_zt(pid_t child, struct test_config *config)
646 {
647 	uint8_t buf[512];
648 	struct iovec iov;
649 	int ret;
650 
651 	if (!sme2_supported())
652 		return true;
653 
654 	iov.iov_base = &buf;
655 	iov.iov_len = ZT_SIG_REG_BYTES;
656 	ret = ptrace(PTRACE_GETREGSET, child, NT_ARM_ZT, &iov);
657 	if (ret != 0) {
658 		ksft_print_msg("Failed to read initial ZT: %s (%d)\n",
659 			       strerror(errno), errno);
660 		return false;
661 	}
662 
663 	return compare_buffer("initial ZT", buf, zt_in, ZT_SIG_REG_BYTES);
664 }
665 
666 static bool check_ptrace_values_fpmr(pid_t child, struct test_config *config)
667 {
668 	uint64_t val;
669 	struct iovec iov;
670 	int ret;
671 
672 	if (!fpmr_supported())
673 		return true;
674 
675 	iov.iov_base = &val;
676 	iov.iov_len = sizeof(val);
677 	ret = ptrace(PTRACE_GETREGSET, child, NT_ARM_FPMR, &iov);
678 	if (ret != 0) {
679 		ksft_print_msg("Failed to read initial FPMR: %s (%d)\n",
680 			       strerror(errno), errno);
681 		return false;
682 	}
683 
684 	return compare_buffer("initial FPMR", &val, &fpmr_in, sizeof(val));
685 }
686 
687 static bool check_ptrace_values(pid_t child, struct test_config *config)
688 {
689 	bool pass = true;
690 	struct user_fpsimd_state fpsimd;
691 	struct iovec iov;
692 	int ret;
693 
694 	iov.iov_base = &fpsimd;
695 	iov.iov_len = sizeof(fpsimd);
696 	ret = ptrace(PTRACE_GETREGSET, child, NT_PRFPREG, &iov);
697 	if (ret == 0) {
698 		if (!compare_buffer("initial V", &fpsimd.vregs, v_in,
699 				    sizeof(v_in))) {
700 			pass = false;
701 		}
702 	} else {
703 		ksft_print_msg("Failed to read initial V: %s (%d)\n",
704 			       strerror(errno), errno);
705 		pass = false;
706 	}
707 
708 	if (!check_ptrace_values_sve(child, config))
709 		pass = false;
710 
711 	if (!check_ptrace_values_ssve(child, config))
712 		pass = false;
713 
714 	if (!check_ptrace_values_za(child, config))
715 		pass = false;
716 
717 	if (!check_ptrace_values_zt(child, config))
718 		pass = false;
719 
720 	if (!check_ptrace_values_fpmr(child, config))
721 		pass = false;
722 
723 	return pass;
724 }
725 
726 static bool run_parent(pid_t child, struct test_definition *test,
727 		       struct test_config *config)
728 {
729 	int wait_status, ret;
730 	pid_t pid;
731 	bool pass;
732 
733 	/* Initial attach */
734 	while (1) {
735 		pid = waitpid(child, &wait_status, 0);
736 		if (pid < 0) {
737 			if (errno == EINTR)
738 				continue;
739 			ksft_exit_fail_msg("waitpid() failed: %s (%d)\n",
740 					   strerror(errno), errno);
741 		}
742 
743 		if (pid == child)
744 			break;
745 	}
746 
747 	if (WIFEXITED(wait_status)) {
748 		ksft_print_msg("Child exited loading values with status %d\n",
749 			       WEXITSTATUS(wait_status));
750 		pass = false;
751 		goto out;
752 	}
753 
754 	if (WIFSIGNALED(wait_status)) {
755 		ksft_print_msg("Child died from signal %d loading values\n",
756 			       WTERMSIG(wait_status));
757 		pass = false;
758 		goto out;
759 	}
760 
761 	/* Read initial values via ptrace */
762 	pass = check_ptrace_values(child, config);
763 
764 	/* Do whatever writes we want to do */
765 	if (test->modify_values)
766 		test->modify_values(child, config);
767 
768 	if (!continue_breakpoint(child, PTRACE_CONT))
769 		goto cleanup;
770 
771 	while (1) {
772 		pid = waitpid(child, &wait_status, 0);
773 		if (pid < 0) {
774 			if (errno == EINTR)
775 				continue;
776 			ksft_exit_fail_msg("waitpid() failed: %s (%d)\n",
777 					   strerror(errno), errno);
778 		}
779 
780 		if (pid == child)
781 			break;
782 	}
783 
784 	if (WIFEXITED(wait_status)) {
785 		ksft_print_msg("Child exited saving values with status %d\n",
786 			       WEXITSTATUS(wait_status));
787 		pass = false;
788 		goto out;
789 	}
790 
791 	if (WIFSIGNALED(wait_status)) {
792 		ksft_print_msg("Child died from signal %d saving values\n",
793 			       WTERMSIG(wait_status));
794 		pass = false;
795 		goto out;
796 	}
797 
798 	/* See what happened as a result */
799 	read_child_regs(child);
800 
801 	if (!continue_breakpoint(child, PTRACE_DETACH))
802 		goto cleanup;
803 
804 	/* The child should exit cleanly */
805 	got_alarm = false;
806 	alarm(1);
807 	while (1) {
808 		if (got_alarm) {
809 			ksft_print_msg("Wait for child timed out\n");
810 			goto cleanup;
811 		}
812 
813 		pid = waitpid(child, &wait_status, 0);
814 		if (pid < 0) {
815 			if (errno == EINTR)
816 				continue;
817 			ksft_exit_fail_msg("waitpid() failed: %s (%d)\n",
818 					   strerror(errno), errno);
819 		}
820 
821 		if (pid == child)
822 			break;
823 	}
824 	alarm(0);
825 
826 	if (got_alarm) {
827 		ksft_print_msg("Timed out waiting for child\n");
828 		pass = false;
829 		goto cleanup;
830 	}
831 
832 	if (pid == child && WIFSIGNALED(wait_status)) {
833 		ksft_print_msg("Child died from signal %d cleaning up\n",
834 			       WTERMSIG(wait_status));
835 		pass = false;
836 		goto out;
837 	}
838 
839 	if (pid == child && WIFEXITED(wait_status)) {
840 		if (WEXITSTATUS(wait_status) != 0) {
841 			ksft_print_msg("Child exited with error %d\n",
842 				       WEXITSTATUS(wait_status));
843 			pass = false;
844 		}
845 	} else {
846 		ksft_print_msg("Child did not exit cleanly\n");
847 		pass = false;
848 		goto cleanup;
849 	}
850 
851 	goto out;
852 
853 cleanup:
854 	ret = kill(child, SIGKILL);
855 	if (ret != 0) {
856 		ksft_print_msg("kill() failed: %s (%d)\n",
857 			       strerror(errno), errno);
858 		return false;
859 	}
860 
861 	while (1) {
862 		pid = waitpid(child, &wait_status, 0);
863 		if (pid < 0) {
864 			if (errno == EINTR)
865 				continue;
866 			ksft_exit_fail_msg("waitpid() failed: %s (%d)\n",
867 					   strerror(errno), errno);
868 		}
869 
870 		if (pid == child)
871 			break;
872 	}
873 
874 out:
875 	return pass;
876 }
877 
878 static void fill_random(void *buf, size_t size)
879 {
880 	int i;
881 	uint32_t *lbuf = buf;
882 
883 	/* random() returns a 32 bit number regardless of the size of long */
884 	for (i = 0; i < size / sizeof(uint32_t); i++)
885 		lbuf[i] = random();
886 }
887 
888 static void fill_random_ffr(void *buf, size_t vq)
889 {
890 	uint8_t *lbuf = buf;
891 	int bits, i;
892 
893 	/*
894 	 * Only values with a continuous set of 0..n bits set are
895 	 * valid for FFR, set all bits then clear a random number of
896 	 * high bits.
897 	 */
898 	memset(buf, 0, __SVE_FFR_SIZE(vq));
899 
900 	bits = random() % (__SVE_FFR_SIZE(vq) * 8);
901 	for (i = 0; i < bits / 8; i++)
902 		lbuf[i] = 0xff;
903 	if (bits / 8 != __SVE_FFR_SIZE(vq))
904 		lbuf[i] = (1 << (bits % 8)) - 1;
905 }
906 
907 static void fpsimd_to_sve(__uint128_t *v, char *z, int vl)
908 {
909 	int vq = __sve_vq_from_vl(vl);
910 	int i;
911 	__uint128_t *p;
912 
913 	if (!vl)
914 		return;
915 
916 	for (i = 0; i < __SVE_NUM_ZREGS; i++) {
917 		p = (__uint128_t *)&z[__SVE_ZREG_OFFSET(vq, i)];
918 		*p = v[i];
919 	}
920 }
921 
922 static void set_initial_values(struct test_config *config)
923 {
924 	int vq = __sve_vq_from_vl(vl_in(config));
925 	int sme_vq = __sve_vq_from_vl(config->sme_vl_in);
926 
927 	svcr_in = config->svcr_in;
928 	svcr_expected = config->svcr_expected;
929 	svcr_out = 0;
930 
931 	fill_random(&v_in, sizeof(v_in));
932 	memcpy(v_expected, v_in, sizeof(v_in));
933 	memset(v_out, 0, sizeof(v_out));
934 
935 	/* Changes will be handled in the test case */
936 	if (sve_supported() || (config->svcr_in & SVCR_SM)) {
937 		/* The low 128 bits of Z are shared with the V registers */
938 		fill_random(&z_in, __SVE_ZREGS_SIZE(vq));
939 		fpsimd_to_sve(v_in, z_in, vl_in(config));
940 		memcpy(z_expected, z_in, __SVE_ZREGS_SIZE(vq));
941 		memset(z_out, 0, sizeof(z_out));
942 
943 		fill_random(&p_in, __SVE_PREGS_SIZE(vq));
944 		memcpy(p_expected, p_in, __SVE_PREGS_SIZE(vq));
945 		memset(p_out, 0, sizeof(p_out));
946 
947 		if ((config->svcr_in & SVCR_SM) && !fa64_supported())
948 			memset(ffr_in, 0, __SVE_PREG_SIZE(vq));
949 		else
950 			fill_random_ffr(&ffr_in, vq);
951 		memcpy(ffr_expected, ffr_in, __SVE_PREG_SIZE(vq));
952 		memset(ffr_out, 0, __SVE_PREG_SIZE(vq));
953 	}
954 
955 	if (config->svcr_in & SVCR_ZA)
956 		fill_random(za_in, ZA_SIG_REGS_SIZE(sme_vq));
957 	else
958 		memset(za_in, 0, ZA_SIG_REGS_SIZE(sme_vq));
959 	if (config->svcr_expected & SVCR_ZA)
960 		memcpy(za_expected, za_in, ZA_SIG_REGS_SIZE(sme_vq));
961 	else
962 		memset(za_expected, 0, ZA_SIG_REGS_SIZE(sme_vq));
963 	if (sme_supported())
964 		memset(za_out, 0, sizeof(za_out));
965 
966 	if (sme2_supported()) {
967 		if (config->svcr_in & SVCR_ZA)
968 			fill_random(zt_in, ZT_SIG_REG_BYTES);
969 		else
970 			memset(zt_in, 0, ZT_SIG_REG_BYTES);
971 		if (config->svcr_expected & SVCR_ZA)
972 			memcpy(zt_expected, zt_in, ZT_SIG_REG_BYTES);
973 		else
974 			memset(zt_expected, 0, ZT_SIG_REG_BYTES);
975 		memset(zt_out, 0, sizeof(zt_out));
976 	}
977 
978 	if (fpmr_supported()) {
979 		fill_random(&fpmr_in, sizeof(fpmr_in));
980 		fpmr_in &= FPMR_SAFE_BITS;
981 		fpmr_expected = fpmr_in;
982 	} else {
983 		fpmr_in = 0;
984 		fpmr_expected = 0;
985 		fpmr_out = 0;
986 	}
987 }
988 
989 static bool check_memory_values(struct test_config *config)
990 {
991 	bool pass = true;
992 	int vq, sme_vq;
993 
994 	if (!compare_buffer("saved V", v_out, v_expected, sizeof(v_out)))
995 		pass = false;
996 
997 	vq = __sve_vq_from_vl(vl_expected(config));
998 	sme_vq = __sve_vq_from_vl(config->sme_vl_expected);
999 
1000 	if (svcr_out != svcr_expected) {
1001 		ksft_print_msg("Mismatch in saved SVCR %lx != %lx\n",
1002 			       svcr_out, svcr_expected);
1003 		pass = false;
1004 	}
1005 
1006 	if (sve_vl_out != config->sve_vl_expected) {
1007 		ksft_print_msg("Mismatch in SVE VL: %ld != %d\n",
1008 			       sve_vl_out, config->sve_vl_expected);
1009 		pass = false;
1010 	}
1011 
1012 	if (sme_vl_out != config->sme_vl_expected) {
1013 		ksft_print_msg("Mismatch in SME VL: %ld != %d\n",
1014 			       sme_vl_out, config->sme_vl_expected);
1015 		pass = false;
1016 	}
1017 
1018 	if (!compare_buffer("saved Z", z_out, z_expected,
1019 			    __SVE_ZREGS_SIZE(vq)))
1020 		pass = false;
1021 
1022 	if (!compare_buffer("saved P", p_out, p_expected,
1023 			    __SVE_PREGS_SIZE(vq)))
1024 		pass = false;
1025 
1026 	if (!compare_buffer("saved FFR", ffr_out, ffr_expected,
1027 			    __SVE_PREG_SIZE(vq)))
1028 		pass = false;
1029 
1030 	if (!compare_buffer("saved ZA", za_out, za_expected,
1031 			    ZA_PT_ZA_SIZE(sme_vq)))
1032 		pass = false;
1033 
1034 	if (!compare_buffer("saved ZT", zt_out, zt_expected, ZT_SIG_REG_BYTES))
1035 		pass = false;
1036 
1037 	if (fpmr_out != fpmr_expected) {
1038 		ksft_print_msg("Mismatch in saved FPMR: %lx != %lx\n",
1039 			       fpmr_out, fpmr_expected);
1040 		pass = false;
1041 	}
1042 
1043 	return pass;
1044 }
1045 
1046 static bool sve_sme_same(struct test_config *config)
1047 {
1048 	if (config->sve_vl_in != config->sve_vl_expected)
1049 		return false;
1050 
1051 	if (config->sme_vl_in != config->sme_vl_expected)
1052 		return false;
1053 
1054 	if (config->svcr_in != config->svcr_expected)
1055 		return false;
1056 
1057 	return true;
1058 }
1059 
1060 static bool sve_write_supported(struct test_config *config)
1061 {
1062 	if (!sve_supported() && !sme_supported())
1063 		return false;
1064 
1065 	if ((config->svcr_in & SVCR_ZA) != (config->svcr_expected & SVCR_ZA))
1066 		return false;
1067 
1068 	if (config->svcr_expected & SVCR_SM) {
1069 		if (config->sve_vl_in != config->sve_vl_expected) {
1070 			return false;
1071 		}
1072 
1073 		/* Changing the SME VL disables ZA */
1074 		if ((config->svcr_expected & SVCR_ZA) &&
1075 		    (config->sme_vl_in != config->sme_vl_expected)) {
1076 			return false;
1077 		}
1078 	} else {
1079 		if (config->sme_vl_in != config->sme_vl_expected) {
1080 			return false;
1081 		}
1082 
1083 		if (!sve_supported())
1084 			return false;
1085 	}
1086 
1087 	return true;
1088 }
1089 
1090 static bool sve_write_fpsimd_supported(struct test_config *config)
1091 {
1092 	if (!sve_supported() && !sme_supported())
1093 		return false;
1094 
1095 	if ((config->svcr_in & SVCR_ZA) != (config->svcr_expected & SVCR_ZA))
1096 		return false;
1097 
1098 	if (config->svcr_expected & SVCR_SM)
1099 		return false;
1100 
1101 	if (config->sme_vl_in != config->sme_vl_expected)
1102 		return false;
1103 
1104 	return true;
1105 }
1106 
1107 static void fpsimd_write_expected(struct test_config *config)
1108 {
1109 	int vl;
1110 
1111 	fill_random(&v_expected, sizeof(v_expected));
1112 
1113 	/* The SVE registers are flushed by a FPSIMD write */
1114 	vl = vl_expected(config);
1115 
1116 	memset(z_expected, 0, __SVE_ZREGS_SIZE(__sve_vq_from_vl(vl)));
1117 	memset(p_expected, 0, __SVE_PREGS_SIZE(__sve_vq_from_vl(vl)));
1118 	memset(ffr_expected, 0, __SVE_PREG_SIZE(__sve_vq_from_vl(vl)));
1119 
1120 	fpsimd_to_sve(v_expected, z_expected, vl);
1121 }
1122 
1123 static void fpsimd_write(pid_t child, struct test_config *test_config)
1124 {
1125 	struct user_fpsimd_state fpsimd;
1126 	struct iovec iov;
1127 	int ret;
1128 
1129 	memset(&fpsimd, 0, sizeof(fpsimd));
1130 	memcpy(&fpsimd.vregs, v_expected, sizeof(v_expected));
1131 
1132 	iov.iov_base = &fpsimd;
1133 	iov.iov_len = sizeof(fpsimd);
1134 	ret = ptrace(PTRACE_SETREGSET, child, NT_PRFPREG, &iov);
1135 	if (ret == -1)
1136 		ksft_print_msg("FPSIMD set failed: (%s) %d\n",
1137 			       strerror(errno), errno);
1138 }
1139 
1140 static bool fpmr_write_supported(struct test_config *config)
1141 {
1142 	if (!fpmr_supported())
1143 		return false;
1144 
1145 	if (!sve_sme_same(config))
1146 		return false;
1147 
1148 	return true;
1149 }
1150 
1151 static void fpmr_write_expected(struct test_config *config)
1152 {
1153 	fill_random(&fpmr_expected, sizeof(fpmr_expected));
1154 	fpmr_expected &= FPMR_SAFE_BITS;
1155 }
1156 
1157 static void fpmr_write(pid_t child, struct test_config *config)
1158 {
1159 	struct iovec iov;
1160 	int ret;
1161 
1162 	iov.iov_len = sizeof(fpmr_expected);
1163 	iov.iov_base = &fpmr_expected;
1164 	ret = ptrace(PTRACE_SETREGSET, child, NT_ARM_FPMR, &iov);
1165 	if (ret != 0)
1166 		ksft_print_msg("Failed to write FPMR: %s (%d)\n",
1167 			       strerror(errno), errno);
1168 }
1169 
1170 static void sve_write_expected(struct test_config *config)
1171 {
1172 	int vl = vl_expected(config);
1173 	int sme_vq = __sve_vq_from_vl(config->sme_vl_expected);
1174 
1175 	if (!vl)
1176 		return;
1177 
1178 	fill_random(z_expected, __SVE_ZREGS_SIZE(__sve_vq_from_vl(vl)));
1179 	fill_random(p_expected, __SVE_PREGS_SIZE(__sve_vq_from_vl(vl)));
1180 
1181 	if ((svcr_expected & SVCR_SM) && !fa64_supported())
1182 		memset(ffr_expected, 0, __SVE_PREG_SIZE(sme_vq));
1183 	else
1184 		fill_random_ffr(ffr_expected, __sve_vq_from_vl(vl));
1185 
1186 	/* Share the low bits of Z with V */
1187 	fill_random(&v_expected, sizeof(v_expected));
1188 	fpsimd_to_sve(v_expected, z_expected, vl);
1189 
1190 	if (config->sme_vl_in != config->sme_vl_expected) {
1191 		memset(za_expected, 0, ZA_PT_ZA_SIZE(sme_vq));
1192 		memset(zt_expected, 0, sizeof(zt_expected));
1193 	}
1194 }
1195 
1196 static void sve_write_sve(pid_t child, struct test_config *config)
1197 {
1198 	struct user_sve_header *sve;
1199 	struct iovec iov;
1200 	int ret, vl, vq, regset;
1201 
1202 	vl = vl_expected(config);
1203 	vq = __sve_vq_from_vl(vl);
1204 
1205 	if (!vl)
1206 		return;
1207 
1208 	iov.iov_len = SVE_PT_SIZE(vq, SVE_PT_REGS_SVE);
1209 	iov.iov_base = malloc(iov.iov_len);
1210 	if (!iov.iov_base) {
1211 		ksft_print_msg("Failed allocating %lu byte SVE write buffer\n",
1212 			       iov.iov_len);
1213 		return;
1214 	}
1215 	memset(iov.iov_base, 0, iov.iov_len);
1216 
1217 	sve = iov.iov_base;
1218 	sve->size = iov.iov_len;
1219 	sve->flags = SVE_PT_REGS_SVE;
1220 	sve->vl = vl;
1221 
1222 	memcpy(iov.iov_base + SVE_PT_SVE_ZREG_OFFSET(vq, 0),
1223 	       z_expected, SVE_PT_SVE_ZREGS_SIZE(vq));
1224 	memcpy(iov.iov_base + SVE_PT_SVE_PREG_OFFSET(vq, 0),
1225 	       p_expected, SVE_PT_SVE_PREGS_SIZE(vq));
1226 	memcpy(iov.iov_base + SVE_PT_SVE_FFR_OFFSET(vq),
1227 	       ffr_expected, SVE_PT_SVE_PREG_SIZE(vq));
1228 
1229 	if (svcr_expected & SVCR_SM)
1230 		regset = NT_ARM_SSVE;
1231 	else
1232 		regset = NT_ARM_SVE;
1233 
1234 	ret = ptrace(PTRACE_SETREGSET, child, regset, &iov);
1235 	if (ret != 0)
1236 		ksft_print_msg("Failed to write SVE: %s (%d)\n",
1237 			       strerror(errno), errno);
1238 
1239 	free(iov.iov_base);
1240 }
1241 
1242 static void sve_write_fpsimd(pid_t child, struct test_config *config)
1243 {
1244 	struct user_sve_header *sve;
1245 	struct user_fpsimd_state *fpsimd;
1246 	struct iovec iov;
1247 	int ret, vl, vq;
1248 
1249 	vl = vl_expected(config);
1250 	vq = __sve_vq_from_vl(vl);
1251 
1252 	iov.iov_len = SVE_PT_SIZE(vq, SVE_PT_REGS_FPSIMD);
1253 	iov.iov_base = malloc(iov.iov_len);
1254 	if (!iov.iov_base) {
1255 		ksft_print_msg("Failed allocating %lu byte SVE write buffer\n",
1256 			       iov.iov_len);
1257 		return;
1258 	}
1259 	memset(iov.iov_base, 0, iov.iov_len);
1260 
1261 	sve = iov.iov_base;
1262 	sve->size = iov.iov_len;
1263 	sve->flags = SVE_PT_REGS_FPSIMD;
1264 	sve->vl = vl;
1265 
1266 	fpsimd = iov.iov_base + SVE_PT_REGS_OFFSET;
1267 	memcpy(&fpsimd->vregs, v_expected, sizeof(v_expected));
1268 
1269 	ret = ptrace(PTRACE_SETREGSET, child, NT_ARM_SVE, &iov);
1270 	if (ret != 0)
1271 		ksft_print_msg("Failed to write SVE: %s (%d)\n",
1272 			       strerror(errno), errno);
1273 
1274 	free(iov.iov_base);
1275 }
1276 
1277 static bool za_write_supported(struct test_config *config)
1278 {
1279 	if ((config->svcr_in & SVCR_SM) != (config->svcr_expected & SVCR_SM))
1280 		return false;
1281 
1282 	return true;
1283 }
1284 
1285 static void za_write_expected(struct test_config *config)
1286 {
1287 	int sme_vq, sve_vq;
1288 
1289 	sme_vq = __sve_vq_from_vl(config->sme_vl_expected);
1290 
1291 	if (config->svcr_expected & SVCR_ZA) {
1292 		fill_random(za_expected, ZA_PT_ZA_SIZE(sme_vq));
1293 	} else {
1294 		memset(za_expected, 0, ZA_PT_ZA_SIZE(sme_vq));
1295 		memset(zt_expected, 0, sizeof(zt_expected));
1296 	}
1297 
1298 	/* Changing the SME VL flushes ZT, SVE state */
1299 	if (config->sme_vl_in != config->sme_vl_expected) {
1300 		sve_vq = __sve_vq_from_vl(vl_expected(config));
1301 		memset(z_expected, 0, __SVE_ZREGS_SIZE(sve_vq));
1302 		memset(p_expected, 0, __SVE_PREGS_SIZE(sve_vq));
1303 		memset(ffr_expected, 0, __SVE_PREG_SIZE(sve_vq));
1304 		memset(zt_expected, 0, sizeof(zt_expected));
1305 
1306 		fpsimd_to_sve(v_expected, z_expected, vl_expected(config));
1307 	}
1308 }
1309 
1310 static void za_write(pid_t child, struct test_config *config)
1311 {
1312 	struct user_za_header *za;
1313 	struct iovec iov;
1314 	int ret, vq;
1315 
1316 	vq = __sve_vq_from_vl(config->sme_vl_expected);
1317 
1318 	if (config->svcr_expected & SVCR_ZA)
1319 		iov.iov_len = ZA_PT_SIZE(vq);
1320 	else
1321 		iov.iov_len = sizeof(*za);
1322 	iov.iov_base = malloc(iov.iov_len);
1323 	if (!iov.iov_base) {
1324 		ksft_print_msg("Failed allocating %lu byte ZA write buffer\n",
1325 			       iov.iov_len);
1326 		return;
1327 	}
1328 	memset(iov.iov_base, 0, iov.iov_len);
1329 
1330 	za = iov.iov_base;
1331 	za->size = iov.iov_len;
1332 	za->vl = config->sme_vl_expected;
1333 	if (config->svcr_expected & SVCR_ZA)
1334 		memcpy(iov.iov_base + ZA_PT_ZA_OFFSET, za_expected,
1335 		       ZA_PT_ZA_SIZE(vq));
1336 
1337 	ret = ptrace(PTRACE_SETREGSET, child, NT_ARM_ZA, &iov);
1338 	if (ret != 0)
1339 		ksft_print_msg("Failed to write ZA: %s (%d)\n",
1340 			       strerror(errno), errno);
1341 
1342 	free(iov.iov_base);
1343 }
1344 
1345 static bool zt_write_supported(struct test_config *config)
1346 {
1347 	if (!sme2_supported())
1348 		return false;
1349 	if (config->sme_vl_in != config->sme_vl_expected)
1350 		return false;
1351 	if (!(config->svcr_expected & SVCR_ZA))
1352 		return false;
1353 	if ((config->svcr_in & SVCR_SM) != (config->svcr_expected & SVCR_SM))
1354 		return false;
1355 
1356 	return true;
1357 }
1358 
1359 static void zt_write_expected(struct test_config *config)
1360 {
1361 	int sme_vq;
1362 
1363 	sme_vq = __sve_vq_from_vl(config->sme_vl_expected);
1364 
1365 	if (config->svcr_expected & SVCR_ZA) {
1366 		fill_random(zt_expected, sizeof(zt_expected));
1367 	} else {
1368 		memset(za_expected, 0, ZA_PT_ZA_SIZE(sme_vq));
1369 		memset(zt_expected, 0, sizeof(zt_expected));
1370 	}
1371 }
1372 
1373 static void zt_write(pid_t child, struct test_config *config)
1374 {
1375 	struct iovec iov;
1376 	int ret;
1377 
1378 	iov.iov_len = ZT_SIG_REG_BYTES;
1379 	iov.iov_base = zt_expected;
1380 	ret = ptrace(PTRACE_SETREGSET, child, NT_ARM_ZT, &iov);
1381 	if (ret != 0)
1382 		ksft_print_msg("Failed to write ZT: %s (%d)\n",
1383 			       strerror(errno), errno);
1384 }
1385 
1386 /* Actually run a test */
1387 static void run_test(struct test_definition *test, struct test_config *config)
1388 {
1389 	pid_t child;
1390 	char name[1024];
1391 	bool pass;
1392 
1393 	if (sve_supported() && sme_supported())
1394 		snprintf(name, sizeof(name), "%s, SVE %d->%d, SME %d/%x->%d/%x",
1395 			 test->name,
1396 			 config->sve_vl_in, config->sve_vl_expected,
1397 			 config->sme_vl_in, config->svcr_in,
1398 			 config->sme_vl_expected, config->svcr_expected);
1399 	else if (sve_supported())
1400 		snprintf(name, sizeof(name), "%s, SVE %d->%d", test->name,
1401 			 config->sve_vl_in, config->sve_vl_expected);
1402 	else if (sme_supported())
1403 		snprintf(name, sizeof(name), "%s, SME %d/%x->%d/%x",
1404 			 test->name,
1405 			 config->sme_vl_in, config->svcr_in,
1406 			 config->sme_vl_expected, config->svcr_expected);
1407 	else
1408 		snprintf(name, sizeof(name), "%s", test->name);
1409 
1410 	if (test->supported && !test->supported(config)) {
1411 		ksft_test_result_skip("%s\n", name);
1412 		return;
1413 	}
1414 
1415 	set_initial_values(config);
1416 
1417 	if (test->set_expected_values)
1418 		test->set_expected_values(config);
1419 
1420 	child = fork();
1421 	if (child < 0)
1422 		ksft_exit_fail_msg("fork() failed: %s (%d)\n",
1423 				   strerror(errno), errno);
1424 	/* run_child() never returns */
1425 	if (child == 0)
1426 		run_child(config);
1427 
1428 	pass = run_parent(child, test, config);
1429 	if (!check_memory_values(config))
1430 		pass = false;
1431 
1432 	ksft_test_result(pass, "%s\n", name);
1433 }
1434 
1435 static void run_tests(struct test_definition defs[], int count,
1436 		      struct test_config *config)
1437 {
1438 	int i;
1439 
1440 	for (i = 0; i < count; i++)
1441 		run_test(&defs[i], config);
1442 }
1443 
1444 static struct test_definition base_test_defs[] = {
1445 	{
1446 		.name = "No writes",
1447 		.supported = sve_sme_same,
1448 	},
1449 	{
1450 		.name = "FPSIMD write",
1451 		.supported = sve_sme_same,
1452 		.set_expected_values = fpsimd_write_expected,
1453 		.modify_values = fpsimd_write,
1454 	},
1455 	{
1456 		.name = "FPMR write",
1457 		.supported = fpmr_write_supported,
1458 		.set_expected_values = fpmr_write_expected,
1459 		.modify_values = fpmr_write,
1460 	},
1461 };
1462 
1463 static struct test_definition sve_test_defs[] = {
1464 	{
1465 		.name = "SVE write",
1466 		.supported = sve_write_supported,
1467 		.set_expected_values = sve_write_expected,
1468 		.modify_values = sve_write_sve,
1469 	},
1470 	{
1471 		.name = "SVE write FPSIMD format",
1472 		.supported = sve_write_fpsimd_supported,
1473 		.set_expected_values = fpsimd_write_expected,
1474 		.modify_values = sve_write_fpsimd,
1475 	},
1476 };
1477 
1478 static struct test_definition za_test_defs[] = {
1479 	{
1480 		.name = "ZA write",
1481 		.supported = za_write_supported,
1482 		.set_expected_values = za_write_expected,
1483 		.modify_values = za_write,
1484 	},
1485 };
1486 
1487 static struct test_definition zt_test_defs[] = {
1488 	{
1489 		.name = "ZT write",
1490 		.supported = zt_write_supported,
1491 		.set_expected_values = zt_write_expected,
1492 		.modify_values = zt_write,
1493 	},
1494 };
1495 
1496 static int sve_vls[MAX_NUM_VLS], sme_vls[MAX_NUM_VLS];
1497 static int sve_vl_count, sme_vl_count;
1498 
1499 static void probe_vls(const char *name, int vls[], int *vl_count, int set_vl)
1500 {
1501 	unsigned int vq;
1502 	int vl;
1503 
1504 	*vl_count = 0;
1505 
1506 	for (vq = ARCH_VQ_MAX; vq > 0; vq /= 2) {
1507 		vl = prctl(set_vl, vq * 16);
1508 		if (vl == -1)
1509 			ksft_exit_fail_msg("SET_VL failed: %s (%d)\n",
1510 					   strerror(errno), errno);
1511 
1512 		vl &= PR_SVE_VL_LEN_MASK;
1513 
1514 		if (*vl_count && (vl == vls[*vl_count - 1]))
1515 			break;
1516 
1517 		vq = sve_vq_from_vl(vl);
1518 
1519 		vls[*vl_count] = vl;
1520 		*vl_count += 1;
1521 	}
1522 
1523 	if (*vl_count > 2) {
1524 		/* Just use the minimum and maximum */
1525 		vls[1] = vls[*vl_count - 1];
1526 		ksft_print_msg("%d %s VLs, using %d and %d\n",
1527 			       *vl_count, name, vls[0], vls[1]);
1528 		*vl_count = 2;
1529 	} else {
1530 		ksft_print_msg("%d %s VLs\n", *vl_count, name);
1531 	}
1532 }
1533 
1534 static struct {
1535 	int svcr_in, svcr_expected;
1536 } svcr_combinations[] = {
1537 	{ .svcr_in = 0, .svcr_expected = 0, },
1538 	{ .svcr_in = 0, .svcr_expected = SVCR_SM, },
1539 	{ .svcr_in = 0, .svcr_expected = SVCR_ZA, },
1540 	/* Can't enable both SM and ZA with a single ptrace write */
1541 
1542 	{ .svcr_in = SVCR_SM, .svcr_expected = 0, },
1543 	{ .svcr_in = SVCR_SM, .svcr_expected = SVCR_SM, },
1544 	{ .svcr_in = SVCR_SM, .svcr_expected = SVCR_ZA, },
1545 	{ .svcr_in = SVCR_SM, .svcr_expected = SVCR_SM | SVCR_ZA, },
1546 
1547 	{ .svcr_in = SVCR_ZA, .svcr_expected = 0, },
1548 	{ .svcr_in = SVCR_ZA, .svcr_expected = SVCR_SM, },
1549 	{ .svcr_in = SVCR_ZA, .svcr_expected = SVCR_ZA, },
1550 	{ .svcr_in = SVCR_ZA, .svcr_expected = SVCR_SM | SVCR_ZA, },
1551 
1552 	{ .svcr_in = SVCR_SM | SVCR_ZA, .svcr_expected = 0, },
1553 	{ .svcr_in = SVCR_SM | SVCR_ZA, .svcr_expected = SVCR_SM, },
1554 	{ .svcr_in = SVCR_SM | SVCR_ZA, .svcr_expected = SVCR_ZA, },
1555 	{ .svcr_in = SVCR_SM | SVCR_ZA, .svcr_expected = SVCR_SM | SVCR_ZA, },
1556 };
1557 
1558 static void run_sve_tests(void)
1559 {
1560 	struct test_config test_config;
1561 	int i, j;
1562 
1563 	if (!sve_supported())
1564 		return;
1565 
1566 	test_config.sme_vl_in = sme_vls[0];
1567 	test_config.sme_vl_expected = sme_vls[0];
1568 	test_config.svcr_in = 0;
1569 	test_config.svcr_expected = 0;
1570 
1571 	for (i = 0; i < sve_vl_count; i++) {
1572 		test_config.sve_vl_in = sve_vls[i];
1573 
1574 		for (j = 0; j < sve_vl_count; j++) {
1575 			test_config.sve_vl_expected = sve_vls[j];
1576 
1577 			run_tests(base_test_defs,
1578 				  ARRAY_SIZE(base_test_defs),
1579 				  &test_config);
1580 			if (sve_supported())
1581 				run_tests(sve_test_defs,
1582 					  ARRAY_SIZE(sve_test_defs),
1583 					  &test_config);
1584 		}
1585 	}
1586 }
1587 
1588 static void run_sme_tests(void)
1589 {
1590 	struct test_config test_config;
1591 	int i, j, k;
1592 
1593 	if (!sme_supported())
1594 		return;
1595 
1596 	test_config.sve_vl_in = sve_vls[0];
1597 	test_config.sve_vl_expected = sve_vls[0];
1598 
1599 	/*
1600 	 * Every SME VL/SVCR combination
1601 	 */
1602 	for (i = 0; i < sme_vl_count; i++) {
1603 		test_config.sme_vl_in = sme_vls[i];
1604 
1605 		for (j = 0; j < sme_vl_count; j++) {
1606 			test_config.sme_vl_expected = sme_vls[j];
1607 
1608 			for (k = 0; k < ARRAY_SIZE(svcr_combinations); k++) {
1609 				test_config.svcr_in = svcr_combinations[k].svcr_in;
1610 				test_config.svcr_expected = svcr_combinations[k].svcr_expected;
1611 
1612 				run_tests(base_test_defs,
1613 					  ARRAY_SIZE(base_test_defs),
1614 					  &test_config);
1615 				run_tests(sve_test_defs,
1616 					  ARRAY_SIZE(sve_test_defs),
1617 					  &test_config);
1618 				run_tests(za_test_defs,
1619 					  ARRAY_SIZE(za_test_defs),
1620 					  &test_config);
1621 
1622 				if (sme2_supported())
1623 					run_tests(zt_test_defs,
1624 						  ARRAY_SIZE(zt_test_defs),
1625 						  &test_config);
1626 			}
1627 		}
1628 	}
1629 }
1630 
1631 int main(void)
1632 {
1633 	struct test_config test_config;
1634 	struct sigaction sa;
1635 	int tests, ret, tmp;
1636 
1637 	srandom(getpid());
1638 
1639 	ksft_print_header();
1640 
1641 	if (sve_supported()) {
1642 		probe_vls("SVE", sve_vls, &sve_vl_count, PR_SVE_SET_VL);
1643 
1644 		tests = ARRAY_SIZE(base_test_defs) +
1645 			ARRAY_SIZE(sve_test_defs);
1646 		tests *= sve_vl_count * sve_vl_count;
1647 	} else {
1648 		/* Only run the FPSIMD tests */
1649 		sve_vl_count = 1;
1650 		tests = ARRAY_SIZE(base_test_defs);
1651 	}
1652 
1653 	if (sme_supported()) {
1654 		probe_vls("SME", sme_vls, &sme_vl_count, PR_SME_SET_VL);
1655 
1656 		tmp = ARRAY_SIZE(base_test_defs) + ARRAY_SIZE(sve_test_defs)
1657 			+ ARRAY_SIZE(za_test_defs);
1658 
1659 		if (sme2_supported())
1660 			tmp += ARRAY_SIZE(zt_test_defs);
1661 
1662 		tmp *= sme_vl_count * sme_vl_count;
1663 		tmp *= ARRAY_SIZE(svcr_combinations);
1664 		tests += tmp;
1665 	} else {
1666 		sme_vl_count = 1;
1667 	}
1668 
1669 	if (sme2_supported())
1670 		ksft_print_msg("SME2 supported\n");
1671 
1672 	if (fa64_supported())
1673 		ksft_print_msg("FA64 supported\n");
1674 
1675 	if (fpmr_supported())
1676 		ksft_print_msg("FPMR supported\n");
1677 
1678 	ksft_set_plan(tests);
1679 
1680 	/* Get signal handers ready before we start any children */
1681 	memset(&sa, 0, sizeof(sa));
1682 	sa.sa_sigaction = handle_alarm;
1683 	sa.sa_flags = SA_RESTART | SA_SIGINFO;
1684 	sigemptyset(&sa.sa_mask);
1685 	ret = sigaction(SIGALRM, &sa, NULL);
1686 	if (ret < 0)
1687 		ksft_print_msg("Failed to install SIGALRM handler: %s (%d)\n",
1688 			       strerror(errno), errno);
1689 
1690 	/*
1691 	 * Run the test set if there is no SVE or SME, with those we
1692 	 * have to pick a VL for each run.
1693 	 */
1694 	if (!sve_supported() && !sme_supported()) {
1695 		test_config.sve_vl_in = 0;
1696 		test_config.sve_vl_expected = 0;
1697 		test_config.sme_vl_in = 0;
1698 		test_config.sme_vl_expected = 0;
1699 		test_config.svcr_in = 0;
1700 		test_config.svcr_expected = 0;
1701 
1702 		run_tests(base_test_defs, ARRAY_SIZE(base_test_defs),
1703 			  &test_config);
1704 	}
1705 
1706 	run_sve_tests();
1707 	run_sme_tests();
1708 
1709 	ksft_finished();
1710 }
1711