/* * Copyright (c) 2007-2021 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. The rights granted to you under the License * may not be used to create, or enable the creation or redistribution of, * unlawful or unlicensed copies of an Apple operating system, or to * circumvent, violate, or enable the circumvention or violation of, any * terms of an Apple operating system software license agreement. * * Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * @OSF_COPYRIGHT@ */ /* * Mach Operating System * Copyright (c) 1991,1990,1989 Carnegie Mellon University * All Rights Reserved. * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. * * Carnegie Mellon requests users of this software to return to * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 * * any improvements or extensions that they make and grant Carnegie Mellon * the rights to redistribute these changes. */ /* */ #ifndef _ARM_THREAD_H_ #define _ARM_THREAD_H_ #include #include #include #include #ifdef MACH_KERNEL_PRIVATE #include #include #include #if SCHED_HYGIENE_DEBUG #include #endif #endif /* MACH_KERNEL_PRIVATE */ struct perfcontrol_state { uint64_t opaque[8] __attribute__((aligned(8))); }; /* * Maps state flavor to number of words in the state: */ extern unsigned int _MachineStateCount[]; #ifdef MACH_KERNEL_PRIVATE typedef arm_kernel_context_t machine_thread_kernel_state; #include #if (!__arm64__) #error Unknown arch #endif #if HAS_ARM_FEAT_SME #define HAVE_MACHINE_THREAD_MATRIX_STATE 1 #endif #if HAVE_MACHINE_THREAD_MATRIX_STATE #define UMATRIX_PTRAUTH XNU_PTRAUTH_SIGNED_PTR("machine_thread.umatrix_hdr") #endif /* * Machine Thread Structure */ struct machine_thread { #if __ARM_USER_PROTECT__ unsigned int uptw_ttb; unsigned int kptw_ttb; unsigned int asid; #else unsigned int reserved0; unsigned int reserved1; unsigned int reserved2; #endif uint32_t arm_machine_flags; /* thread flags (arm64/machine_machdep.h) */ arm_context_t * contextData; /* allocated user context */ arm_saved_state_t * XNU_PTRAUTH_SIGNED_PTR("machine_thread.upcb") upcb; /* pointer to user GPR state */ arm_neon_saved_state_t * XNU_PTRAUTH_SIGNED_PTR("machine_thread.uNeon") uNeon; /* pointer to user VFP state */ arm_saved_state_t * kpcb; /* pointer to kernel GPR state */ #if HAVE_MACHINE_THREAD_MATRIX_STATE union { arm_state_hdr_t *UMATRIX_PTRAUTH umatrix_hdr; #if HAS_ARM_FEAT_SME arm_sme_saved_state_t *UMATRIX_PTRAUTH usme; /* pointer to user SME state */ #endif }; #endif /* HAVE_MACHINE_THREAD_MATRIX_STATE */ long reserved4; uint64_t recover_far; arm_debug_state_t *DebugData; vm_address_t cthread_self; /* for use of cthread package */ uint64_t recover_esr; void * XNU_PTRAUTH_SIGNED_PTR("machine_thread.kstackptr") kstackptr; /* top of kernel stack */ struct perfcontrol_state perfctrl_state; uint64_t reserved5; #if SCHED_HYGIENE_DEBUG kern_timeout_t int_timeout; /* for interrupt disabled timeout mechanism */ unsigned int int_type; /* interrupt type of the interrupt that was processed */ uintptr_t int_handler_addr; /* slid, ptrauth-stripped virtual address of the interrupt handler */ uintptr_t int_vector; /* IOInterruptVector */ uint64_t int_time_mt; /* total time spent in interrupt context */ #endif /* SCHED_HYGIENE_DEBUG */ #if defined(CONFIG_XNUPOST) volatile expected_fault_handler_t expected_fault_handler; volatile uintptr_t expected_fault_addr; /* Address due to which an exception is expected to be thrown (FAR_ELx) */ volatile uintptr_t expected_fault_pc; /* PC at which an exception is expected to be thrown (ELR_ELx) */ #endif uint64_t reserved6; union { long pcpu_data_base_and_cpu_number; const uint16_t cpu_number; }; struct cpu_data * CpuDatap; /* current per cpu data */ unsigned int preemption_count; /* preemption count */ uint16_t exception_trace_code; bool reserved7; #if HAS_MTE bool sec_override; /* disable MTE for this thread, regardless of the current map's MTE policy */ bool el0_synchronous_trap; /* is this thread inside an EL0 synchronous trap handler? */ #else bool reserved8; bool reserved9; #endif #if defined(HAS_APPLE_PAC) uint64_t rop_pid; uint64_t jop_pid; #else uint64_t reserved10; uint64_t reserved11; #endif uint64_t reserved12; #if HAS_ARM_FEAT_SME uint64_t tpidr2_el0; #else uint64_t reserved13; #endif uint64_t reserved14; #if HAS_MTE bool in_unprivileged_access; #else bool reserved15; #endif }; #endif static inline long ml_make_pcpu_base_and_cpu_number(long base, uint16_t cpu) { return (base << 16) | cpu; } extern struct arm_saved_state * get_user_regs(thread_t); extern struct arm_saved_state * find_user_regs(thread_t); extern struct arm_saved_state * find_kern_regs(thread_t); extern struct arm_vfpsaved_state * find_user_vfp(thread_t); extern arm_debug_state32_t * find_debug_state32(thread_t); extern arm_debug_state32_t * find_or_allocate_debug_state32(thread_t); extern arm_debug_state64_t * find_debug_state64(thread_t); extern arm_debug_state64_t * find_or_allocate_debug_state64(thread_t); extern void set_user_neon_reg(thread_t, unsigned int, uint128_t); #define FIND_PERFCONTROL_STATE(th) (&th->machine.perfctrl_state) #ifdef MACH_KERNEL_PRIVATE #if __ARM_VFP__ extern void vfp_state_initialize(struct arm_vfpsaved_state *vfp_state); extern void vfp_save(struct arm_vfpsaved_state *vfp_ss); extern void vfp_load(struct arm_vfpsaved_state *vfp_ss); #endif /* __ARM_VFP__ */ extern void arm_debug_set(arm_debug_state_t *debug_state); extern void arm_debug_set32(arm_debug_state_t *debug_state); extern void arm_debug_set64(arm_debug_state_t *debug_state); #endif /* MACH_KERNEL_PRIVATE */ extern void *act_thread_csave(void); extern void act_thread_catt(void *ctx); extern void act_thread_cfree(void *ctx); #if MACH_KERNEL_PRIVATE #if HAS_ARM_FEAT_SME extern arm_sme_saved_state_t *machine_thread_get_sme_state(thread_t thread); extern kern_return_t machine_thread_sme_state_alloc(thread_t thread); #endif #if HAVE_MACHINE_THREAD_MATRIX_STATE extern void machine_thread_matrix_state_dup(thread_t target); #endif #endif /* MACH_KERNEL_PRIVATE */ #if HAS_APPLE_GENERIC_TIMER extern void agt_thread_bootstrap(void); #endif /* HAS_MACHINE_GENERIC_TIMER */ /* * Return address of the function that called current function, given * address of the first parameter of current function. */ #define GET_RETURN_PC(addr) (__builtin_return_address(0)) #endif /* _ARM_THREAD_H_ */