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