osfmk/arm64/status.c

xnu source @ f6217f8 2025-10-16 · 2725 lines · view on GitHub
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 47struct arm_vfpv2_state { 48 __uint32_t __r[32]; 49 __uint32_t __fpscr; 50}; 51 52typedef 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 */ 60void thread_set_child(thread_t child, int pid); 61static void free_debug_state(thread_t thread); 62user_addr_t thread_get_sigreturn_token(thread_t thread); 63uint32_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__ */ 69unsigned 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 91extern zone_t ads_zone; 92 93#if __arm64__ 94/* 95 * Copy values from saved_state to ts64. 96 */ 97void 98saved_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 */ 124void 125thread_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 177static kern_return_t 178handle_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 194static kern_return_t 195handle_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 212static kern_return_t 213handle_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 245static kern_return_t 246handle_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 258static kern_return_t 259handle_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 272static kern_return_t 273handle_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 310static kern_return_t 311handle_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 349static kern_return_t 350handle_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 381static kern_return_t 382handle_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 413static kern_return_t 414handle_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 446static kern_return_t 447handle_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 487static kern_return_t 488handle_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 514static kern_return_t 515handle_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 541static kern_return_t 542handle_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 570static kern_return_t 571handle_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 600static kern_return_t 601handle_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 632static inline uint32_t 633thread_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 651kern_return_t 652machine_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) 816extern char * proc_name_address(void *p); 817 818CA_EVENT(pac_thread_state_exception_event, 819 CA_STATIC_STRING(CA_PROCNAME_LEN), proc_name); 820 821static void 822machine_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 849CA_EVENT(pac_thread_state_sigreturn_event, 850 CA_STATIC_STRING(CA_PROCNAME_LEN), proc_name); 851 852static bool 853machine_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 900kern_return_t 901machine_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) 1101bool 1102machine_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 1117kern_return_t 1118machine_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 1151kern_return_t 1152machine_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 */ 1189kern_return_t 1190machine_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 */ 1546kern_return_t 1547machine_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 1592void 1593machine_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 1620extern long long arm_debug_get(void); 1621 1622/* 1623 * Routine: machine_thread_set_state 1624 * 1625 */ 1626kern_return_t 1627machine_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 2048mach_vm_address_t 2049machine_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 2055void 2056machine_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 */ 2065void 2066machine_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 */ 2121kern_return_t 2122machine_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 */ 2157struct arm_saved_state * 2158get_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 */ 2176void 2177set_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 */ 2197struct arm_saved_state * 2198find_user_regs(thread_t thread) 2199{ 2200 return thread->machine.upcb; 2201} 2202 2203/* 2204 * Routine: find_kern_regs 2205 * 2206 */ 2207struct arm_saved_state * 2208find_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 2220arm_debug_state32_t * 2221find_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 2230arm_debug_state64_t * 2231find_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 2240os_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 */ 2252arm_debug_state64_t * 2253find_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 */ 2278arm_debug_state32_t * 2279find_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 */ 2299static inline void 2300free_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 */ 2316kern_return_t 2317thread_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 */ 2392kern_return_t 2393thread_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 */ 2409void 2410thread_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 */ 2426user_addr_t 2427thread_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 */ 2447void 2448thread_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 */ 2472kern_return_t 2473thread_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 */ 2535void 2536thread_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 2548struct 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 */ 2559void * 2560act_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 */ 2605void 2606act_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 2638out: 2639 kfree_type(struct arm_act_context, ic); 2640} 2641 2642/* 2643 * Routine: act_thread_catt 2644 * 2645 */ 2646void 2647act_thread_cfree(void *ctx) 2648{ 2649 kfree_type(struct arm_act_context, ctx); 2650} 2651 2652kern_return_t 2653thread_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 2690kern_return_t 2691thread_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}