extern vm_offset_t intstack_top;
#if __arm64__
extern vm_offset_t excepstack_top;
+extern uint64_t events_per_sec;
#else
extern vm_offset_t fiqstack_top;
#endif
+
#if INTERRUPT_MASKED_DEBUG
boolean_t interrupt_masked_debug = 1;
uint64_t interrupt_masked_timeout = 0xd0000;
* JOP rebasing
*/
+#if defined(HAS_APPLE_PAC)
+#include <ptrauth.h>
+#endif /* defined(HAS_APPLE_PAC) */
// Note, the following should come from a header from dyld
static void
do {
uint64_t value = *(uint64_t*)address;
+#if HAS_APPLE_PAC
+ uint16_t diversity = (uint16_t)(value >> 32);
+ bool hasAddressDiversity = (value & (1ULL << 48)) != 0;
+ ptrauth_key key = (ptrauth_key)((value >> 49) & 0x3);
+#endif
bool isAuthenticated = (value & (1ULL << 63)) != 0;
bool isRebase = (value & (1ULL << 62)) == 0;
if (isRebase) {
uint64_t newValue = (value & 0xFFFFFFFF) + slide;
// Add in the offset from the mach_header
newValue += baseAddress;
+#if HAS_APPLE_PAC
+ // We have bits to merge in to the discriminator
+ uintptr_t discriminator = diversity;
+ if (hasAddressDiversity) {
+ // First calculate a new discriminator using the address of where we are trying to store the value
+ // Only blend if we have a discriminator
+ if (discriminator) {
+ discriminator = __builtin_ptrauth_blend_discriminator((void*)address, discriminator);
+ } else {
+ discriminator = address;
+ }
+ }
+ switch (key) {
+ case ptrauth_key_asia:
+ newValue = (uintptr_t)__builtin_ptrauth_sign_unauthenticated((void*)newValue, ptrauth_key_asia, discriminator);
+ break;
+ case ptrauth_key_asib:
+ newValue = (uintptr_t)__builtin_ptrauth_sign_unauthenticated((void*)newValue, ptrauth_key_asib, discriminator);
+ break;
+ case ptrauth_key_asda:
+ newValue = (uintptr_t)__builtin_ptrauth_sign_unauthenticated((void*)newValue, ptrauth_key_asda, discriminator);
+ break;
+ case ptrauth_key_asdb:
+ newValue = (uintptr_t)__builtin_ptrauth_sign_unauthenticated((void*)newValue, ptrauth_key_asdb, discriminator);
+ break;
+ }
+#endif
*(uint64_t*)address = newValue;
} else {
// Regular pointer which needs to fit in 51-bits of value.
return true;
}
+
/*
* Routine: arm_init
* Function:
BootArgs = args = &const_boot_args;
cpu_data_init(&BootCpuData);
+#if defined(HAS_APPLE_PAC)
+ /* bootstrap cpu process dependent key for kernel has been loaded by start.s */
+ BootCpuData.rop_key = KERNEL_ROP_ID;
+#endif /* defined(HAS_APPLE_PAC) */
PE_init_platform(FALSE, args); /* Get platform expert set up */
#if __arm64__
+#if defined(HAS_APPLE_PAC)
+ boolean_t user_jop = TRUE;
+ PE_parse_boot_argn("user_jop", &user_jop, sizeof(user_jop));
+ if (!user_jop) {
+ args->bootFlags |= kBootFlagsDisableUserJOP;
+ }
+ boolean_t user_ts_jop = TRUE;
+ PE_parse_boot_argn("user_ts_jop", &user_ts_jop, sizeof(user_ts_jop));
+ if (!user_ts_jop) {
+ args->bootFlags |= kBootFlagsDisableUserThreadStateJOP;
+ }
+#endif /* defined(HAS_APPLE_PAC) */
+
{
unsigned int tmp_16k = 0;
rtclock_early_init();
+ lck_mod_init();
+
+ /*
+ * Initialize the timer callout world
+ */
+ timer_call_init();
+
kernel_early_bootstrap();
cpu_init();
- EntropyData.index_ptr = EntropyData.buffer;
-
processor_bootstrap();
my_master_proc = master_processor;
/* Disable if WDT is disabled or no_interrupt_mask_debug in boot-args */
if (PE_parse_boot_argn("no_interrupt_masked_debug", &interrupt_masked_debug,
sizeof(interrupt_masked_debug)) || (PE_parse_boot_argn("wdt", &wdt_boot_arg,
- sizeof(wdt_boot_arg)) && (wdt_boot_arg == -1))) {
+ sizeof(wdt_boot_arg)) && (wdt_boot_arg == -1)) || kern_feature_override(KF_INTERRUPT_MASKED_DEBUG_OVRD)) {
interrupt_masked_debug = 0;
}
#endif
PE_init_platform(TRUE, &BootCpuData);
+
+#if __arm64__
+ if (PE_parse_boot_argn("wfe_events_sec", &events_per_sec, sizeof(events_per_sec))) {
+ if (events_per_sec <= 0) {
+ events_per_sec = 1;
+ } else if (events_per_sec > USEC_PER_SEC) {
+ events_per_sec = USEC_PER_SEC;
+ }
+ } else {
+#if defined(ARM_BOARD_WFE_TIMEOUT_NS)
+ events_per_sec = NSEC_PER_SEC / ARM_BOARD_WFE_TIMEOUT_NS;
+#else /* !defined(ARM_BOARD_WFE_TIMEOUT_NS) */
+ /* Default to 1usec (or as close as we can get) */
+ events_per_sec = USEC_PER_SEC;
+#endif /* !defined(ARM_BOARD_WFE_TIMEOUT_NS) */
+ }
+#endif
+
cpu_timebase_init(TRUE);
+ PE_init_cpu();
fiq_context_bootstrap(TRUE);
__builtin_arm_wsr("pan", 1);
#endif
+
cpu_data_ptr->cpu_flags &= ~SleepState;
#if __ARM_SMP__ && defined(ARMA7)
cpu_data_ptr->cpu_CLW_active = 1;
PE_init_platform(TRUE, NULL);
commpage_update_timebase();
}
+ PE_init_cpu();
fiq_context_init(TRUE);
cpu_data_ptr->rtcPop = EndOfAllTime;