]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/arm/arm_init.c
xnu-6153.11.26.tar.gz
[apple/xnu.git] / osfmk / arm / arm_init.c
index cf490691536474765aebdff9e8fdfc65e12b41e7..9f2b60169165682de9b68261bf1f327491e51a74 100644 (file)
@@ -85,6 +85,7 @@ extern void sleep_token_buffer_init(void);
 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
@@ -101,6 +102,7 @@ boolean_t up_style_idle_exit = 0;
 
 
 
+
 #if INTERRUPT_MASKED_DEBUG
 boolean_t interrupt_masked_debug = 1;
 uint64_t interrupt_masked_timeout = 0xd0000;
@@ -135,6 +137,9 @@ unsigned int page_shift_user32; /* for page_size as seen by a 32-bit task */
  * 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
@@ -145,6 +150,11 @@ rebase_chain(uintptr_t chainStartAddress, uint64_t stepMultiplier, uintptr_t bas
        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) {
@@ -153,6 +163,33 @@ rebase_chain(uintptr_t chainStartAddress, uint64_t stepMultiplier, uintptr_t bas
                                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.
@@ -190,6 +227,7 @@ rebase_threaded_starts(uint32_t *threadArrayStart, uint32_t *threadArrayEnd,
        return true;
 }
 
+
 /*
  *             Routine:                arm_init
  *             Function:
@@ -222,12 +260,29 @@ arm_init(
        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;
 
@@ -339,12 +394,17 @@ arm_init(
 
        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;
 
@@ -366,7 +426,7 @@ arm_init(
        /* 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;
        }
 
@@ -450,7 +510,26 @@ arm_init(
 #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);
 
 
@@ -483,6 +562,7 @@ arm_init_cpu(
        __builtin_arm_wsr("pan", 1);
 #endif
 
+
        cpu_data_ptr->cpu_flags &= ~SleepState;
 #if     __ARM_SMP__ && defined(ARMA7)
        cpu_data_ptr->cpu_CLW_active = 1;
@@ -528,6 +608,7 @@ arm_init_cpu(
                PE_init_platform(TRUE, NULL);
                commpage_update_timebase();
        }
+       PE_init_cpu();
 
        fiq_context_init(TRUE);
        cpu_data_ptr->rtcPop = EndOfAllTime;