xref: /xnu-12377.1.9/osfmk/arm64/status.c (revision f6217f891ac0bb64f3d375211650a4c1ff8ca1ea)
1 /*
2  * Copyright (c) 2007-2024 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 #include <debug.h>
29 #include <mach/mach_types.h>
30 #include <mach/kern_return.h>
31 #include <mach/thread_status.h>
32 #include <kern/thread.h>
33 #include <kern/kalloc.h>
34 #include <arm/vmparam.h>
35 #include <arm/cpu_data_internal.h>
36 #include <arm/misc_protos.h>
37 #include <arm64/machine_machdep.h>
38 #include <arm64/proc_reg.h>
39 #include <sys/random.h>
40 #if __has_feature(ptrauth_calls)
41 #include <ptrauth.h>
42 #endif
43 
44 #include <libkern/coreanalytics/coreanalytics.h>
45 
46 
47 struct arm_vfpv2_state {
48 	__uint32_t __r[32];
49 	__uint32_t __fpscr;
50 };
51 
52 typedef struct arm_vfpv2_state arm_vfpv2_state_t;
53 
54 #define ARM_VFPV2_STATE_COUNT \
55 	((mach_msg_type_number_t)(sizeof (arm_vfpv2_state_t)/sizeof(uint32_t)))
56 
57 /*
58  * Forward definitions
59  */
60 void thread_set_child(thread_t child, int pid);
61 static void free_debug_state(thread_t thread);
62 user_addr_t thread_get_sigreturn_token(thread_t thread);
63 uint32_t thread_get_sigreturn_diversifier(thread_t thread);
64 
65 /*
66  * Maps state flavor to number of words in the state:
67  */
68 /* __private_extern__ */
69 unsigned int _MachineStateCount[THREAD_STATE_FLAVORS] = {
70 	[ARM_UNIFIED_THREAD_STATE] = ARM_UNIFIED_THREAD_STATE_COUNT,
71 	[ARM_VFP_STATE] = ARM_VFP_STATE_COUNT,
72 	[ARM_EXCEPTION_STATE] = ARM_EXCEPTION_STATE_COUNT,
73 	[ARM_DEBUG_STATE] = ARM_DEBUG_STATE_COUNT,
74 	[ARM_THREAD_STATE64] = ARM_THREAD_STATE64_COUNT,
75 	[ARM_EXCEPTION_STATE64] = ARM_EXCEPTION_STATE64_COUNT,
76 	[ARM_EXCEPTION_STATE64_V2] = ARM_EXCEPTION_STATE64_V2_COUNT,
77 	[ARM_THREAD_STATE32] = ARM_THREAD_STATE32_COUNT,
78 	[ARM_DEBUG_STATE32] = ARM_DEBUG_STATE32_COUNT,
79 	[ARM_DEBUG_STATE64] = ARM_DEBUG_STATE64_COUNT,
80 	[ARM_NEON_STATE] = ARM_NEON_STATE_COUNT,
81 	[ARM_NEON_STATE64] = ARM_NEON_STATE64_COUNT,
82 	[ARM_PAGEIN_STATE] = ARM_PAGEIN_STATE_COUNT,
83 	/*
84 	 * Mach exception ports don't currently support SME state flavors.
85 	 * In case exception_deliver tries to access them anyway, give
86 	 * them bogus sizes that will ensure the access fails.
87 	 */
88 	[ARM_SME_STATE ... ARM_SME2_STATE] = 0,
89 };
90 
91 extern zone_t ads_zone;
92 
93 #if __arm64__
94 /*
95  * Copy values from saved_state to ts64.
96  */
97 void
saved_state_to_thread_state64(const arm_saved_state_t * saved_state,arm_thread_state64_t * ts64)98 saved_state_to_thread_state64(const arm_saved_state_t * saved_state,
99     arm_thread_state64_t *    ts64)
100 {
101 	uint32_t i;
102 
103 	assert(is_saved_state64(saved_state));
104 
105 	ts64->fp = get_saved_state_fp(saved_state);
106 	ts64->lr = get_saved_state_lr(saved_state);
107 	ts64->sp = get_saved_state_sp(saved_state);
108 	ts64->pc = get_saved_state_pc(saved_state);
109 	ts64->cpsr = get_saved_state_cpsr(saved_state);
110 	for (i = 0; i < 29; i++) {
111 		ts64->x[i] = get_saved_state_reg(saved_state, i);
112 	}
113 }
114 
115 /*
116  * Copy values from ts64 to saved_state.
117  *
118  * For safety, CPSR is sanitized as follows:
119  *
120  * - ts64->cpsr.{N,Z,C,V} are copied as-is into saved_state->cpsr
121  * - ts64->cpsr.M is ignored, and saved_state->cpsr.M is reset to EL0
122  * - All other saved_state->cpsr bits are preserved as-is
123  */
124 void
thread_state64_to_saved_state(const arm_thread_state64_t * ts64,arm_saved_state_t * saved_state)125 thread_state64_to_saved_state(const arm_thread_state64_t * ts64,
126     arm_saved_state_t *          saved_state)
127 {
128 	uint32_t i;
129 #if __has_feature(ptrauth_calls)
130 	uint64_t intr = ml_pac_safe_interrupts_disable();
131 #endif /* __has_feature(ptrauth_calls) */
132 
133 	assert(is_saved_state64(saved_state));
134 
135 	const uint32_t CPSR_COPY_MASK = PSR64_USER_MASK;
136 	const uint32_t CPSR_ZERO_MASK = PSR64_MODE_MASK;
137 	const uint32_t CPSR_PRESERVE_MASK = ~(CPSR_COPY_MASK | CPSR_ZERO_MASK);
138 #if __has_feature(ptrauth_calls)
139 	/* BEGIN IGNORE CODESTYLE */
140 	MANIPULATE_SIGNED_USER_THREAD_STATE(saved_state,
141 		"and	w2, w2, %w[preserve_mask]"	"\n"
142 		"mov	w6, %w[cpsr]"			"\n"
143 		"and	w6, w6, %w[copy_mask]"		"\n"
144 		"orr	w2, w2, w6"			"\n"
145 		"str	w2, [x0, %[SS64_CPSR]]"		"\n",
146 		[cpsr] "r"(ts64->cpsr),
147 		[preserve_mask] "i"(CPSR_PRESERVE_MASK),
148 		[copy_mask] "i"(CPSR_COPY_MASK)
149 	);
150 	/* END IGNORE CODESTYLE */
151 	/*
152 	 * Make writes to ts64->cpsr visible first, since it's useful as a
153 	 * canary to detect thread-state corruption.
154 	 */
155 	__builtin_arm_dmb(DMB_ST);
156 #else
157 	uint32_t new_cpsr = get_saved_state_cpsr(saved_state);
158 	new_cpsr &= CPSR_PRESERVE_MASK;
159 	new_cpsr |= (ts64->cpsr & CPSR_COPY_MASK);
160 	set_user_saved_state_cpsr(saved_state, new_cpsr);
161 #endif /* __has_feature(ptrauth_calls) */
162 	set_saved_state_fp(saved_state, ts64->fp);
163 	set_user_saved_state_lr(saved_state, ts64->lr);
164 	set_saved_state_sp(saved_state, ts64->sp);
165 	set_user_saved_state_pc(saved_state, ts64->pc);
166 	for (i = 0; i < 29; i++) {
167 		set_user_saved_state_reg(saved_state, i, ts64->x[i]);
168 	}
169 
170 #if __has_feature(ptrauth_calls)
171 	ml_pac_safe_interrupts_restore(intr);
172 #endif /* __has_feature(ptrauth_calls) */
173 }
174 
175 #endif /* __arm64__ */
176 
177 static kern_return_t
handle_get_arm32_thread_state(thread_state_t tstate,mach_msg_type_number_t * count,const arm_saved_state_t * saved_state)178 handle_get_arm32_thread_state(thread_state_t            tstate,
179     mach_msg_type_number_t *  count,
180     const arm_saved_state_t * saved_state)
181 {
182 	if (*count < ARM_THREAD_STATE32_COUNT) {
183 		return KERN_INVALID_ARGUMENT;
184 	}
185 	if (!is_saved_state32(saved_state)) {
186 		return KERN_INVALID_ARGUMENT;
187 	}
188 
189 	(void)saved_state_to_thread_state32(saved_state, (arm_thread_state32_t *)tstate);
190 	*count = ARM_THREAD_STATE32_COUNT;
191 	return KERN_SUCCESS;
192 }
193 
194 static kern_return_t
handle_get_arm64_thread_state(thread_state_t tstate,mach_msg_type_number_t * count,const arm_saved_state_t * saved_state)195 handle_get_arm64_thread_state(thread_state_t            tstate,
196     mach_msg_type_number_t *  count,
197     const arm_saved_state_t * saved_state)
198 {
199 	if (*count < ARM_THREAD_STATE64_COUNT) {
200 		return KERN_INVALID_ARGUMENT;
201 	}
202 	if (!is_saved_state64(saved_state)) {
203 		return KERN_INVALID_ARGUMENT;
204 	}
205 
206 	(void)saved_state_to_thread_state64(saved_state, (arm_thread_state64_t *)tstate);
207 	*count = ARM_THREAD_STATE64_COUNT;
208 	return KERN_SUCCESS;
209 }
210 
211 
212 static kern_return_t
handle_get_arm_thread_state(thread_state_t tstate,mach_msg_type_number_t * count,const arm_saved_state_t * saved_state)213 handle_get_arm_thread_state(thread_state_t            tstate,
214     mach_msg_type_number_t *  count,
215     const arm_saved_state_t * saved_state)
216 {
217 	/* In an arm64 world, this flavor can be used to retrieve the thread
218 	 * state of a 32-bit or 64-bit thread into a unified structure, but we
219 	 * need to support legacy clients who are only aware of 32-bit, so
220 	 * check the count to see what the client is expecting.
221 	 */
222 	if (*count < ARM_UNIFIED_THREAD_STATE_COUNT) {
223 		return handle_get_arm32_thread_state(tstate, count, saved_state);
224 	}
225 
226 	arm_unified_thread_state_t *unified_state = (arm_unified_thread_state_t *) tstate;
227 	bzero(unified_state, sizeof(*unified_state));
228 #if __arm64__
229 	if (is_saved_state64(saved_state)) {
230 		unified_state->ash.flavor = ARM_THREAD_STATE64;
231 		unified_state->ash.count = ARM_THREAD_STATE64_COUNT;
232 		(void)saved_state_to_thread_state64(saved_state, thread_state64(unified_state));
233 	} else
234 #endif
235 	{
236 		unified_state->ash.flavor = ARM_THREAD_STATE32;
237 		unified_state->ash.count = ARM_THREAD_STATE32_COUNT;
238 		(void)saved_state_to_thread_state32(saved_state, thread_state32(unified_state));
239 	}
240 	*count = ARM_UNIFIED_THREAD_STATE_COUNT;
241 	return KERN_SUCCESS;
242 }
243 
244 
245 static kern_return_t
handle_set_arm32_thread_state(const thread_state_t tstate,mach_msg_type_number_t count,arm_saved_state_t * saved_state)246 handle_set_arm32_thread_state(const thread_state_t   tstate,
247     mach_msg_type_number_t count,
248     arm_saved_state_t *    saved_state)
249 {
250 	if (count != ARM_THREAD_STATE32_COUNT) {
251 		return KERN_INVALID_ARGUMENT;
252 	}
253 
254 	(void)thread_state32_to_saved_state((const arm_thread_state32_t *)tstate, saved_state);
255 	return KERN_SUCCESS;
256 }
257 
258 static kern_return_t
handle_set_arm64_thread_state(const thread_state_t tstate,mach_msg_type_number_t count,arm_saved_state_t * saved_state)259 handle_set_arm64_thread_state(const thread_state_t   tstate,
260     mach_msg_type_number_t count,
261     arm_saved_state_t *    saved_state)
262 {
263 	if (count != ARM_THREAD_STATE64_COUNT) {
264 		return KERN_INVALID_ARGUMENT;
265 	}
266 
267 	(void)thread_state64_to_saved_state((const arm_thread_state64_t *)tstate, saved_state);
268 	return KERN_SUCCESS;
269 }
270 
271 
272 static kern_return_t
handle_set_arm_thread_state(const thread_state_t tstate,mach_msg_type_number_t count,arm_saved_state_t * saved_state)273 handle_set_arm_thread_state(const thread_state_t   tstate,
274     mach_msg_type_number_t count,
275     arm_saved_state_t *    saved_state)
276 {
277 	/* In an arm64 world, this flavor can be used to set the thread state of a
278 	 * 32-bit or 64-bit thread from a unified structure, but we need to support
279 	 * legacy clients who are only aware of 32-bit, so check the count to see
280 	 * what the client is expecting.
281 	 */
282 	if (count < ARM_UNIFIED_THREAD_STATE_COUNT) {
283 		if (!is_saved_state32(saved_state)) {
284 			return KERN_INVALID_ARGUMENT;
285 		}
286 		return handle_set_arm32_thread_state(tstate, count, saved_state);
287 	}
288 
289 	const arm_unified_thread_state_t *unified_state = (const arm_unified_thread_state_t *) tstate;
290 #if __arm64__
291 	if (is_thread_state64(unified_state)) {
292 		if (!is_saved_state64(saved_state)) {
293 			return KERN_INVALID_ARGUMENT;
294 		}
295 		(void)thread_state64_to_saved_state(const_thread_state64(unified_state), saved_state);
296 	} else
297 #endif
298 	{
299 		if (!is_saved_state32(saved_state)) {
300 			return KERN_INVALID_ARGUMENT;
301 		}
302 		(void)thread_state32_to_saved_state(const_thread_state32(unified_state), saved_state);
303 	}
304 
305 	return KERN_SUCCESS;
306 }
307 
308 
309 #if HAS_ARM_FEAT_SME
310 static kern_return_t
handle_get_arm_sme_state(thread_state_t tstate,mach_msg_type_number_t * count,thread_t thread)311 handle_get_arm_sme_state(thread_state_t tstate, mach_msg_type_number_t *count, thread_t thread)
312 {
313 	if (!arm_sme_version()) {
314 		return KERN_INVALID_ARGUMENT;
315 	}
316 
317 	if (*count < ARM_SME_STATE_COUNT) {
318 		return KERN_INVALID_ARGUMENT;
319 	}
320 
321 	arm_sme_state_t *state_out = (arm_sme_state_t *)tstate;
322 	state_out->svl_b = arm_sme_svl_b();
323 
324 	/*
325 	 * Saved-state TPIDR2_EL0, ZA, and ZT0 are only updated on context-switch.  If
326 	 * the thread is currently active on this CPU, those saved-state values may be
327 	 * stale and must be resynchronized with the live CPU state.
328 	 *
329 	 * We don't need to do this for threads active on other CPUs, since thread_get_state()
330 	 * forcibly preempts them before calling machine_thread_get_state().
331 	 */
332 	if (thread == current_thread()) {
333 		thread->machine.tpidr2_el0 = __builtin_arm_rsr64("TPIDR2_EL0");
334 	}
335 	state_out->tpidr2_el0 = thread->machine.tpidr2_el0;
336 
337 	arm_sme_saved_state_t *saved_state = machine_thread_get_sme_state(thread);
338 	if (!saved_state) {
339 		/* This thread has never used SME before, so all SME state is invalid */
340 		state_out->svcr = 0;
341 	} else {
342 		state_out->svcr = saved_state->svcr;
343 	}
344 
345 	*count = ARM_SME_STATE_COUNT;
346 	return KERN_SUCCESS;
347 }
348 
349 static kern_return_t
handle_get_arm_sve_z_state(thread_state_t tstate,mach_msg_type_number_t * count,thread_t thread,size_t z_offset)350 handle_get_arm_sve_z_state(thread_state_t tstate, mach_msg_type_number_t *count, thread_t thread, size_t z_offset)
351 {
352 	if (*count < ARM_SVE_Z_STATE_COUNT) {
353 		return KERN_INVALID_ARGUMENT;
354 	}
355 
356 	arm_sme_saved_state_t *saved_state = machine_thread_get_sme_state(thread);
357 	if (!saved_state) {
358 		return KERN_INVALID_ARGUMENT;
359 	}
360 	if (!(saved_state->svcr & SVCR_SM)) {
361 		return KERN_INVALID_ARGUMENT;
362 	}
363 
364 	arm_sve_z_state_t *state_out = (arm_sve_z_state_t *)tstate;
365 	const size_t elem_size = saved_state->svl_b;
366 	const uint8_t *saved_state_z = const_arm_sme_z(&saved_state->context) + z_offset * elem_size;
367 
368 	const size_t padding_size = sizeof(state_out->z[0]) - elem_size;
369 	for (int i = 0; i < ARRAY_COUNT(state_out->z); i++) {
370 		bcopy(saved_state_z, state_out->z[i], elem_size);
371 		if (padding_size) {
372 			bzero(state_out->z[i] + elem_size, padding_size);
373 		}
374 		saved_state_z += elem_size;
375 	}
376 
377 	*count = ARM_SVE_Z_STATE_COUNT;
378 	return KERN_SUCCESS;
379 }
380 
381 static kern_return_t
handle_get_arm_sve_p_state(thread_state_t tstate,mach_msg_type_number_t * count,thread_t thread)382 handle_get_arm_sve_p_state(thread_state_t tstate, mach_msg_type_number_t *count, thread_t thread)
383 {
384 	if (*count < ARM_SVE_P_STATE_COUNT) {
385 		return KERN_INVALID_ARGUMENT;
386 	}
387 
388 	arm_sme_saved_state_t *saved_state = machine_thread_get_sme_state(thread);
389 	if (!saved_state) {
390 		return KERN_INVALID_ARGUMENT;
391 	}
392 	if (!(saved_state->svcr & SVCR_SM)) {
393 		return KERN_INVALID_ARGUMENT;
394 	}
395 
396 	arm_sve_p_state_t *state_out = (arm_sve_p_state_t *)tstate;
397 	const uint8_t *saved_state_p = const_arm_sme_p(&saved_state->context, saved_state->svl_b);
398 
399 	const size_t elem_size = saved_state->svl_b / 8;
400 	const size_t padding_size = sizeof(state_out->p[0]) - elem_size;
401 	for (int i = 0; i < ARRAY_COUNT(state_out->p); i++) {
402 		bcopy(saved_state_p, state_out->p[i], elem_size);
403 		if (padding_size) {
404 			bzero(state_out->p[i] + elem_size, padding_size);
405 		}
406 		saved_state_p += elem_size;
407 	}
408 
409 	*count = ARM_SVE_P_STATE_COUNT;
410 	return KERN_SUCCESS;
411 }
412 
413 static kern_return_t
handle_get_arm_za_state(thread_state_t tstate,mach_msg_type_number_t * count,thread_t thread)414 handle_get_arm_za_state(thread_state_t tstate, mach_msg_type_number_t *count, thread_t thread)
415 {
416 	if (*count < ARM_SME_ZA_STATE_COUNT) {
417 		return KERN_INVALID_ARGUMENT;
418 	}
419 
420 	arm_sme_saved_state_t *saved_state = machine_thread_get_sme_state(thread);
421 	if (!saved_state) {
422 		return KERN_INVALID_ARGUMENT;
423 	}
424 	if (!(saved_state->svcr & SVCR_ZA)) {
425 		return KERN_INVALID_ARGUMENT;
426 	}
427 
428 	if (thread == current_thread()) {
429 		arm_save_sme_za(&saved_state->context, saved_state->svl_b);
430 	}
431 
432 	const uint8_t *saved_state_za = const_arm_sme_za(&saved_state->context, saved_state->svl_b);
433 	size_t za_size = saved_state->svl_b * saved_state->svl_b;
434 	arm_sme_za_state_t *state_out = (arm_sme_za_state_t *)tstate;
435 	assert(za_size <= sizeof(state_out->za));
436 
437 	bcopy(saved_state_za, state_out->za, za_size);
438 	if (za_size < sizeof(state_out->za)) {
439 		bzero(state_out->za + za_size, sizeof(state_out->za) - za_size);
440 	}
441 
442 	*count = ARM_SME_ZA_STATE_COUNT;
443 	return KERN_SUCCESS;
444 }
445 
446 static kern_return_t
handle_set_arm_sme_state(const thread_state_t tstate,mach_msg_type_number_t count,thread_t thread)447 handle_set_arm_sme_state(const thread_state_t tstate, mach_msg_type_number_t count, thread_t thread)
448 {
449 	if (!arm_sme_version()) {
450 		return KERN_INVALID_ARGUMENT;
451 	}
452 
453 	if (count < ARM_SME_STATE_COUNT) {
454 		return KERN_INVALID_ARGUMENT;
455 	}
456 
457 	const arm_sme_state_t *state_in = (const arm_sme_state_t *)tstate;
458 	uint16_t svl_b = arm_sme_svl_b();
459 	if (state_in->svl_b != svl_b) {
460 		/* arm_sme_state_t::svl_b is currently read-only */
461 		return KERN_INVALID_ARGUMENT;
462 	}
463 
464 	arm_sme_saved_state_t *saved_state = machine_thread_get_sme_state(thread);
465 	if (!saved_state) {
466 		kern_return_t err = machine_thread_sme_state_alloc(thread);
467 		if (err) {
468 			return err;
469 		}
470 		saved_state = machine_thread_get_sme_state(thread);
471 		assert(saved_state);
472 	}
473 
474 	saved_state->svcr = state_in->svcr & (SVCR_SM | SVCR_ZA);
475 	thread->machine.tpidr2_el0 = state_in->tpidr2_el0;
476 	/*
477 	 * Like in handle_get_arm_sme_state(), if we're accessing live TPIDR2_EL0, ZA,
478 	 * or ZT0 state then we need to explicitly synchronize the saved-state with
479 	 * hardware.
480 	 */
481 	if (thread == current_thread()) {
482 		__builtin_arm_wsr64("TPIDR2_EL0", state_in->tpidr2_el0);
483 	}
484 	return KERN_SUCCESS;
485 }
486 
487 static kern_return_t
handle_set_arm_sve_z_state(const thread_state_t tstate,mach_msg_type_number_t count,thread_t thread,size_t z_offset)488 handle_set_arm_sve_z_state(const thread_state_t tstate, mach_msg_type_number_t count, thread_t thread, size_t z_offset)
489 {
490 	if (count < ARM_SVE_Z_STATE_COUNT) {
491 		return KERN_INVALID_ARGUMENT;
492 	}
493 
494 	arm_sme_saved_state_t *saved_state = machine_thread_get_sme_state(thread);
495 	if (!saved_state) {
496 		return KERN_INVALID_ARGUMENT;
497 	}
498 	if (!(saved_state->svcr & SVCR_SM)) {
499 		return KERN_INVALID_ARGUMENT;
500 	}
501 
502 	const arm_sve_z_state_t *state_in = (const arm_sve_z_state_t *)tstate;
503 	const size_t elem_size = saved_state->svl_b;
504 	uint8_t *saved_state_z = arm_sme_z(&saved_state->context) + z_offset * elem_size;
505 
506 	for (int i = 0; i < ARRAY_COUNT(state_in->z); i++) {
507 		bcopy(state_in->z[i], saved_state_z, elem_size);
508 		saved_state_z += elem_size;
509 	}
510 
511 	return KERN_SUCCESS;
512 }
513 
514 static kern_return_t
handle_set_arm_sve_p_state(const thread_state_t tstate,mach_msg_type_number_t count,thread_t thread)515 handle_set_arm_sve_p_state(const thread_state_t tstate, mach_msg_type_number_t count, thread_t thread)
516 {
517 	if (count < ARM_SVE_P_STATE_COUNT) {
518 		return KERN_INVALID_ARGUMENT;
519 	}
520 
521 	arm_sme_saved_state_t *saved_state = machine_thread_get_sme_state(thread);
522 	if (!saved_state) {
523 		return KERN_INVALID_ARGUMENT;
524 	}
525 	if (!(saved_state->svcr & SVCR_SM)) {
526 		return KERN_INVALID_ARGUMENT;
527 	}
528 
529 	const arm_sve_p_state_t *state_in = (const arm_sve_p_state_t *)tstate;
530 	uint8_t *saved_state_p = arm_sme_p(&saved_state->context, saved_state->svl_b);
531 
532 	const size_t elem_size = saved_state->svl_b / 8;
533 	for (int i = 0; i < ARRAY_COUNT(state_in->p); i++) {
534 		bcopy(state_in->p[i], saved_state_p, elem_size);
535 		saved_state_p += elem_size;
536 	}
537 
538 	return KERN_SUCCESS;
539 }
540 
541 static kern_return_t
handle_set_arm_za_state(const thread_state_t tstate,mach_msg_type_number_t count,thread_t thread)542 handle_set_arm_za_state(const thread_state_t tstate, mach_msg_type_number_t count, thread_t thread)
543 {
544 	if (count < ARM_SME_ZA_STATE_COUNT) {
545 		return KERN_INVALID_ARGUMENT;
546 	}
547 
548 	arm_sme_saved_state_t *saved_state = machine_thread_get_sme_state(thread);
549 	if (!saved_state) {
550 		return KERN_INVALID_ARGUMENT;
551 	}
552 	if (!(saved_state->svcr & SVCR_ZA)) {
553 		return KERN_INVALID_ARGUMENT;
554 	}
555 
556 	uint8_t *saved_state_za = arm_sme_za(&saved_state->context, saved_state->svl_b);
557 	size_t za_size = saved_state->svl_b * saved_state->svl_b;
558 	const arm_sme_za_state_t *state_in = (const arm_sme_za_state_t *)tstate;
559 	assert(za_size <= sizeof(state_in->za));
560 
561 	bcopy(state_in->za, saved_state_za, za_size);
562 	if (thread == current_thread()) {
563 		arm_load_sme_za(&saved_state->context, saved_state->svl_b);
564 	}
565 
566 	return KERN_SUCCESS;
567 }
568 
569 #if HAS_ARM_FEAT_SME2
570 static kern_return_t
handle_get_arm_sme2_state(thread_state_t tstate,mach_msg_type_number_t * count,thread_t thread)571 handle_get_arm_sme2_state(thread_state_t tstate, mach_msg_type_number_t *count, thread_t thread)
572 {
573 	if (arm_sme_version() < ARM_FEAT_SME2) {
574 		return KERN_INVALID_ARGUMENT;
575 	}
576 
577 	if (*count < ARM_SME2_STATE_COUNT) {
578 		return KERN_INVALID_ARGUMENT;
579 	}
580 
581 	arm_sme_saved_state_t *saved_state = machine_thread_get_sme_state(thread);
582 	if (!saved_state) {
583 		return KERN_INVALID_ARGUMENT;
584 	}
585 
586 	if ((saved_state->svcr & SVCR_ZA) == 0) {
587 		return KERN_INVALID_ARGUMENT;
588 	}
589 
590 	arm_sme2_state_t *sme2_tstate = (arm_sme2_state_t *)tstate;
591 	if (thread == current_thread()) {
592 		arm_save_sme_zt0(&saved_state->context);
593 	}
594 	memcpy(sme2_tstate->zt0, saved_state->context.zt0, sizeof(saved_state->context.zt0));
595 
596 	*count = ARM_SME2_STATE_COUNT;
597 	return KERN_SUCCESS;
598 }
599 
600 static kern_return_t
handle_set_arm_sme2_state(const thread_state_t tstate,mach_msg_type_number_t count,thread_t thread)601 handle_set_arm_sme2_state(const thread_state_t tstate, mach_msg_type_number_t count, thread_t thread)
602 {
603 	if (arm_sme_version() < ARM_FEAT_SME2) {
604 		return KERN_INVALID_ARGUMENT;
605 	}
606 
607 	arm_sme_saved_state_t *saved_state = machine_thread_get_sme_state(thread);
608 	if (!saved_state) {
609 		return KERN_INVALID_ARGUMENT;
610 	}
611 
612 	if (count < ARM_SME2_STATE_COUNT) {
613 		return KERN_INVALID_ARGUMENT;
614 	}
615 
616 	if ((saved_state->svcr & SVCR_ZA) == 0) {
617 		return KERN_INVALID_ARGUMENT;
618 	}
619 
620 	const arm_sme2_state_t *sme2_tstate = (const arm_sme2_state_t *)tstate;
621 	memcpy(saved_state->context.zt0, sme2_tstate->zt0, sizeof(saved_state->context.zt0));
622 	if (thread == current_thread()) {
623 		arm_load_sme_zt0(&saved_state->context);
624 	}
625 	return KERN_SUCCESS;
626 }
627 #endif /* HAS_ARM_FEAT_SME2 */
628 #endif /* HAS_ARM_FEAT_SME */
629 
630 #if __has_feature(ptrauth_calls)
631 
632 static inline uint32_t
thread_generate_sigreturn_token(void * ptr,thread_t thread)633 thread_generate_sigreturn_token(
634 	void *ptr,
635 	thread_t thread)
636 {
637 	user64_addr_t token = (user64_addr_t)ptr;
638 	token ^= (user64_addr_t)thread_get_sigreturn_token(thread);
639 	token = (user64_addr_t)pmap_sign_user_ptr((void*)token,
640 	    ptrauth_key_process_independent_data, ptrauth_string_discriminator("nonce"),
641 	    thread->machine.jop_pid);
642 	token >>= 32;
643 	return (uint32_t)token;
644 }
645 #endif //__has_feature(ptrauth_calls)
646 
647 /*
648  * Translate thread state arguments to userspace representation
649  */
650 
651 kern_return_t
machine_thread_state_convert_to_user(thread_t thread,thread_flavor_t flavor,thread_state_t tstate,mach_msg_type_number_t * count,thread_set_status_flags_t tssf_flags)652 machine_thread_state_convert_to_user(
653 	thread_t thread,
654 	thread_flavor_t flavor,
655 	thread_state_t tstate,
656 	mach_msg_type_number_t *count,
657 	thread_set_status_flags_t tssf_flags)
658 {
659 #if __has_feature(ptrauth_calls)
660 	arm_thread_state64_t *ts64;
661 	bool preserve_flags = !!(tssf_flags & TSSF_PRESERVE_FLAGS);
662 	bool stash_sigreturn_token = !!(tssf_flags & TSSF_STASH_SIGRETURN_TOKEN);
663 	bool random_div = !!(tssf_flags & TSSF_RANDOM_USER_DIV);
664 	bool thread_div = !!(tssf_flags & TSSF_THREAD_USER_DIV);
665 	bool task_div = !!(tssf_flags & TSSF_TASK_USER_DIV);
666 	uint32_t old_flags;
667 	bool kernel_signed_pc = true;
668 	bool kernel_signed_lr = true;
669 	uint32_t userland_diversifier = 0;
670 
671 	switch (flavor) {
672 	case ARM_THREAD_STATE:
673 	{
674 		arm_unified_thread_state_t *unified_state = (arm_unified_thread_state_t *)tstate;
675 
676 		if (*count < ARM_UNIFIED_THREAD_STATE_COUNT || !is_thread_state64(unified_state)) {
677 			return KERN_SUCCESS;
678 		}
679 		ts64 = thread_state64(unified_state);
680 		break;
681 	}
682 	case ARM_THREAD_STATE64:
683 	{
684 		if (*count < ARM_THREAD_STATE64_COUNT) {
685 			return KERN_SUCCESS;
686 		}
687 		ts64 = (arm_thread_state64_t *)tstate;
688 		break;
689 	}
690 	default:
691 		return KERN_SUCCESS;
692 	}
693 
694 	// Note that kernel threads never have disable_user_jop set
695 	if ((current_thread()->machine.arm_machine_flags & ARM_MACHINE_THREAD_DISABLE_USER_JOP) ||
696 	    !thread_is_64bit_addr(current_thread()) ||
697 	    (thread->machine.arm_machine_flags & ARM_MACHINE_THREAD_DISABLE_USER_JOP) || !thread_is_64bit_addr(thread)
698 	    ) {
699 		ts64->flags = __DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH;
700 		return KERN_SUCCESS;
701 	}
702 
703 	old_flags = ts64->flags;
704 	ts64->flags = 0;
705 	if (ts64->lr) {
706 		// lr might contain an IB-signed return address (strip is a no-op on unsigned addresses)
707 		uintptr_t stripped_lr = (uintptr_t)ptrauth_strip((void *)ts64->lr,
708 		    ptrauth_key_return_address);
709 		if (ts64->lr != stripped_lr) {
710 			// Need to allow already-signed lr value to round-trip as is
711 			ts64->flags |= __DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR;
712 		}
713 		// Note that an IB-signed return address that happens to have a 0 signature value
714 		// will round-trip correctly even if IA-signed again below (and IA-authd later)
715 	}
716 
717 	if (arm_user_jop_disabled()) {
718 		return KERN_SUCCESS;
719 	}
720 
721 	if (preserve_flags) {
722 		assert(random_div == false);
723 		assert(thread_div == false);
724 
725 		/* Restore the diversifier and other opaque flags */
726 		ts64->flags |= (old_flags & __DARWIN_ARM_THREAD_STATE64_USER_DIVERSIFIER_MASK);
727 		userland_diversifier = old_flags & __DARWIN_ARM_THREAD_STATE64_USER_DIVERSIFIER_MASK;
728 		if (!(old_flags & __DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_PC)) {
729 			kernel_signed_pc = false;
730 		}
731 		if (!(old_flags & __DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_LR)) {
732 			kernel_signed_lr = false;
733 		}
734 	} else {
735 		/* Set a non zero userland diversifier */
736 		if (random_div || task_div) {
737 			/* Still use random div in case of task_div to avoid leaking the secret key */
738 			do {
739 				read_random(&userland_diversifier, sizeof(userland_diversifier));
740 				userland_diversifier &=
741 				    __DARWIN_ARM_THREAD_STATE64_USER_DIVERSIFIER_MASK;
742 			} while (userland_diversifier == 0);
743 		} else if (thread_div) {
744 			userland_diversifier = thread_get_sigreturn_diversifier(thread) &
745 			    __DARWIN_ARM_THREAD_STATE64_USER_DIVERSIFIER_MASK;
746 		}
747 		ts64->flags |= userland_diversifier;
748 	}
749 
750 	if (kernel_signed_pc) {
751 		ts64->flags |= __DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_PC;
752 	}
753 
754 	if (kernel_signed_lr) {
755 		ts64->flags |= __DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_LR;
756 	}
757 
758 
759 	if (ts64->pc) {
760 		uint64_t discriminator = ptrauth_string_discriminator("pc");
761 		if (!kernel_signed_pc && userland_diversifier != 0) {
762 			discriminator = ptrauth_blend_discriminator((void *)(long)userland_diversifier,
763 			    ptrauth_string_discriminator("pc"));
764 		}
765 
766 		ts64->pc = (uintptr_t)pmap_sign_user_ptr((void*)ts64->pc,
767 		    ptrauth_key_process_independent_code, discriminator,
768 		    thread->machine.jop_pid);
769 	}
770 	if (ts64->lr && !(ts64->flags & __DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR)) {
771 		uint64_t discriminator = ptrauth_string_discriminator("lr");
772 		if (!kernel_signed_lr && userland_diversifier != 0) {
773 			discriminator = ptrauth_blend_discriminator((void *)(long)userland_diversifier,
774 			    ptrauth_string_discriminator("lr"));
775 		}
776 
777 		ts64->lr = (uintptr_t)pmap_sign_user_ptr((void*)ts64->lr,
778 		    ptrauth_key_process_independent_code, discriminator,
779 		    thread->machine.jop_pid);
780 	}
781 	if (ts64->sp) {
782 		ts64->sp = (uintptr_t)pmap_sign_user_ptr((void*)ts64->sp,
783 		    ptrauth_key_process_independent_data, ptrauth_string_discriminator("sp"),
784 		    thread->machine.jop_pid);
785 	}
786 	if (ts64->fp) {
787 		ts64->fp = (uintptr_t)pmap_sign_user_ptr((void*)ts64->fp,
788 		    ptrauth_key_process_independent_data, ptrauth_string_discriminator("fp"),
789 		    thread->machine.jop_pid);
790 	}
791 
792 	/* Stash the sigreturn token */
793 	if (stash_sigreturn_token) {
794 		if (kernel_signed_pc) {
795 			uint32_t token = thread_generate_sigreturn_token((void *)ts64->pc, thread);
796 			__DARWIN_ARM_THREAD_STATE64_SET_SIGRETURN_TOKEN(ts64, token,
797 			    __DARWIN_ARM_THREAD_STATE64_SIGRETURN_PC_MASK);
798 		}
799 
800 		if (kernel_signed_lr) {
801 			uint32_t token = thread_generate_sigreturn_token((void *)ts64->lr, thread);
802 			__DARWIN_ARM_THREAD_STATE64_SET_SIGRETURN_TOKEN(ts64, token,
803 			    __DARWIN_ARM_THREAD_STATE64_SIGRETURN_LR_MASK);
804 		}
805 	}
806 
807 	return KERN_SUCCESS;
808 #else
809 	// No conversion to userspace representation on this platform
810 	(void)thread; (void)flavor; (void)tstate; (void)count; (void)tssf_flags;
811 	return KERN_SUCCESS;
812 #endif /* __has_feature(ptrauth_calls) */
813 }
814 
815 #if __has_feature(ptrauth_calls)
816 extern char *   proc_name_address(void *p);
817 
818 CA_EVENT(pac_thread_state_exception_event,
819     CA_STATIC_STRING(CA_PROCNAME_LEN), proc_name);
820 
821 static void
machine_thread_state_check_pac_state(arm_thread_state64_t * ts64,arm_thread_state64_t * old_ts64)822 machine_thread_state_check_pac_state(
823 	arm_thread_state64_t *ts64,
824 	arm_thread_state64_t *old_ts64)
825 {
826 	bool send_event = false;
827 	task_t task = current_task();
828 	void *proc = get_bsdtask_info(task);
829 	char *proc_name = (char *) "unknown";
830 
831 	if (((ts64->flags & __DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_PC) &&
832 	    ts64->pc != old_ts64->pc) || (!(ts64->flags & __DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR) &&
833 	    (ts64->flags & __DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_LR) && (ts64->lr != old_ts64->lr ||
834 	    (old_ts64->flags & __DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR)))) {
835 		send_event = true;
836 	}
837 
838 	if (!send_event) {
839 		return;
840 	}
841 
842 	proc_name = proc_name_address(proc);
843 	ca_event_t ca_event = CA_EVENT_ALLOCATE(pac_thread_state_exception_event);
844 	CA_EVENT_TYPE(pac_thread_state_exception_event) * pexc_event = ca_event->data;
845 	strlcpy(pexc_event->proc_name, proc_name, CA_PROCNAME_LEN);
846 	CA_EVENT_SEND(ca_event);
847 }
848 
849 CA_EVENT(pac_thread_state_sigreturn_event,
850     CA_STATIC_STRING(CA_PROCNAME_LEN), proc_name);
851 
852 static bool
machine_thread_state_check_sigreturn_token(arm_thread_state64_t * ts64,thread_t thread)853 machine_thread_state_check_sigreturn_token(
854 	arm_thread_state64_t *ts64,
855 	thread_t thread)
856 {
857 	task_t task = current_task();
858 	void *proc = get_bsdtask_info(task);
859 	char *proc_name = (char *) "unknown";
860 	bool token_matched = true;
861 	bool kernel_signed_pc = !!(ts64->flags & __DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_PC);
862 	bool kernel_signed_lr = !!(ts64->flags & __DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_LR);
863 
864 	if (kernel_signed_pc) {
865 		/* Compute the sigreturn token */
866 		uint32_t token = thread_generate_sigreturn_token((void *)ts64->pc, thread);
867 		if (!__DARWIN_ARM_THREAD_STATE64_CHECK_SIGRETURN_TOKEN(ts64, token,
868 		    __DARWIN_ARM_THREAD_STATE64_SIGRETURN_PC_MASK)) {
869 			token_matched = false;
870 		}
871 	}
872 
873 	if (kernel_signed_lr) {
874 		/* Compute the sigreturn token */
875 		uint32_t token = thread_generate_sigreturn_token((void *)ts64->lr, thread);
876 		if (!__DARWIN_ARM_THREAD_STATE64_CHECK_SIGRETURN_TOKEN(ts64, token,
877 		    __DARWIN_ARM_THREAD_STATE64_SIGRETURN_LR_MASK)) {
878 			token_matched = false;
879 		}
880 	}
881 
882 	if (token_matched) {
883 		return true;
884 	}
885 
886 	proc_name = proc_name_address(proc);
887 	ca_event_t ca_event = CA_EVENT_ALLOCATE(pac_thread_state_sigreturn_event);
888 	CA_EVENT_TYPE(pac_thread_state_sigreturn_event) * psig_event = ca_event->data;
889 	strlcpy(psig_event->proc_name, proc_name, CA_PROCNAME_LEN);
890 	CA_EVENT_SEND(ca_event);
891 	return false;
892 }
893 
894 #endif
895 
896 /*
897  * Translate thread state arguments from userspace representation
898  */
899 
900 kern_return_t
machine_thread_state_convert_from_user(thread_t thread,thread_flavor_t flavor,thread_state_t tstate,mach_msg_type_number_t count,thread_state_t old_tstate,mach_msg_type_number_t old_count,thread_set_status_flags_t tssf_flags)901 machine_thread_state_convert_from_user(
902 	thread_t thread,
903 	thread_flavor_t flavor,
904 	thread_state_t tstate,
905 	mach_msg_type_number_t count,
906 	thread_state_t old_tstate,
907 	mach_msg_type_number_t old_count,
908 	thread_set_status_flags_t tssf_flags)
909 {
910 	arm_thread_state64_t *ts64;
911 	arm_thread_state64_t *old_ts64 = NULL;
912 	bool only_set_pc = !!(tssf_flags & TSSF_ONLY_PC);
913 
914 	switch (flavor) {
915 	case ARM_THREAD_STATE:
916 	{
917 		arm_unified_thread_state_t *unified_state = (arm_unified_thread_state_t *)tstate;
918 
919 		if (count < ARM_UNIFIED_THREAD_STATE_COUNT || !is_thread_state64(unified_state)) {
920 			return KERN_SUCCESS;
921 		}
922 		ts64 = thread_state64(unified_state);
923 
924 		arm_unified_thread_state_t *old_unified_state = (arm_unified_thread_state_t *)old_tstate;
925 		if (old_unified_state && old_count >= ARM_UNIFIED_THREAD_STATE_COUNT) {
926 			old_ts64 = thread_state64(old_unified_state);
927 		}
928 		break;
929 	}
930 	case ARM_THREAD_STATE64:
931 	{
932 		if (count != ARM_THREAD_STATE64_COUNT) {
933 			return KERN_SUCCESS;
934 		}
935 		ts64 = (arm_thread_state64_t *)tstate;
936 
937 		if (old_count == ARM_THREAD_STATE64_COUNT) {
938 			old_ts64 = (arm_thread_state64_t *)old_tstate;
939 		}
940 		break;
941 	}
942 	default:
943 		return KERN_SUCCESS;
944 	}
945 
946 	if (only_set_pc) {
947 		uint64_t new_pc = ts64->pc;
948 		uint64_t new_flags = ts64->flags;
949 		/* Only allow pc to be modified in new_state */
950 		memcpy(ts64, old_ts64, sizeof(arm_thread_state64_t));
951 		ts64->pc = new_pc;
952 		ts64->flags = new_flags;
953 	}
954 
955 #if __has_feature(ptrauth_calls)
956 
957 	void *userland_diversifier = NULL;
958 	bool kernel_signed_pc;
959 	bool kernel_signed_lr;
960 	bool random_div = !!(tssf_flags & TSSF_RANDOM_USER_DIV);
961 	bool thread_div = !!(tssf_flags & TSSF_THREAD_USER_DIV);
962 	bool task_div = !!(tssf_flags & TSSF_TASK_USER_DIV);
963 
964 	// Note that kernel threads never have disable_user_jop set
965 	if ((current_thread()->machine.arm_machine_flags & ARM_MACHINE_THREAD_DISABLE_USER_JOP) ||
966 	    !thread_is_64bit_addr(current_thread())) {
967 		if ((thread->machine.arm_machine_flags & ARM_MACHINE_THREAD_DISABLE_USER_JOP) ||
968 		    !thread_is_64bit_addr(thread)) {
969 			ts64->flags = __DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH;
970 			return KERN_SUCCESS;
971 		}
972 		// A JOP-disabled process must not set thread state on a JOP-enabled process
973 		return KERN_PROTECTION_FAILURE;
974 	}
975 
976 	if (ts64->flags & __DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH) {
977 		if ((thread->machine.arm_machine_flags & ARM_MACHINE_THREAD_DISABLE_USER_JOP) ||
978 		    !thread_is_64bit_addr(thread)
979 		    ) {
980 			return KERN_SUCCESS;
981 		}
982 		// Disallow setting unsigned thread state on JOP-enabled processes.
983 		// Ignore flag and treat thread state arguments as signed, ptrauth
984 		// poisoning will cause resulting thread state to be invalid
985 		ts64->flags &= ~__DARWIN_ARM_THREAD_STATE64_FLAGS_NO_PTRAUTH;
986 	}
987 
988 	if (ts64->flags & __DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR) {
989 		// lr might contain an IB-signed return address (strip is a no-op on unsigned addresses)
990 		uintptr_t stripped_lr = (uintptr_t)ptrauth_strip((void *)ts64->lr,
991 		    ptrauth_key_return_address);
992 		if (ts64->lr == stripped_lr) {
993 			// Don't allow unsigned pointer to be passed through as is. Ignore flag and
994 			// treat as IA-signed below (where auth failure may poison the value).
995 			ts64->flags &= ~__DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR;
996 		}
997 		// Note that an IB-signed return address that happens to have a 0 signature value
998 		// will also have been IA-signed (without this flag being set) and so will IA-auth
999 		// correctly below.
1000 	}
1001 
1002 	if (arm_user_jop_disabled()) {
1003 		return KERN_SUCCESS;
1004 	}
1005 
1006 	kernel_signed_pc = !!(ts64->flags & __DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_PC);
1007 	kernel_signed_lr = !!(ts64->flags & __DARWIN_ARM_THREAD_STATE64_FLAGS_KERNEL_SIGNED_LR);
1008 	/*
1009 	 * Replace pc/lr with old state if allow only
1010 	 * user ptr flag is passed and ptrs are marked
1011 	 * kernel signed.
1012 	 */
1013 	if ((tssf_flags & TSSF_CHECK_USER_FLAGS) &&
1014 	    (kernel_signed_pc || kernel_signed_lr)) {
1015 		if (old_ts64 && old_count == count) {
1016 			/* Send a CA event if the thread state does not match */
1017 			machine_thread_state_check_pac_state(ts64, old_ts64);
1018 
1019 			/* Check if user ptrs needs to be replaced */
1020 			if ((tssf_flags & TSSF_ALLOW_ONLY_USER_PTRS) &&
1021 			    kernel_signed_pc) {
1022 				ts64->pc = old_ts64->pc;
1023 			}
1024 
1025 			if ((tssf_flags & TSSF_ALLOW_ONLY_USER_PTRS) &&
1026 			    !(ts64->flags & __DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR) &&
1027 			    kernel_signed_lr) {
1028 				ts64->lr = old_ts64->lr;
1029 				if (old_ts64->flags & __DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR) {
1030 					ts64->flags |= __DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR;
1031 				} else {
1032 					ts64->flags &= ~__DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR;
1033 				}
1034 			}
1035 		}
1036 	}
1037 
1038 	/* Validate sigreturn token */
1039 	if (tssf_flags & TSSF_CHECK_SIGRETURN_TOKEN) {
1040 		bool token_matched = machine_thread_state_check_sigreturn_token(ts64, thread);
1041 		if ((tssf_flags & TSSF_ALLOW_ONLY_MATCHING_TOKEN) && !token_matched) {
1042 			return KERN_PROTECTION_FAILURE;
1043 		}
1044 	}
1045 
1046 	/* Get the userland diversifier */
1047 	if (random_div && old_ts64 && old_count == count) {
1048 		/* Get the random diversifier from the old thread state */
1049 		userland_diversifier = (void *)(long)(old_ts64->flags &
1050 		    __DARWIN_ARM_THREAD_STATE64_USER_DIVERSIFIER_MASK);
1051 	} else if (thread_div) {
1052 		userland_diversifier = (void *)(long)(thread_get_sigreturn_diversifier(thread) &
1053 		    __DARWIN_ARM_THREAD_STATE64_USER_DIVERSIFIER_MASK);
1054 	} else if (task_div) {
1055 		userland_diversifier =
1056 		    (void *)(long)((get_threadtask(thread)->hardened_exception_action.signed_pc_key) &
1057 		    __DARWIN_ARM_THREAD_STATE64_USER_DIVERSIFIER_MASK);
1058 	}
1059 
1060 	if (ts64->pc) {
1061 		uint64_t discriminator = ptrauth_string_discriminator("pc");
1062 		if (!kernel_signed_pc && userland_diversifier != 0) {
1063 			discriminator = ptrauth_blend_discriminator(userland_diversifier,
1064 			    ptrauth_string_discriminator("pc"));
1065 		}
1066 		ts64->pc = (uintptr_t)pmap_auth_user_ptr((void*)ts64->pc,
1067 		    ptrauth_key_process_independent_code, discriminator,
1068 		    thread->machine.jop_pid);
1069 	}
1070 	if (ts64->lr && !(ts64->flags & __DARWIN_ARM_THREAD_STATE64_FLAGS_IB_SIGNED_LR)) {
1071 		uint64_t discriminator = ptrauth_string_discriminator("lr");
1072 		if (!kernel_signed_lr && userland_diversifier != 0) {
1073 			discriminator = ptrauth_blend_discriminator(userland_diversifier,
1074 			    ptrauth_string_discriminator("lr"));
1075 		}
1076 		ts64->lr = (uintptr_t)pmap_auth_user_ptr((void*)ts64->lr,
1077 		    ptrauth_key_process_independent_code, discriminator,
1078 		    thread->machine.jop_pid);
1079 	}
1080 	if (ts64->sp) {
1081 		ts64->sp = (uintptr_t)pmap_auth_user_ptr((void*)ts64->sp,
1082 		    ptrauth_key_process_independent_data, ptrauth_string_discriminator("sp"),
1083 		    thread->machine.jop_pid);
1084 	}
1085 	if (ts64->fp) {
1086 		ts64->fp = (uintptr_t)pmap_auth_user_ptr((void*)ts64->fp,
1087 		    ptrauth_key_process_independent_data, ptrauth_string_discriminator("fp"),
1088 		    thread->machine.jop_pid);
1089 	}
1090 
1091 	return KERN_SUCCESS;
1092 #else
1093 	// No conversion from userspace representation on this platform
1094 	(void)thread; (void)flavor; (void)tstate; (void)count;
1095 	(void)old_tstate; (void)old_count; (void)tssf_flags;
1096 	return KERN_SUCCESS;
1097 #endif /* __has_feature(ptrauth_calls) */
1098 }
1099 
1100 #if __has_feature(ptrauth_calls)
1101 bool
machine_thread_state_is_debug_flavor(int flavor)1102 machine_thread_state_is_debug_flavor(int flavor)
1103 {
1104 	if (flavor == ARM_DEBUG_STATE ||
1105 	    flavor == ARM_DEBUG_STATE64 ||
1106 	    flavor == ARM_DEBUG_STATE32) {
1107 		return true;
1108 	}
1109 	return false;
1110 }
1111 #endif /* __has_feature(ptrauth_calls) */
1112 
1113 /*
1114  * Translate signal context data pointer to userspace representation
1115  */
1116 
1117 kern_return_t
machine_thread_siguctx_pointer_convert_to_user(thread_t thread,user_addr_t * uctxp)1118 machine_thread_siguctx_pointer_convert_to_user(
1119 	thread_t thread,
1120 	user_addr_t *uctxp)
1121 {
1122 #if __has_feature(ptrauth_calls)
1123 	if ((current_thread()->machine.arm_machine_flags & ARM_MACHINE_THREAD_DISABLE_USER_JOP) ||
1124 	    !thread_is_64bit_addr(current_thread())) {
1125 		assert((thread->machine.arm_machine_flags & ARM_MACHINE_THREAD_DISABLE_USER_JOP) || !thread_is_64bit_addr(thread));
1126 		return KERN_SUCCESS;
1127 	}
1128 
1129 	if (arm_user_jop_disabled()) {
1130 		return KERN_SUCCESS;
1131 	}
1132 
1133 	if (*uctxp) {
1134 		*uctxp = (uintptr_t)pmap_sign_user_ptr((void*)*uctxp,
1135 		    ptrauth_key_process_independent_data, ptrauth_string_discriminator("uctx"),
1136 		    thread->machine.jop_pid);
1137 	}
1138 
1139 	return KERN_SUCCESS;
1140 #else
1141 	// No conversion to userspace representation on this platform
1142 	(void)thread; (void)uctxp;
1143 	return KERN_SUCCESS;
1144 #endif /* __has_feature(ptrauth_calls) */
1145 }
1146 
1147 /*
1148  * Translate array of function pointer syscall arguments from userspace representation
1149  */
1150 
1151 kern_return_t
machine_thread_function_pointers_convert_from_user(thread_t thread,user_addr_t * fptrs,uint32_t count)1152 machine_thread_function_pointers_convert_from_user(
1153 	thread_t thread,
1154 	user_addr_t *fptrs,
1155 	uint32_t count)
1156 {
1157 #if __has_feature(ptrauth_calls)
1158 	if ((current_thread()->machine.arm_machine_flags & ARM_MACHINE_THREAD_DISABLE_USER_JOP) ||
1159 	    !thread_is_64bit_addr(current_thread())) {
1160 		assert((thread->machine.arm_machine_flags & ARM_MACHINE_THREAD_DISABLE_USER_JOP) ||
1161 		    !thread_is_64bit_addr(thread));
1162 		return KERN_SUCCESS;
1163 	}
1164 
1165 	if (arm_user_jop_disabled()) {
1166 		return KERN_SUCCESS;
1167 	}
1168 
1169 	while (count--) {
1170 		if (*fptrs) {
1171 			*fptrs = (uintptr_t)pmap_auth_user_ptr((void*)*fptrs,
1172 			    ptrauth_key_function_pointer, 0, thread->machine.jop_pid);
1173 		}
1174 		fptrs++;
1175 	}
1176 
1177 	return KERN_SUCCESS;
1178 #else
1179 	// No conversion from userspace representation on this platform
1180 	(void)thread; (void)fptrs; (void)count;
1181 	return KERN_SUCCESS;
1182 #endif /* __has_feature(ptrauth_calls) */
1183 }
1184 
1185 /*
1186  * Routine: machine_thread_get_state
1187  *
1188  */
1189 kern_return_t
machine_thread_get_state(thread_t thread,thread_flavor_t flavor,thread_state_t tstate,mach_msg_type_number_t * count)1190 machine_thread_get_state(thread_t                 thread,
1191     thread_flavor_t          flavor,
1192     thread_state_t           tstate,
1193     mach_msg_type_number_t * count)
1194 {
1195 	switch (flavor) {
1196 	case THREAD_STATE_FLAVOR_LIST:
1197 		if (*count < 4) {
1198 			return KERN_INVALID_ARGUMENT;
1199 		}
1200 
1201 		tstate[0] = ARM_THREAD_STATE;
1202 		tstate[1] = ARM_VFP_STATE;
1203 		tstate[2] = ARM_EXCEPTION_STATE;
1204 		tstate[3] = ARM_DEBUG_STATE;
1205 		*count = 4;
1206 		break;
1207 
1208 	case THREAD_STATE_FLAVOR_LIST_NEW:
1209 		if (*count < 4) {
1210 			return KERN_INVALID_ARGUMENT;
1211 		}
1212 
1213 		tstate[0] = ARM_THREAD_STATE;
1214 		tstate[1] = ARM_VFP_STATE;
1215 		tstate[2] = thread_is_64bit_data(thread) ? ARM_EXCEPTION_STATE64 : ARM_EXCEPTION_STATE;
1216 		tstate[3] = thread_is_64bit_data(thread) ? ARM_DEBUG_STATE64 : ARM_DEBUG_STATE32;
1217 		*count = 4;
1218 		break;
1219 
1220 	case THREAD_STATE_FLAVOR_LIST_10_15:
1221 		if (*count < 5) {
1222 			return KERN_INVALID_ARGUMENT;
1223 		}
1224 
1225 		tstate[0] = ARM_THREAD_STATE;
1226 		tstate[1] = ARM_VFP_STATE;
1227 		tstate[2] = thread_is_64bit_data(thread) ? ARM_EXCEPTION_STATE64 : ARM_EXCEPTION_STATE;
1228 		tstate[3] = thread_is_64bit_data(thread) ? ARM_DEBUG_STATE64 : ARM_DEBUG_STATE32;
1229 		tstate[4] = ARM_PAGEIN_STATE;
1230 		*count = 5;
1231 		break;
1232 
1233 	case ARM_THREAD_STATE:
1234 	{
1235 		kern_return_t rn = handle_get_arm_thread_state(tstate, count, thread->machine.upcb);
1236 		if (rn) {
1237 			return rn;
1238 		}
1239 		break;
1240 	}
1241 	case ARM_THREAD_STATE32:
1242 	{
1243 		if (thread_is_64bit_data(thread)) {
1244 			return KERN_INVALID_ARGUMENT;
1245 		}
1246 
1247 		kern_return_t rn = handle_get_arm32_thread_state(tstate, count, thread->machine.upcb);
1248 		if (rn) {
1249 			return rn;
1250 		}
1251 		break;
1252 	}
1253 #if __arm64__
1254 	case ARM_THREAD_STATE64:
1255 	{
1256 		if (!thread_is_64bit_data(thread)) {
1257 			return KERN_INVALID_ARGUMENT;
1258 		}
1259 
1260 		kern_return_t rn = handle_get_arm64_thread_state(tstate, count, thread->machine.upcb);
1261 		if (rn) {
1262 			return rn;
1263 		}
1264 
1265 		break;
1266 	}
1267 #endif
1268 	case ARM_EXCEPTION_STATE:{
1269 		struct arm_exception_state *state;
1270 		struct arm_saved_state32 *saved_state;
1271 
1272 		if (*count < ARM_EXCEPTION_STATE_COUNT) {
1273 			return KERN_INVALID_ARGUMENT;
1274 		}
1275 		if (thread_is_64bit_data(thread)) {
1276 			return KERN_INVALID_ARGUMENT;
1277 		}
1278 
1279 		state = (struct arm_exception_state *) tstate;
1280 		saved_state = saved_state32(thread->machine.upcb);
1281 
1282 		state->exception = saved_state->exception;
1283 		state->fsr = (uint32_t) saved_state->esr;
1284 		state->far = saved_state->far;
1285 
1286 		*count = ARM_EXCEPTION_STATE_COUNT;
1287 		break;
1288 	}
1289 	case ARM_EXCEPTION_STATE64:{
1290 		struct arm_exception_state64 *state;
1291 		struct arm_saved_state64 *saved_state;
1292 
1293 		if (*count < ARM_EXCEPTION_STATE64_COUNT) {
1294 			return KERN_INVALID_ARGUMENT;
1295 		}
1296 		if (!thread_is_64bit_data(thread)) {
1297 			return KERN_INVALID_ARGUMENT;
1298 		}
1299 
1300 		state = (struct arm_exception_state64 *) tstate;
1301 		saved_state = saved_state64(thread->machine.upcb);
1302 
1303 		state->exception = 0;
1304 		state->far = saved_state->far;
1305 		state->esr = (uint32_t) saved_state->esr;
1306 
1307 		*count = ARM_EXCEPTION_STATE64_COUNT;
1308 		break;
1309 	}
1310 	case ARM_EXCEPTION_STATE64_V2:{
1311 		struct arm_exception_state64_v2 *state;
1312 		struct arm_saved_state64 *saved_state;
1313 
1314 		if (*count < ARM_EXCEPTION_STATE64_V2_COUNT) {
1315 			return KERN_INVALID_ARGUMENT;
1316 		}
1317 		if (!thread_is_64bit_data(thread)) {
1318 			return KERN_INVALID_ARGUMENT;
1319 		}
1320 
1321 		state = (struct arm_exception_state64_v2 *) tstate;
1322 		saved_state = saved_state64(thread->machine.upcb);
1323 
1324 		state->far = saved_state->far;
1325 		state->esr = saved_state->esr;
1326 
1327 		*count = ARM_EXCEPTION_STATE64_V2_COUNT;
1328 		break;
1329 	}
1330 	case ARM_DEBUG_STATE:{
1331 		arm_legacy_debug_state_t *state;
1332 		arm_debug_state32_t *thread_state;
1333 
1334 		if (*count < ARM_LEGACY_DEBUG_STATE_COUNT) {
1335 			return KERN_INVALID_ARGUMENT;
1336 		}
1337 
1338 		if (thread_is_64bit_data(thread)) {
1339 			return KERN_INVALID_ARGUMENT;
1340 		}
1341 
1342 		state = (arm_legacy_debug_state_t *) tstate;
1343 		thread_state = find_debug_state32(thread);
1344 
1345 		if (thread_state == NULL) {
1346 			bzero(state, sizeof(arm_legacy_debug_state_t));
1347 		} else {
1348 			bcopy(thread_state, state, sizeof(arm_legacy_debug_state_t));
1349 		}
1350 
1351 		*count = ARM_LEGACY_DEBUG_STATE_COUNT;
1352 		break;
1353 	}
1354 	case ARM_DEBUG_STATE32:{
1355 		arm_debug_state32_t *state;
1356 		arm_debug_state32_t *thread_state;
1357 
1358 		if (*count < ARM_DEBUG_STATE32_COUNT) {
1359 			return KERN_INVALID_ARGUMENT;
1360 		}
1361 
1362 		if (thread_is_64bit_data(thread)) {
1363 			return KERN_INVALID_ARGUMENT;
1364 		}
1365 
1366 		state = (arm_debug_state32_t *) tstate;
1367 		thread_state = find_debug_state32(thread);
1368 
1369 		if (thread_state == NULL) {
1370 			bzero(state, sizeof(arm_debug_state32_t));
1371 		} else {
1372 			bcopy(thread_state, state, sizeof(arm_debug_state32_t));
1373 		}
1374 
1375 		*count = ARM_DEBUG_STATE32_COUNT;
1376 		break;
1377 	}
1378 
1379 	case ARM_DEBUG_STATE64:{
1380 		arm_debug_state64_t *state;
1381 		arm_debug_state64_t *thread_state;
1382 
1383 		if (*count < ARM_DEBUG_STATE64_COUNT) {
1384 			return KERN_INVALID_ARGUMENT;
1385 		}
1386 
1387 		if (!thread_is_64bit_data(thread)) {
1388 			return KERN_INVALID_ARGUMENT;
1389 		}
1390 
1391 		state = (arm_debug_state64_t *) tstate;
1392 		thread_state = find_debug_state64(thread);
1393 
1394 		if (thread_state == NULL) {
1395 			bzero(state, sizeof(arm_debug_state64_t));
1396 		} else {
1397 			bcopy(thread_state, state, sizeof(arm_debug_state64_t));
1398 		}
1399 
1400 		*count = ARM_DEBUG_STATE64_COUNT;
1401 		break;
1402 	}
1403 
1404 	case ARM_VFP_STATE:{
1405 		struct arm_vfp_state *state;
1406 		arm_neon_saved_state32_t *thread_state;
1407 		unsigned int max;
1408 
1409 		if (*count < ARM_VFP_STATE_COUNT) {
1410 			if (*count < ARM_VFPV2_STATE_COUNT) {
1411 				return KERN_INVALID_ARGUMENT;
1412 			} else {
1413 				*count =  ARM_VFPV2_STATE_COUNT;
1414 			}
1415 		}
1416 
1417 		if (*count == ARM_VFPV2_STATE_COUNT) {
1418 			max = 32;
1419 		} else {
1420 			max = 64;
1421 		}
1422 
1423 		state = (struct arm_vfp_state *) tstate;
1424 		thread_state = neon_state32(thread->machine.uNeon);
1425 		/* ARM64 TODO: set fpsr and fpcr from state->fpscr */
1426 
1427 		bcopy(thread_state, state, (max + 1) * sizeof(uint32_t));
1428 		*count = (max + 1);
1429 		break;
1430 	}
1431 	case ARM_NEON_STATE:{
1432 		arm_neon_state_t *state;
1433 		arm_neon_saved_state32_t *thread_state;
1434 
1435 		if (*count < ARM_NEON_STATE_COUNT) {
1436 			return KERN_INVALID_ARGUMENT;
1437 		}
1438 
1439 		if (thread_is_64bit_data(thread)) {
1440 			return KERN_INVALID_ARGUMENT;
1441 		}
1442 
1443 		state = (arm_neon_state_t *)tstate;
1444 		thread_state = neon_state32(thread->machine.uNeon);
1445 
1446 		assert(sizeof(*thread_state) == sizeof(*state));
1447 		bcopy(thread_state, state, sizeof(arm_neon_state_t));
1448 
1449 		*count = ARM_NEON_STATE_COUNT;
1450 		break;
1451 	}
1452 
1453 	case ARM_NEON_STATE64:{
1454 		arm_neon_state64_t *state;
1455 		const arm_neon_saved_state64_t *thread_state;
1456 
1457 		if (*count < ARM_NEON_STATE64_COUNT) {
1458 			return KERN_INVALID_ARGUMENT;
1459 		}
1460 
1461 		if (!thread_is_64bit_data(thread)) {
1462 			return KERN_INVALID_ARGUMENT;
1463 		}
1464 
1465 		state = (arm_neon_state64_t *)tstate;
1466 		thread_state = neon_state64(thread->machine.uNeon);
1467 
1468 #if HAS_ARM_FEAT_SME
1469 		const arm_sme_saved_state_t *sme_ss = machine_thread_get_sme_state(thread);
1470 		/* Inside streaming SVE mode, reads from Q[i] access the lower 128 bits of Z[i] */
1471 		if (sme_ss && (sme_ss->svcr & SVCR_SM)) {
1472 			const uint8_t *z = const_arm_sme_z(&sme_ss->context);
1473 
1474 			for (int i = 0; i < ARRAY_COUNT(state->q); i++) {
1475 				bcopy(z, &state->q[i], sizeof(state->q[i]));
1476 				z += sme_ss->svl_b;
1477 			}
1478 			state->fpcr = thread_state->fpcr;
1479 			state->fpsr = thread_state->fpsr;
1480 #else
1481 		if (0) {
1482 #endif
1483 		} else {
1484 			/* For now, these are identical */
1485 			assert(sizeof(*state) == sizeof(*thread_state));
1486 			bcopy(thread_state, state, sizeof(arm_neon_state64_t));
1487 		}
1488 
1489 
1490 		*count = ARM_NEON_STATE64_COUNT;
1491 		break;
1492 	}
1493 
1494 
1495 	case ARM_PAGEIN_STATE: {
1496 		arm_pagein_state_t *state;
1497 
1498 		if (*count < ARM_PAGEIN_STATE_COUNT) {
1499 			return KERN_INVALID_ARGUMENT;
1500 		}
1501 
1502 		state = (arm_pagein_state_t *)tstate;
1503 		state->__pagein_error = thread->t_pagein_error;
1504 
1505 		*count = ARM_PAGEIN_STATE_COUNT;
1506 		break;
1507 	}
1508 
1509 #if HAS_ARM_FEAT_SME
1510 	case ARM_SME_STATE:
1511 		return handle_get_arm_sme_state(tstate, count, thread);
1512 
1513 	case ARM_SVE_Z_STATE1:
1514 		return handle_get_arm_sve_z_state(tstate, count, thread, 0);
1515 
1516 	case ARM_SVE_Z_STATE2:
1517 		return handle_get_arm_sve_z_state(tstate, count, thread, 16);
1518 
1519 	case ARM_SVE_P_STATE:
1520 		return handle_get_arm_sve_p_state(tstate, count, thread);
1521 
1522 	case ARM_SME_ZA_STATE1:
1523 		return handle_get_arm_za_state(tstate, count, thread);
1524 
1525 	case ARM_SME_ZA_STATE2 ... ARM_SME_ZA_STATE16:
1526 		/* Reserved for future use */
1527 		return KERN_INVALID_ARGUMENT;
1528 
1529 #if HAS_ARM_FEAT_SME2
1530 	case ARM_SME2_STATE:
1531 		return handle_get_arm_sme2_state(tstate, count, thread);
1532 #endif
1533 #endif
1534 
1535 	default:
1536 		return KERN_INVALID_ARGUMENT;
1537 	}
1538 	return KERN_SUCCESS;
1539 }
1540 
1541 
1542 /*
1543  * Routine: machine_thread_get_kern_state
1544  *
1545  */
1546 kern_return_t
1547 machine_thread_get_kern_state(thread_t                 thread,
1548     thread_flavor_t          flavor,
1549     thread_state_t           tstate,
1550     mach_msg_type_number_t * count)
1551 {
1552 	/*
1553 	 * This works only for an interrupted kernel thread
1554 	 */
1555 	if (thread != current_thread() || getCpuDatap()->cpu_int_state == NULL) {
1556 		return KERN_FAILURE;
1557 	}
1558 
1559 	switch (flavor) {
1560 	case ARM_THREAD_STATE:
1561 	{
1562 		kern_return_t rn = handle_get_arm_thread_state(tstate, count, getCpuDatap()->cpu_int_state);
1563 		if (rn) {
1564 			return rn;
1565 		}
1566 		break;
1567 	}
1568 	case ARM_THREAD_STATE32:
1569 	{
1570 		kern_return_t rn = handle_get_arm32_thread_state(tstate, count, getCpuDatap()->cpu_int_state);
1571 		if (rn) {
1572 			return rn;
1573 		}
1574 		break;
1575 	}
1576 #if __arm64__
1577 	case ARM_THREAD_STATE64:
1578 	{
1579 		kern_return_t rn = handle_get_arm64_thread_state(tstate, count, getCpuDatap()->cpu_int_state);
1580 		if (rn) {
1581 			return rn;
1582 		}
1583 		break;
1584 	}
1585 #endif
1586 	default:
1587 		return KERN_INVALID_ARGUMENT;
1588 	}
1589 	return KERN_SUCCESS;
1590 }
1591 
1592 void
1593 machine_thread_switch_addrmode(thread_t thread)
1594 {
1595 	if (task_has_64Bit_data(get_threadtask(thread))) {
1596 		thread->machine.upcb->ash.flavor = ARM_SAVED_STATE64;
1597 		thread->machine.upcb->ash.count = ARM_SAVED_STATE64_COUNT;
1598 		thread->machine.uNeon->nsh.flavor = ARM_NEON_SAVED_STATE64;
1599 		thread->machine.uNeon->nsh.count = ARM_NEON_SAVED_STATE64_COUNT;
1600 
1601 		/*
1602 		 * Reinitialize the NEON state.
1603 		 */
1604 		bzero(&thread->machine.uNeon->uns, sizeof(thread->machine.uNeon->uns));
1605 		thread->machine.uNeon->ns_64.fpcr = FPCR_DEFAULT;
1606 	} else {
1607 		thread->machine.upcb->ash.flavor = ARM_SAVED_STATE32;
1608 		thread->machine.upcb->ash.count = ARM_SAVED_STATE32_COUNT;
1609 		thread->machine.uNeon->nsh.flavor = ARM_NEON_SAVED_STATE32;
1610 		thread->machine.uNeon->nsh.count = ARM_NEON_SAVED_STATE32_COUNT;
1611 
1612 		/*
1613 		 * Reinitialize the NEON state.
1614 		 */
1615 		bzero(&thread->machine.uNeon->uns, sizeof(thread->machine.uNeon->uns));
1616 		thread->machine.uNeon->ns_32.fpcr = FPCR_DEFAULT_32;
1617 	}
1618 }
1619 
1620 extern long long arm_debug_get(void);
1621 
1622 /*
1623  * Routine: machine_thread_set_state
1624  *
1625  */
1626 kern_return_t
1627 machine_thread_set_state(thread_t               thread,
1628     thread_flavor_t        flavor,
1629     thread_state_t         tstate,
1630     mach_msg_type_number_t count)
1631 {
1632 	kern_return_t rn;
1633 
1634 	switch (flavor) {
1635 	case ARM_THREAD_STATE:
1636 		rn = handle_set_arm_thread_state(tstate, count, thread->machine.upcb);
1637 		if (rn) {
1638 			return rn;
1639 		}
1640 		break;
1641 
1642 	case ARM_THREAD_STATE32:
1643 		if (thread_is_64bit_data(thread)) {
1644 			return KERN_INVALID_ARGUMENT;
1645 		}
1646 
1647 		rn = handle_set_arm32_thread_state(tstate, count, thread->machine.upcb);
1648 		if (rn) {
1649 			return rn;
1650 		}
1651 		break;
1652 
1653 #if __arm64__
1654 	case ARM_THREAD_STATE64:
1655 		if (!thread_is_64bit_data(thread)) {
1656 			return KERN_INVALID_ARGUMENT;
1657 		}
1658 
1659 
1660 		rn = handle_set_arm64_thread_state(tstate, count, thread->machine.upcb);
1661 		if (rn) {
1662 			return rn;
1663 		}
1664 		break;
1665 #endif
1666 	case ARM_EXCEPTION_STATE:{
1667 		if (count != ARM_EXCEPTION_STATE_COUNT) {
1668 			return KERN_INVALID_ARGUMENT;
1669 		}
1670 		if (thread_is_64bit_data(thread)) {
1671 			return KERN_INVALID_ARGUMENT;
1672 		}
1673 
1674 		break;
1675 	}
1676 	case ARM_EXCEPTION_STATE64:{
1677 		if (count != ARM_EXCEPTION_STATE64_COUNT) {
1678 			return KERN_INVALID_ARGUMENT;
1679 		}
1680 		if (!thread_is_64bit_data(thread)) {
1681 			return KERN_INVALID_ARGUMENT;
1682 		}
1683 
1684 		break;
1685 	}
1686 	case ARM_EXCEPTION_STATE64_V2:{
1687 		if (count != ARM_EXCEPTION_STATE64_V2_COUNT) {
1688 			return KERN_INVALID_ARGUMENT;
1689 		}
1690 		if (!thread_is_64bit_data(thread)) {
1691 			return KERN_INVALID_ARGUMENT;
1692 		}
1693 
1694 		break;
1695 	}
1696 	case ARM_DEBUG_STATE:
1697 	{
1698 		arm_legacy_debug_state_t *state;
1699 		boolean_t enabled = FALSE;
1700 		unsigned int    i;
1701 
1702 		if (count != ARM_LEGACY_DEBUG_STATE_COUNT) {
1703 			return KERN_INVALID_ARGUMENT;
1704 		}
1705 		if (thread_is_64bit_data(thread)) {
1706 			return KERN_INVALID_ARGUMENT;
1707 		}
1708 
1709 		state = (arm_legacy_debug_state_t *) tstate;
1710 
1711 		for (i = 0; i < 16; i++) {
1712 			/* do not allow context IDs to be set */
1713 			if (((state->bcr[i] & ARM_DBGBCR_TYPE_MASK) != ARM_DBGBCR_TYPE_IVA)
1714 			    || ((state->bcr[i] & ARM_DBG_CR_LINKED_MASK) != ARM_DBG_CR_LINKED_UNLINKED)
1715 			    || ((state->wcr[i] & ARM_DBGBCR_TYPE_MASK) != ARM_DBGBCR_TYPE_IVA)
1716 			    || ((state->wcr[i] & ARM_DBG_CR_LINKED_MASK) != ARM_DBG_CR_LINKED_UNLINKED)) {
1717 				return KERN_PROTECTION_FAILURE;
1718 			}
1719 			if ((((state->bcr[i] & ARM_DBG_CR_ENABLE_MASK) == ARM_DBG_CR_ENABLE_ENABLE))
1720 			    || ((state->wcr[i] & ARM_DBG_CR_ENABLE_MASK) == ARM_DBG_CR_ENABLE_ENABLE)) {
1721 				enabled = TRUE;
1722 			}
1723 		}
1724 
1725 		if (!enabled) {
1726 			free_debug_state(thread);
1727 		} else {
1728 			arm_debug_state32_t *thread_state = find_or_allocate_debug_state32(thread);
1729 
1730 			if (thread_state == NULL) {
1731 				return KERN_FAILURE;
1732 			}
1733 
1734 			for (i = 0; i < 16; i++) {
1735 				/* set appropriate privilege; mask out unknown bits */
1736 				thread_state->bcr[i] = (state->bcr[i] & (ARM_DBG_CR_ADDRESS_MASK_MASK
1737 				    | ARM_DBGBCR_MATCH_MASK
1738 				    | ARM_DBG_CR_BYTE_ADDRESS_SELECT_MASK
1739 				    | ARM_DBG_CR_ENABLE_MASK))
1740 				    | ARM_DBGBCR_TYPE_IVA
1741 				    | ARM_DBG_CR_LINKED_UNLINKED
1742 				    | ARM_DBG_CR_SECURITY_STATE_BOTH
1743 				    | ARM_DBG_CR_MODE_CONTROL_USER;
1744 				thread_state->bvr[i] = state->bvr[i] & ARM_DBG_VR_ADDRESS_MASK;
1745 				thread_state->wcr[i] = (state->wcr[i] & (ARM_DBG_CR_ADDRESS_MASK_MASK
1746 				    | ARM_DBGWCR_BYTE_ADDRESS_SELECT_MASK
1747 				    | ARM_DBGWCR_ACCESS_CONTROL_MASK
1748 				    | ARM_DBG_CR_ENABLE_MASK))
1749 				    | ARM_DBG_CR_LINKED_UNLINKED
1750 				    | ARM_DBG_CR_SECURITY_STATE_BOTH
1751 				    | ARM_DBG_CR_MODE_CONTROL_USER;
1752 				thread_state->wvr[i] = state->wvr[i] & ARM_DBG_VR_ADDRESS_MASK;
1753 			}
1754 
1755 			thread_state->mdscr_el1 = 0ULL;         // Legacy customers issuing ARM_DEBUG_STATE dont drive single stepping.
1756 		}
1757 
1758 		if (thread == current_thread()) {
1759 			arm_debug_set32(thread->machine.DebugData);
1760 		}
1761 
1762 		break;
1763 	}
1764 	case ARM_DEBUG_STATE32:
1765 		/* ARM64_TODO  subtle bcr/wcr semantic differences e.g. wcr and ARM_DBGBCR_TYPE_IVA */
1766 	{
1767 		arm_debug_state32_t *state;
1768 		boolean_t enabled = FALSE;
1769 		unsigned int    i;
1770 
1771 		if (count != ARM_DEBUG_STATE32_COUNT) {
1772 			return KERN_INVALID_ARGUMENT;
1773 		}
1774 		if (thread_is_64bit_data(thread)) {
1775 			return KERN_INVALID_ARGUMENT;
1776 		}
1777 
1778 		state = (arm_debug_state32_t *) tstate;
1779 
1780 		if (state->mdscr_el1 & MDSCR_SS) {
1781 			enabled = TRUE;
1782 		}
1783 
1784 		for (i = 0; i < 16; i++) {
1785 			/* do not allow context IDs to be set */
1786 			if (((state->bcr[i] & ARM_DBGBCR_TYPE_MASK) != ARM_DBGBCR_TYPE_IVA)
1787 			    || ((state->bcr[i] & ARM_DBG_CR_LINKED_MASK) != ARM_DBG_CR_LINKED_UNLINKED)
1788 			    || ((state->wcr[i] & ARM_DBGBCR_TYPE_MASK) != ARM_DBGBCR_TYPE_IVA)
1789 			    || ((state->wcr[i] & ARM_DBG_CR_LINKED_MASK) != ARM_DBG_CR_LINKED_UNLINKED)) {
1790 				return KERN_PROTECTION_FAILURE;
1791 			}
1792 			if ((((state->bcr[i] & ARM_DBG_CR_ENABLE_MASK) == ARM_DBG_CR_ENABLE_ENABLE))
1793 			    || ((state->wcr[i] & ARM_DBG_CR_ENABLE_MASK) == ARM_DBG_CR_ENABLE_ENABLE)) {
1794 				enabled = TRUE;
1795 			}
1796 		}
1797 
1798 		if (!enabled) {
1799 			free_debug_state(thread);
1800 		} else {
1801 			arm_debug_state32_t * thread_state = find_or_allocate_debug_state32(thread);
1802 
1803 			if (thread_state == NULL) {
1804 				return KERN_FAILURE;
1805 			}
1806 
1807 			if (state->mdscr_el1 & MDSCR_SS) {
1808 				thread_state->mdscr_el1 |= MDSCR_SS;
1809 			} else {
1810 				thread_state->mdscr_el1 &= ~MDSCR_SS;
1811 			}
1812 
1813 			for (i = 0; i < 16; i++) {
1814 				/* set appropriate privilege; mask out unknown bits */
1815 				thread_state->bcr[i] = (state->bcr[i] & (ARM_DBG_CR_ADDRESS_MASK_MASK
1816 				    | ARM_DBGBCR_MATCH_MASK
1817 				    | ARM_DBG_CR_BYTE_ADDRESS_SELECT_MASK
1818 				    | ARM_DBG_CR_ENABLE_MASK))
1819 				    | ARM_DBGBCR_TYPE_IVA
1820 				    | ARM_DBG_CR_LINKED_UNLINKED
1821 				    | ARM_DBG_CR_SECURITY_STATE_BOTH
1822 				    | ARM_DBG_CR_MODE_CONTROL_USER;
1823 				thread_state->bvr[i] = state->bvr[i] & ARM_DBG_VR_ADDRESS_MASK;
1824 				thread_state->wcr[i] = (state->wcr[i] & (ARM_DBG_CR_ADDRESS_MASK_MASK
1825 				    | ARM_DBGWCR_BYTE_ADDRESS_SELECT_MASK
1826 				    | ARM_DBGWCR_ACCESS_CONTROL_MASK
1827 				    | ARM_DBG_CR_ENABLE_MASK))
1828 				    | ARM_DBG_CR_LINKED_UNLINKED
1829 				    | ARM_DBG_CR_SECURITY_STATE_BOTH
1830 				    | ARM_DBG_CR_MODE_CONTROL_USER;
1831 				thread_state->wvr[i] = state->wvr[i] & ARM_DBG_VR_ADDRESS_MASK;
1832 			}
1833 		}
1834 
1835 		if (thread == current_thread()) {
1836 			arm_debug_set32(thread->machine.DebugData);
1837 		}
1838 
1839 		break;
1840 	}
1841 
1842 	case ARM_DEBUG_STATE64:
1843 	{
1844 		arm_debug_state64_t *state;
1845 		boolean_t enabled = FALSE;
1846 		unsigned int i;
1847 
1848 		if (count != ARM_DEBUG_STATE64_COUNT) {
1849 			return KERN_INVALID_ARGUMENT;
1850 		}
1851 		if (!thread_is_64bit_data(thread)) {
1852 			return KERN_INVALID_ARGUMENT;
1853 		}
1854 
1855 		state = (arm_debug_state64_t *) tstate;
1856 
1857 		if (state->mdscr_el1 & MDSCR_SS) {
1858 			enabled = TRUE;
1859 		}
1860 
1861 		for (i = 0; i < 16; i++) {
1862 			/* do not allow context IDs to be set */
1863 			if (((state->bcr[i] & ARM_DBGBCR_TYPE_MASK) != ARM_DBGBCR_TYPE_IVA)
1864 			    || ((state->bcr[i] & ARM_DBG_CR_LINKED_MASK) != ARM_DBG_CR_LINKED_UNLINKED)
1865 			    || ((state->wcr[i] & ARM_DBG_CR_LINKED_MASK) != ARM_DBG_CR_LINKED_UNLINKED)) {
1866 				return KERN_PROTECTION_FAILURE;
1867 			}
1868 			if ((((state->bcr[i] & ARM_DBG_CR_ENABLE_MASK) == ARM_DBG_CR_ENABLE_ENABLE))
1869 			    || ((state->wcr[i] & ARM_DBG_CR_ENABLE_MASK) == ARM_DBG_CR_ENABLE_ENABLE)) {
1870 				enabled = TRUE;
1871 			}
1872 		}
1873 
1874 		if (!enabled) {
1875 			free_debug_state(thread);
1876 		} else {
1877 			arm_debug_state64_t *thread_state = find_or_allocate_debug_state64(thread);
1878 
1879 			if (thread_state == NULL) {
1880 				return KERN_FAILURE;
1881 			}
1882 
1883 			if (state->mdscr_el1 & MDSCR_SS) {
1884 				thread_state->mdscr_el1 |= MDSCR_SS;
1885 			} else {
1886 				thread_state->mdscr_el1 &= ~MDSCR_SS;
1887 			}
1888 
1889 			for (i = 0; i < 16; i++) {
1890 				/* set appropriate privilege; mask out unknown bits */
1891 				thread_state->bcr[i] = (state->bcr[i] & (0         /* Was ARM_DBG_CR_ADDRESS_MASK_MASK deprecated in v8 */
1892 				    | 0                             /* Was ARM_DBGBCR_MATCH_MASK, ignored in AArch64 state */
1893 				    | ARM_DBG_CR_BYTE_ADDRESS_SELECT_MASK
1894 				    | ARM_DBG_CR_ENABLE_MASK))
1895 				    | ARM_DBGBCR_TYPE_IVA
1896 				    | ARM_DBG_CR_LINKED_UNLINKED
1897 				    | ARM_DBG_CR_SECURITY_STATE_BOTH
1898 				    | ARM_DBG_CR_MODE_CONTROL_USER;
1899 				thread_state->bvr[i] = state->bvr[i] & ARM_DBG_VR_ADDRESS_MASK64;
1900 				thread_state->wcr[i] = (state->wcr[i] & (ARM_DBG_CR_ADDRESS_MASK_MASK
1901 				    | ARM_DBGWCR_BYTE_ADDRESS_SELECT_MASK
1902 				    | ARM_DBGWCR_ACCESS_CONTROL_MASK
1903 				    | ARM_DBG_CR_ENABLE_MASK))
1904 				    | ARM_DBG_CR_LINKED_UNLINKED
1905 				    | ARM_DBG_CR_SECURITY_STATE_BOTH
1906 				    | ARM_DBG_CR_MODE_CONTROL_USER;
1907 				thread_state->wvr[i] = state->wvr[i] & ARM_DBG_VR_ADDRESS_MASK64;
1908 			}
1909 		}
1910 
1911 		if (thread == current_thread()) {
1912 			arm_debug_set64(thread->machine.DebugData);
1913 		}
1914 
1915 		break;
1916 	}
1917 
1918 	case ARM_VFP_STATE:{
1919 		struct arm_vfp_state *state;
1920 		arm_neon_saved_state32_t *thread_state;
1921 		unsigned int    max;
1922 
1923 		if (count != ARM_VFP_STATE_COUNT && count != ARM_VFPV2_STATE_COUNT) {
1924 			return KERN_INVALID_ARGUMENT;
1925 		}
1926 
1927 		if (count == ARM_VFPV2_STATE_COUNT) {
1928 			max = 32;
1929 		} else {
1930 			max = 64;
1931 		}
1932 
1933 		state = (struct arm_vfp_state *) tstate;
1934 		thread_state = neon_state32(thread->machine.uNeon);
1935 		/* ARM64 TODO: combine fpsr and fpcr into state->fpscr */
1936 
1937 		bcopy(state, thread_state, (max + 1) * sizeof(uint32_t));
1938 
1939 		thread->machine.uNeon->nsh.flavor = ARM_NEON_SAVED_STATE32;
1940 		thread->machine.uNeon->nsh.count = ARM_NEON_SAVED_STATE32_COUNT;
1941 		break;
1942 	}
1943 
1944 	case ARM_NEON_STATE:{
1945 		arm_neon_state_t *state;
1946 		arm_neon_saved_state32_t *thread_state;
1947 
1948 		if (count != ARM_NEON_STATE_COUNT) {
1949 			return KERN_INVALID_ARGUMENT;
1950 		}
1951 
1952 		if (thread_is_64bit_data(thread)) {
1953 			return KERN_INVALID_ARGUMENT;
1954 		}
1955 
1956 		state = (arm_neon_state_t *)tstate;
1957 		thread_state = neon_state32(thread->machine.uNeon);
1958 
1959 		assert(sizeof(*state) == sizeof(*thread_state));
1960 		bcopy(state, thread_state, sizeof(arm_neon_state_t));
1961 
1962 		thread->machine.uNeon->nsh.flavor = ARM_NEON_SAVED_STATE32;
1963 		thread->machine.uNeon->nsh.count = ARM_NEON_SAVED_STATE32_COUNT;
1964 		break;
1965 	}
1966 
1967 	case ARM_NEON_STATE64:{
1968 		arm_neon_state64_t *state;
1969 		arm_neon_saved_state64_t *thread_state;
1970 
1971 		if (count != ARM_NEON_STATE64_COUNT) {
1972 			return KERN_INVALID_ARGUMENT;
1973 		}
1974 
1975 		if (!thread_is_64bit_data(thread)) {
1976 			return KERN_INVALID_ARGUMENT;
1977 		}
1978 
1979 		state = (arm_neon_state64_t *)tstate;
1980 		thread_state = neon_state64(thread->machine.uNeon);
1981 
1982 #if HAS_ARM_FEAT_SME
1983 		arm_sme_saved_state_t *sme_ss = machine_thread_get_sme_state(thread);
1984 		/*
1985 		 * Inside streaming SVE mode, writes to Q[i] modify the lower 128 bits
1986 		 * of Z[i], and zero out all bits > 128.
1987 		 */
1988 		if (sme_ss && (sme_ss->svcr & SVCR_SM)) {
1989 			uint8_t *z = arm_sme_z(&sme_ss->context);
1990 			const size_t elem_size = sizeof(state->q[0]);
1991 			const size_t padding_size = sme_ss->svl_b - elem_size;
1992 
1993 			for (int i = 0; i < ARRAY_COUNT(state->q); i++) {
1994 				bcopy(&state->q[i], z, elem_size);
1995 				z += elem_size;
1996 				bzero(z, padding_size);
1997 				z += padding_size;
1998 			}
1999 			thread_state->fpcr = state->fpcr;
2000 			thread_state->fpsr = state->fpsr;
2001 #else
2002 		if (0) {
2003 #endif
2004 		} else {
2005 			assert(sizeof(*state) == sizeof(*thread_state));
2006 			bcopy(state, thread_state, sizeof(arm_neon_state64_t));
2007 		}
2008 
2009 
2010 		thread->machine.uNeon->nsh.flavor = ARM_NEON_SAVED_STATE64;
2011 		thread->machine.uNeon->nsh.count = ARM_NEON_SAVED_STATE64_COUNT;
2012 		break;
2013 	}
2014 
2015 
2016 #if HAS_ARM_FEAT_SME
2017 	case ARM_SME_STATE:
2018 		return handle_set_arm_sme_state(tstate, count, thread);
2019 
2020 	case ARM_SVE_Z_STATE1:
2021 		return handle_set_arm_sve_z_state(tstate, count, thread, 0);
2022 
2023 	case ARM_SVE_Z_STATE2:
2024 		return handle_set_arm_sve_z_state(tstate, count, thread, 16);
2025 
2026 	case ARM_SVE_P_STATE:
2027 		return handle_set_arm_sve_p_state(tstate, count, thread);
2028 
2029 	case ARM_SME_ZA_STATE1:
2030 		return handle_set_arm_za_state(tstate, count, thread);
2031 
2032 	case ARM_SME_ZA_STATE2 ... ARM_SME_ZA_STATE16:
2033 		/* Reserved for future use */
2034 		return KERN_INVALID_ARGUMENT;
2035 
2036 #if HAS_ARM_FEAT_SME2
2037 	case ARM_SME2_STATE:
2038 		return handle_set_arm_sme2_state(tstate, count, thread);
2039 #endif
2040 #endif
2041 
2042 	default:
2043 		return KERN_INVALID_ARGUMENT;
2044 	}
2045 	return KERN_SUCCESS;
2046 }
2047 
2048 mach_vm_address_t
2049 machine_thread_pc(thread_t thread)
2050 {
2051 	struct arm_saved_state *ss = get_user_regs(thread);
2052 	return (mach_vm_address_t)get_saved_state_pc(ss);
2053 }
2054 
2055 void
2056 machine_thread_reset_pc(thread_t thread, mach_vm_address_t pc)
2057 {
2058 	set_user_saved_state_pc(get_user_regs(thread), (register_t)pc);
2059 }
2060 
2061 /*
2062  * Routine: machine_thread_state_initialize
2063  *
2064  */
2065 void
2066 machine_thread_state_initialize(thread_t thread)
2067 {
2068 	arm_context_t *context = thread->machine.contextData;
2069 
2070 	/*
2071 	 * Should always be set up later. For a kernel thread, we don't care
2072 	 * about this state. For a user thread, we'll set the state up in
2073 	 * setup_wqthread, bsdthread_create, load_main(), or load_unixthread().
2074 	 */
2075 
2076 	if (context != NULL) {
2077 		bzero(&context->ss.uss, sizeof(context->ss.uss));
2078 		bzero(&context->ns.uns, sizeof(context->ns.uns));
2079 
2080 		if (context->ns.nsh.flavor == ARM_NEON_SAVED_STATE64) {
2081 			context->ns.ns_64.fpcr = FPCR_DEFAULT;
2082 		} else {
2083 			context->ns.ns_32.fpcr = FPCR_DEFAULT_32;
2084 		}
2085 		context->ss.ss_64.cpsr = PSR64_USER64_DEFAULT;
2086 	}
2087 
2088 	thread->machine.DebugData = NULL;
2089 
2090 #if defined(HAS_APPLE_PAC)
2091 	/* Sign the initial user-space thread state */
2092 	if (thread->machine.upcb != NULL) {
2093 		uint64_t intr = ml_pac_safe_interrupts_disable();
2094 		asm volatile (
2095                         "mov	x0, %[iss]"             "\n"
2096                         "mov	x1, #0"                 "\n"
2097                         "mov	w2, %w[usr]"            "\n"
2098                         "mov	x3, #0"                 "\n"
2099                         "mov	x4, #0"                 "\n"
2100                         "mov	x5, #0"                 "\n"
2101                         "msr	SPSel, #1"              "\n"
2102                         VERIFY_USER_THREAD_STATE_INSTR  "\n"
2103                         "mov	x6, lr"                 "\n"
2104                         "bl     _ml_sign_thread_state"  "\n"
2105                         "msr	SPSel, #0"              "\n"
2106                         "mov	lr, x6"                 "\n"
2107                         :
2108                         : [iss] "r"(thread->machine.upcb), [usr] "r"(thread->machine.upcb->ss_64.cpsr),
2109                           VERIFY_USER_THREAD_STATE_INPUTS
2110                         : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x17"
2111                 );
2112 		ml_pac_safe_interrupts_restore(intr);
2113 	}
2114 #endif /* defined(HAS_APPLE_PAC) */
2115 }
2116 
2117 /*
2118  * Routine: machine_thread_dup
2119  *
2120  */
2121 kern_return_t
2122 machine_thread_dup(thread_t self,
2123     thread_t target,
2124     __unused boolean_t is_corpse)
2125 {
2126 	struct arm_saved_state *self_saved_state;
2127 	struct arm_saved_state *target_saved_state;
2128 
2129 	target->machine.cthread_self = self->machine.cthread_self;
2130 
2131 	self_saved_state = self->machine.upcb;
2132 	target_saved_state = target->machine.upcb;
2133 	bcopy(self_saved_state, target_saved_state, sizeof(struct arm_saved_state));
2134 #if defined(HAS_APPLE_PAC)
2135 	if (!is_corpse && is_saved_state64(self_saved_state)) {
2136 		check_and_sign_copied_user_thread_state(target_saved_state, self_saved_state);
2137 	}
2138 #endif /* defined(HAS_APPLE_PAC) */
2139 
2140 	arm_neon_saved_state_t *self_neon_state = self->machine.uNeon;
2141 	arm_neon_saved_state_t *target_neon_state = target->machine.uNeon;
2142 	bcopy(self_neon_state, target_neon_state, sizeof(*target_neon_state));
2143 
2144 #if HAVE_MACHINE_THREAD_MATRIX_STATE
2145 	if (self->machine.umatrix_hdr) {
2146 		machine_thread_matrix_state_dup(target);
2147 	}
2148 #endif
2149 
2150 	return KERN_SUCCESS;
2151 }
2152 
2153 /*
2154  * Routine: get_user_regs
2155  *
2156  */
2157 struct arm_saved_state *
2158 get_user_regs(thread_t thread)
2159 {
2160 	return thread->machine.upcb;
2161 }
2162 
2163 /**
2164  * Sets the value of NEON register Q[regno] inside the provided thread's
2165  * saved-state.
2166  *
2167  * On SME-capable CPUs, this accessor follows the same aliasing rules as
2168  * hardware.  If the thread is inside streaming SVE mode (SVCR.SM == 1), then
2169  * writes to Q[regno] actually update Z[regno][127:0] and zero out
2170  * Z[regno][SVL-1:128].
2171  *
2172  * @param thread thread
2173  * @param regno which Q register to modify
2174  * @param val the new value to store in Q[regno]
2175  */
2176 void
2177 set_user_neon_reg(thread_t thread, unsigned int regno, uint128_t val)
2178 {
2179 #if HAS_ARM_FEAT_SME
2180 	arm_sme_saved_state_t *sme_ss = machine_thread_get_sme_state(thread);
2181 	if (sme_ss && (sme_ss->svcr & SVCR_SM)) {
2182 		uint8_t *z_0 = arm_sme_z(&sme_ss->context);
2183 		uint8_t *z_dst = z_0 + (regno * sme_ss->svl_b);
2184 		bcopy(&val, z_dst, sizeof(val));
2185 		bzero(z_dst + sizeof(val), sme_ss->svl_b - sizeof(val));
2186 		return;
2187 	}
2188 #endif
2189 	void *q_dst = &thread->machine.uNeon->ns_64.v.q[regno];
2190 	bcopy(&val, q_dst, sizeof(val));
2191 }
2192 
2193 /*
2194  * Routine: find_user_regs
2195  *
2196  */
2197 struct arm_saved_state *
2198 find_user_regs(thread_t thread)
2199 {
2200 	return thread->machine.upcb;
2201 }
2202 
2203 /*
2204  * Routine: find_kern_regs
2205  *
2206  */
2207 struct arm_saved_state *
2208 find_kern_regs(thread_t thread)
2209 {
2210 	/*
2211 	 * This works only for an interrupted kernel thread
2212 	 */
2213 	if (thread != current_thread() || getCpuDatap()->cpu_int_state == NULL) {
2214 		return (struct arm_saved_state *) NULL;
2215 	} else {
2216 		return getCpuDatap()->cpu_int_state;
2217 	}
2218 }
2219 
2220 arm_debug_state32_t *
2221 find_debug_state32(thread_t thread)
2222 {
2223 	if (thread && thread->machine.DebugData) {
2224 		return &(thread->machine.DebugData->uds.ds32);
2225 	} else {
2226 		return NULL;
2227 	}
2228 }
2229 
2230 arm_debug_state64_t *
2231 find_debug_state64(thread_t thread)
2232 {
2233 	if (thread && thread->machine.DebugData) {
2234 		return &(thread->machine.DebugData->uds.ds64);
2235 	} else {
2236 		return NULL;
2237 	}
2238 }
2239 
2240 os_refgrp_decl(static, dbg_refgrp, "arm_debug_state", NULL);
2241 
2242 /**
2243  *  Finds the debug state for the given 64 bit thread, allocating one if it
2244  *  does not exist.
2245  *
2246  *  @param thread 64 bit thread to find or allocate debug state for
2247  *
2248  *  @returns A pointer to the given thread's 64 bit debug state or a null
2249  *           pointer if the given thread is null or the allocation of a new
2250  *           debug state fails.
2251  */
2252 arm_debug_state64_t *
2253 find_or_allocate_debug_state64(thread_t thread)
2254 {
2255 	arm_debug_state64_t *thread_state = find_debug_state64(thread);
2256 	if (thread != NULL && thread_state == NULL) {
2257 		thread->machine.DebugData = zalloc_flags(ads_zone,
2258 		    Z_WAITOK | Z_NOFAIL);
2259 		bzero(thread->machine.DebugData, sizeof *(thread->machine.DebugData));
2260 		thread->machine.DebugData->dsh.flavor = ARM_DEBUG_STATE64;
2261 		thread->machine.DebugData->dsh.count = ARM_DEBUG_STATE64_COUNT;
2262 		os_ref_init(&thread->machine.DebugData->ref, &dbg_refgrp);
2263 		thread_state = find_debug_state64(thread);
2264 	}
2265 	return thread_state;
2266 }
2267 
2268 /**
2269  *  Finds the debug state for the given 32 bit thread, allocating one if it
2270  *  does not exist.
2271  *
2272  *  @param thread 32 bit thread to find or allocate debug state for
2273  *
2274  *  @returns A pointer to the given thread's 32 bit debug state or a null
2275  *           pointer if the given thread is null or the allocation of a new
2276  *           debug state fails.
2277  */
2278 arm_debug_state32_t *
2279 find_or_allocate_debug_state32(thread_t thread)
2280 {
2281 	arm_debug_state32_t *thread_state = find_debug_state32(thread);
2282 	if (thread != NULL && thread_state == NULL) {
2283 		thread->machine.DebugData = zalloc_flags(ads_zone,
2284 		    Z_WAITOK | Z_NOFAIL);
2285 		bzero(thread->machine.DebugData, sizeof *(thread->machine.DebugData));
2286 		thread->machine.DebugData->dsh.flavor = ARM_DEBUG_STATE32;
2287 		thread->machine.DebugData->dsh.count = ARM_DEBUG_STATE32_COUNT;
2288 		os_ref_init(&thread->machine.DebugData->ref, &dbg_refgrp);
2289 		thread_state = find_debug_state32(thread);
2290 	}
2291 	return thread_state;
2292 }
2293 
2294 /**
2295  *	Frees a thread's debug state if allocated. Otherwise does nothing.
2296  *
2297  *  @param thread thread to free the debug state of
2298  */
2299 static inline void
2300 free_debug_state(thread_t thread)
2301 {
2302 	if (thread != NULL && thread->machine.DebugData != NULL) {
2303 		arm_debug_state_t *pTmp = thread->machine.DebugData;
2304 		thread->machine.DebugData = NULL;
2305 
2306 		if (os_ref_release(&pTmp->ref) == 0) {
2307 			zfree(ads_zone, pTmp);
2308 		}
2309 	}
2310 }
2311 
2312 /*
2313  * Routine: thread_userstack
2314  *
2315  */
2316 kern_return_t
2317 thread_userstack(__unused thread_t  thread,
2318     int                flavor,
2319     thread_state_t     tstate,
2320     unsigned int       count,
2321     mach_vm_offset_t * user_stack,
2322     int *              customstack,
2323     boolean_t          is_64bit_data
2324     )
2325 {
2326 	register_t sp;
2327 
2328 	switch (flavor) {
2329 	case ARM_THREAD_STATE:
2330 		if (count == ARM_UNIFIED_THREAD_STATE_COUNT) {
2331 #if __arm64__
2332 			if (is_64bit_data) {
2333 				sp = ((arm_unified_thread_state_t *)tstate)->ts_64.sp;
2334 			} else
2335 #endif
2336 			{
2337 				sp = ((arm_unified_thread_state_t *)tstate)->ts_32.sp;
2338 			}
2339 
2340 			break;
2341 		}
2342 
2343 		/* INTENTIONAL FALL THROUGH (see machine_thread_set_state) */
2344 		OS_FALLTHROUGH;
2345 	case ARM_THREAD_STATE32:
2346 		if (count != ARM_THREAD_STATE32_COUNT) {
2347 			return KERN_INVALID_ARGUMENT;
2348 		}
2349 		if (is_64bit_data) {
2350 			return KERN_INVALID_ARGUMENT;
2351 		}
2352 
2353 		sp = ((arm_thread_state32_t *)tstate)->sp;
2354 		break;
2355 #if __arm64__
2356 	case ARM_THREAD_STATE64:
2357 		if (count != ARM_THREAD_STATE64_COUNT) {
2358 			return KERN_INVALID_ARGUMENT;
2359 		}
2360 		if (!is_64bit_data) {
2361 			return KERN_INVALID_ARGUMENT;
2362 		}
2363 
2364 		sp = ((arm_thread_state32_t *)tstate)->sp;
2365 		break;
2366 #endif
2367 	default:
2368 		return KERN_INVALID_ARGUMENT;
2369 	}
2370 
2371 	if (sp) {
2372 		*user_stack = CAST_USER_ADDR_T(sp);
2373 		if (customstack) {
2374 			*customstack = 1;
2375 		}
2376 	} else {
2377 		*user_stack = CAST_USER_ADDR_T(USRSTACK64);
2378 		if (customstack) {
2379 			*customstack = 0;
2380 		}
2381 	}
2382 
2383 	return KERN_SUCCESS;
2384 }
2385 
2386 /*
2387  * thread_userstackdefault:
2388  *
2389  * Return the default stack location for the
2390  * thread, if otherwise unknown.
2391  */
2392 kern_return_t
2393 thread_userstackdefault(mach_vm_offset_t * default_user_stack,
2394     boolean_t          is64bit)
2395 {
2396 	if (is64bit) {
2397 		*default_user_stack = USRSTACK64;
2398 	} else {
2399 		*default_user_stack = USRSTACK;
2400 	}
2401 
2402 	return KERN_SUCCESS;
2403 }
2404 
2405 /*
2406  * Routine: thread_setuserstack
2407  *
2408  */
2409 void
2410 thread_setuserstack(thread_t          thread,
2411     mach_vm_address_t user_stack)
2412 {
2413 	struct arm_saved_state *sv;
2414 
2415 	sv = get_user_regs(thread);
2416 
2417 	set_saved_state_sp(sv, user_stack);
2418 
2419 	return;
2420 }
2421 
2422 /*
2423  * Routine: thread_adjuserstack
2424  *
2425  */
2426 user_addr_t
2427 thread_adjuserstack(thread_t thread,
2428     int      adjust)
2429 {
2430 	struct arm_saved_state *sv;
2431 	uint64_t sp;
2432 
2433 	sv = get_user_regs(thread);
2434 
2435 	sp = get_saved_state_sp(sv);
2436 	sp += adjust;
2437 	set_saved_state_sp(sv, sp);
2438 
2439 	return sp;
2440 }
2441 
2442 
2443 /*
2444  * Routine: thread_setentrypoint
2445  *
2446  */
2447 void
2448 thread_setentrypoint(thread_t         thread,
2449     mach_vm_offset_t entry)
2450 {
2451 	struct arm_saved_state *sv;
2452 
2453 #if HAS_APPLE_PAC
2454 	uint64_t intr = ml_pac_safe_interrupts_disable();
2455 #endif
2456 
2457 	sv = get_user_regs(thread);
2458 
2459 	set_user_saved_state_pc(sv, entry);
2460 
2461 #if HAS_APPLE_PAC
2462 	ml_pac_safe_interrupts_restore(intr);
2463 #endif
2464 
2465 	return;
2466 }
2467 
2468 /*
2469  * Routine: thread_entrypoint
2470  *
2471  */
2472 kern_return_t
2473 thread_entrypoint(__unused thread_t  thread,
2474     int                flavor,
2475     thread_state_t     tstate,
2476     unsigned int       count,
2477     mach_vm_offset_t * entry_point
2478     )
2479 {
2480 	switch (flavor) {
2481 	case ARM_THREAD_STATE:
2482 	{
2483 		struct arm_thread_state *state;
2484 
2485 		if (count != ARM_THREAD_STATE_COUNT) {
2486 			return KERN_INVALID_ARGUMENT;
2487 		}
2488 
2489 		state = (struct arm_thread_state *) tstate;
2490 
2491 		/*
2492 		 * If a valid entry point is specified, use it.
2493 		 */
2494 		if (state->pc) {
2495 			*entry_point = CAST_USER_ADDR_T(state->pc);
2496 		} else {
2497 			*entry_point = CAST_USER_ADDR_T(VM_MIN_ADDRESS);
2498 		}
2499 	}
2500 	break;
2501 
2502 	case ARM_THREAD_STATE64:
2503 	{
2504 		struct arm_thread_state64 *state;
2505 
2506 		if (count != ARM_THREAD_STATE64_COUNT) {
2507 			return KERN_INVALID_ARGUMENT;
2508 		}
2509 
2510 		state = (struct arm_thread_state64*) tstate;
2511 
2512 		/*
2513 		 * If a valid entry point is specified, use it.
2514 		 */
2515 		if (state->pc) {
2516 			*entry_point = CAST_USER_ADDR_T(state->pc);
2517 		} else {
2518 			*entry_point = CAST_USER_ADDR_T(VM_MIN_ADDRESS);
2519 		}
2520 
2521 		break;
2522 	}
2523 	default:
2524 		return KERN_INVALID_ARGUMENT;
2525 	}
2526 
2527 	return KERN_SUCCESS;
2528 }
2529 
2530 
2531 /*
2532  * Routine: thread_set_child
2533  *
2534  */
2535 void
2536 thread_set_child(thread_t child,
2537     int      pid)
2538 {
2539 	struct arm_saved_state *child_state;
2540 
2541 	child_state = get_user_regs(child);
2542 
2543 	set_user_saved_state_reg(child_state, 0, pid);
2544 	set_user_saved_state_reg(child_state, 1, 1ULL);
2545 }
2546 
2547 
2548 struct arm_act_context {
2549 	struct arm_unified_thread_state ss;
2550 #if __ARM_VFP__
2551 	struct arm_neon_saved_state ns;
2552 #endif
2553 };
2554 
2555 /*
2556  * Routine: act_thread_csave
2557  *
2558  */
2559 void *
2560 act_thread_csave(void)
2561 {
2562 	struct arm_act_context *ic;
2563 	kern_return_t   kret;
2564 	unsigned int    val;
2565 	thread_t thread = current_thread();
2566 
2567 	ic = kalloc_type(struct arm_act_context, Z_WAITOK);
2568 	if (ic == (struct arm_act_context *) NULL) {
2569 		return (void *) 0;
2570 	}
2571 
2572 	val = ARM_UNIFIED_THREAD_STATE_COUNT;
2573 	kret = machine_thread_get_state(thread, ARM_THREAD_STATE, (thread_state_t)&ic->ss, &val);
2574 	if (kret != KERN_SUCCESS) {
2575 		kfree_type(struct arm_act_context, ic);
2576 		return (void *) 0;
2577 	}
2578 
2579 #if __ARM_VFP__
2580 	if (thread_is_64bit_data(thread)) {
2581 		val = ARM_NEON_STATE64_COUNT;
2582 		kret = machine_thread_get_state(thread,
2583 		    ARM_NEON_STATE64,
2584 		    (thread_state_t)&ic->ns,
2585 		    &val);
2586 	} else {
2587 		val = ARM_NEON_STATE_COUNT;
2588 		kret = machine_thread_get_state(thread,
2589 		    ARM_NEON_STATE,
2590 		    (thread_state_t)&ic->ns,
2591 		    &val);
2592 	}
2593 	if (kret != KERN_SUCCESS) {
2594 		kfree_type(struct arm_act_context, ic);
2595 		return (void *) 0;
2596 	}
2597 #endif
2598 	return ic;
2599 }
2600 
2601 /*
2602  * Routine: act_thread_catt
2603  *
2604  */
2605 void
2606 act_thread_catt(void * ctx)
2607 {
2608 	struct arm_act_context *ic;
2609 	kern_return_t   kret;
2610 	thread_t thread = current_thread();
2611 
2612 	ic = (struct arm_act_context *) ctx;
2613 	if (ic == (struct arm_act_context *) NULL) {
2614 		return;
2615 	}
2616 
2617 	kret = machine_thread_set_state(thread, ARM_THREAD_STATE, (thread_state_t)&ic->ss, ARM_UNIFIED_THREAD_STATE_COUNT);
2618 	if (kret != KERN_SUCCESS) {
2619 		goto out;
2620 	}
2621 
2622 #if __ARM_VFP__
2623 	if (thread_is_64bit_data(thread)) {
2624 		kret = machine_thread_set_state(thread,
2625 		    ARM_NEON_STATE64,
2626 		    (thread_state_t)&ic->ns,
2627 		    ARM_NEON_STATE64_COUNT);
2628 	} else {
2629 		kret = machine_thread_set_state(thread,
2630 		    ARM_NEON_STATE,
2631 		    (thread_state_t)&ic->ns,
2632 		    ARM_NEON_STATE_COUNT);
2633 	}
2634 	if (kret != KERN_SUCCESS) {
2635 		goto out;
2636 	}
2637 #endif
2638 out:
2639 	kfree_type(struct arm_act_context, ic);
2640 }
2641 
2642 /*
2643  * Routine: act_thread_catt
2644  *
2645  */
2646 void
2647 act_thread_cfree(void *ctx)
2648 {
2649 	kfree_type(struct arm_act_context, ctx);
2650 }
2651 
2652 kern_return_t
2653 thread_set_wq_state32(thread_t       thread,
2654     thread_state_t tstate)
2655 {
2656 	arm_thread_state_t *state;
2657 	struct arm_saved_state *saved_state;
2658 	struct arm_saved_state32 *saved_state_32;
2659 	thread_t curth = current_thread();
2660 	spl_t s = 0;
2661 
2662 	assert(!thread_is_64bit_data(thread));
2663 
2664 	saved_state = thread->machine.upcb;
2665 	saved_state_32 = saved_state32(saved_state);
2666 
2667 	state = (arm_thread_state_t *)tstate;
2668 
2669 	if (curth != thread) {
2670 		s = splsched();
2671 		thread_lock(thread);
2672 	}
2673 
2674 	/*
2675 	 * do not zero saved_state, it can be concurrently accessed
2676 	 * and zero is not a valid state for some of the registers,
2677 	 * like sp.
2678 	 */
2679 	thread_state32_to_saved_state(state, saved_state);
2680 	saved_state_32->cpsr = PSR64_USER32_DEFAULT;
2681 
2682 	if (curth != thread) {
2683 		thread_unlock(thread);
2684 		splx(s);
2685 	}
2686 
2687 	return KERN_SUCCESS;
2688 }
2689 
2690 kern_return_t
2691 thread_set_wq_state64(thread_t       thread,
2692     thread_state_t tstate)
2693 {
2694 	arm_thread_state64_t *state;
2695 	struct arm_saved_state *saved_state;
2696 	struct arm_saved_state64 *saved_state_64;
2697 	thread_t curth = current_thread();
2698 	spl_t s = 0;
2699 
2700 	assert(thread_is_64bit_data(thread));
2701 
2702 	saved_state = thread->machine.upcb;
2703 	saved_state_64 = saved_state64(saved_state);
2704 	state = (arm_thread_state64_t *)tstate;
2705 
2706 	if (curth != thread) {
2707 		s = splsched();
2708 		thread_lock(thread);
2709 	}
2710 
2711 	/*
2712 	 * do not zero saved_state, it can be concurrently accessed
2713 	 * and zero is not a valid state for some of the registers,
2714 	 * like sp.
2715 	 */
2716 	thread_state64_to_saved_state(state, saved_state);
2717 	set_user_saved_state_cpsr(saved_state, PSR64_USER64_DEFAULT);
2718 
2719 	if (curth != thread) {
2720 		thread_unlock(thread);
2721 		splx(s);
2722 	}
2723 
2724 	return KERN_SUCCESS;
2725 }
2726