debug.c
1 /* 2 * Copyright (c) 2000-2020 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 /* 29 * @OSF_COPYRIGHT@ 30 */ 31 /* 32 * Mach Operating System 33 * Copyright (c) 1991,1990,1989 Carnegie Mellon University 34 * All Rights Reserved. 35 * 36 * Permission to use, copy, modify and distribute this software and its 37 * documentation is hereby granted, provided that both the copyright 38 * notice and this permission notice appear in all copies of the 39 * software, derivative works or modified versions, and any portions 40 * thereof, and that both notices appear in supporting documentation. 41 * 42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 43 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 45 * 46 * Carnegie Mellon requests users of this software to return to 47 * 48 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 49 * School of Computer Science 50 * Carnegie Mellon University 51 * Pittsburgh PA 15213-3890 52 * 53 * any improvements or extensions that they make and grant Carnegie Mellon 54 * the rights to redistribute these changes. 55 */ 56 57 #include <mach_assert.h> 58 #include <mach_kdp.h> 59 #include <kdp/kdp.h> 60 #include <kdp/kdp_core.h> 61 #include <kdp/kdp_internal.h> 62 #include <kdp/kdp_callout.h> 63 #include <kern/cpu_number.h> 64 #include <kern/kalloc.h> 65 #include <kern/percpu.h> 66 #include <kern/spl.h> 67 #include <kern/thread.h> 68 #include <kern/assert.h> 69 #include <kern/sched_prim.h> 70 #include <kern/misc_protos.h> 71 #include <kern/clock.h> 72 #include <kern/telemetry.h> 73 #include <kern/ecc.h> 74 #include <kern/kern_cdata.h> 75 #include <kern/zalloc_internal.h> 76 #include <vm/vm_kern.h> 77 #include <vm/vm_map.h> 78 #include <vm/pmap.h> 79 #include <stdarg.h> 80 #include <stdatomic.h> 81 #include <sys/pgo.h> 82 #include <console/serial_protos.h> 83 84 #if !(MACH_KDP && CONFIG_KDP_INTERACTIVE_DEBUGGING) 85 #include <kdp/kdp_udp.h> 86 #endif 87 #include <kern/processor.h> 88 89 #if defined(__i386__) || defined(__x86_64__) 90 #include <IOKit/IOBSD.h> 91 92 #include <i386/cpu_threads.h> 93 #include <i386/pmCPU.h> 94 #endif 95 96 #include <IOKit/IOPlatformExpert.h> 97 #include <machine/pal_routines.h> 98 99 #include <sys/kdebug.h> 100 #include <libkern/OSKextLibPrivate.h> 101 #include <libkern/OSAtomic.h> 102 #include <libkern/kernel_mach_header.h> 103 #include <libkern/section_keywords.h> 104 #include <uuid/uuid.h> 105 #include <mach_debug/zone_info.h> 106 #include <mach/resource_monitors.h> 107 108 #include <os/log_private.h> 109 110 #if defined(__arm__) || defined(__arm64__) 111 #include <pexpert/pexpert.h> /* For gPanicBase */ 112 #include <arm/caches_internal.h> 113 #include <arm/misc_protos.h> 114 extern volatile struct xnu_hw_shmem_dbg_command_info *hwsd_info; 115 #endif 116 117 #if CONFIG_XNUPOST 118 #include <tests/xnupost.h> 119 extern int vsnprintf(char *, size_t, const char *, va_list); 120 #endif 121 122 #if CONFIG_CSR 123 #include <sys/csr.h> 124 #endif 125 126 extern int IODTGetLoaderInfo( const char *key, void **infoAddr, int *infosize ); 127 128 unsigned int halt_in_debugger = 0; 129 unsigned int current_debugger = 0; 130 unsigned int active_debugger = 0; 131 unsigned int panicDebugging = FALSE; 132 unsigned int kernel_debugger_entry_count = 0; 133 134 #if defined(__arm__) || defined(__arm64__) 135 struct additional_panic_data_buffer *panic_data_buffers = NULL; 136 #endif 137 138 #if defined(__arm__) 139 #define TRAP_DEBUGGER __asm__ volatile("trap") 140 #elif defined(__arm64__) 141 /* 142 * Magic number; this should be identical to the __arm__ encoding for trap. 143 */ 144 #define TRAP_DEBUGGER __asm__ volatile(".long 0xe7ffdeff") 145 #elif defined (__x86_64__) 146 #define TRAP_DEBUGGER __asm__("int3") 147 #else 148 #error No TRAP_DEBUGGER for this architecture 149 #endif 150 151 #if defined(__i386__) || defined(__x86_64__) 152 #define panic_stop() pmCPUHalt(PM_HALT_PANIC) 153 #else 154 #define panic_stop() panic_spin_forever() 155 #endif 156 157 struct debugger_state { 158 uint64_t db_panic_options; 159 debugger_op db_current_op; 160 boolean_t db_proceed_on_sync_failure; 161 const char *db_message; 162 const char *db_panic_str; 163 va_list *db_panic_args; 164 void *db_panic_data_ptr; 165 unsigned long db_panic_caller; 166 /* incremented whenever we panic or call Debugger (current CPU panic level) */ 167 uint32_t db_entry_count; 168 kern_return_t db_op_return; 169 }; 170 static struct debugger_state PERCPU_DATA(debugger_state); 171 172 /* __pure2 is correct if this function is called with preemption disabled */ 173 static inline __pure2 struct debugger_state * 174 current_debugger_state(void) 175 { 176 return PERCPU_GET(debugger_state); 177 } 178 179 #define CPUDEBUGGEROP current_debugger_state()->db_current_op 180 #define CPUDEBUGGERMSG current_debugger_state()->db_message 181 #define CPUPANICSTR current_debugger_state()->db_panic_str 182 #define CPUPANICARGS current_debugger_state()->db_panic_args 183 #define CPUPANICOPTS current_debugger_state()->db_panic_options 184 #define CPUPANICDATAPTR current_debugger_state()->db_panic_data_ptr 185 #define CPUDEBUGGERSYNC current_debugger_state()->db_proceed_on_sync_failure 186 #define CPUDEBUGGERCOUNT current_debugger_state()->db_entry_count 187 #define CPUDEBUGGERRET current_debugger_state()->db_op_return 188 #define CPUPANICCALLER current_debugger_state()->db_panic_caller 189 190 #if DEVELOPMENT || DEBUG 191 #define DEBUGGER_DEBUGGING_NESTED_PANIC_IF_REQUESTED(requested) \ 192 MACRO_BEGIN \ 193 if (requested) { \ 194 volatile int *badpointer = (int *)4; \ 195 *badpointer = 0; \ 196 } \ 197 MACRO_END 198 #endif /* DEVELOPMENT || DEBUG */ 199 200 debugger_op debugger_current_op = DBOP_NONE; 201 const char *debugger_panic_str = NULL; 202 va_list *debugger_panic_args = NULL; 203 void *debugger_panic_data = NULL; 204 uint64_t debugger_panic_options = 0; 205 const char *debugger_message = NULL; 206 unsigned long debugger_panic_caller = 0; 207 208 void panic_trap_to_debugger(const char *panic_format_str, va_list *panic_args, 209 unsigned int reason, void *ctx, uint64_t panic_options_mask, void *panic_data, 210 unsigned long panic_caller) __dead2; 211 static void kdp_machine_reboot_type(unsigned int type, uint64_t debugger_flags); 212 void panic_spin_forever(void) __dead2; 213 extern kern_return_t do_stackshot(void); 214 extern void PE_panic_hook(const char*); 215 216 #define NESTEDDEBUGGERENTRYMAX 5 217 static unsigned int max_debugger_entry_count = NESTEDDEBUGGERENTRYMAX; 218 219 #if defined(__arm__) || defined(__arm64__) 220 #define DEBUG_BUF_SIZE (4096) 221 222 /* debug_buf is directly linked with iBoot panic region for arm targets */ 223 char *debug_buf_base = NULL; 224 char *debug_buf_ptr = NULL; 225 unsigned int debug_buf_size = 0; 226 227 SECURITY_READ_ONLY_LATE(boolean_t) kdp_explicitly_requested = FALSE; 228 #else /* defined(__arm__) || defined(__arm64__) */ 229 #define DEBUG_BUF_SIZE ((3 * PAGE_SIZE) + offsetof(struct macos_panic_header, mph_data)) 230 /* EXTENDED_DEBUG_BUF_SIZE definition is now in debug.h */ 231 static_assert(((EXTENDED_DEBUG_BUF_SIZE % PANIC_FLUSH_BOUNDARY) == 0), "Extended debug buf size must match SMC alignment requirements"); 232 233 char debug_buf[DEBUG_BUF_SIZE]; 234 struct macos_panic_header *panic_info = (struct macos_panic_header *)debug_buf; 235 char *debug_buf_base = (debug_buf + offsetof(struct macos_panic_header, mph_data)); 236 char *debug_buf_ptr = (debug_buf + offsetof(struct macos_panic_header, mph_data)); 237 238 /* 239 * We don't include the size of the panic header in the length of the data we actually write. 240 * On co-processor platforms, we lose sizeof(struct macos_panic_header) bytes from the end of 241 * the end of the log because we only support writing (3*PAGESIZE) bytes. 242 */ 243 unsigned int debug_buf_size = (DEBUG_BUF_SIZE - offsetof(struct macos_panic_header, mph_data)); 244 245 boolean_t extended_debug_log_enabled = FALSE; 246 #endif /* defined(__arm__) || defined(__arm64__) */ 247 248 #if defined(XNU_TARGET_OS_OSX) 249 #define KDBG_TRACE_PANIC_FILENAME "/var/tmp/panic.trace" 250 #else 251 #define KDBG_TRACE_PANIC_FILENAME "/var/log/panic.trace" 252 #endif 253 254 /* Debugger state */ 255 atomic_int debugger_cpu = ATOMIC_VAR_INIT(DEBUGGER_NO_CPU); 256 boolean_t debugger_allcpus_halted = FALSE; 257 boolean_t debugger_safe_to_return = TRUE; 258 unsigned int debugger_context = 0; 259 260 static char model_name[64]; 261 unsigned char *kernel_uuid; 262 263 boolean_t kernelcache_uuid_valid = FALSE; 264 uuid_t kernelcache_uuid; 265 uuid_string_t kernelcache_uuid_string; 266 267 boolean_t pageablekc_uuid_valid = FALSE; 268 uuid_t pageablekc_uuid; 269 uuid_string_t pageablekc_uuid_string; 270 271 boolean_t auxkc_uuid_valid = FALSE; 272 uuid_t auxkc_uuid; 273 uuid_string_t auxkc_uuid_string; 274 275 /* 276 * By default we treat Debugger() the same as calls to panic(), unless 277 * we have debug boot-args present and the DB_KERN_DUMP_ON_NMI *NOT* set. 278 * If DB_KERN_DUMP_ON_NMI is *NOT* set, return from Debugger() is supported. 279 * 280 * Return from Debugger() is currently only implemented on x86 281 */ 282 static boolean_t debugger_is_panic = TRUE; 283 284 TUNABLE(unsigned int, debug_boot_arg, "debug", 0); 285 286 char kernel_uuid_string[37]; /* uuid_string_t */ 287 char kernelcache_uuid_string[37]; /* uuid_string_t */ 288 char panic_disk_error_description[512]; 289 size_t panic_disk_error_description_size = sizeof(panic_disk_error_description); 290 291 extern unsigned int write_trace_on_panic; 292 int kext_assertions_enable = 293 #if DEBUG || DEVELOPMENT 294 TRUE; 295 #else 296 FALSE; 297 #endif 298 299 /* 300 * Maintain the physically-contiguous carveout for the `phys_carveout_mb` 301 * boot-arg. 302 */ 303 SECURITY_READ_ONLY_LATE(vm_offset_t) phys_carveout = 0; 304 SECURITY_READ_ONLY_LATE(uintptr_t) phys_carveout_pa = 0; 305 SECURITY_READ_ONLY_LATE(size_t) phys_carveout_size = 0; 306 307 boolean_t 308 kernel_debugging_allowed(void) 309 { 310 #if XNU_TARGET_OS_OSX 311 #if CONFIG_CSR 312 if (csr_check(CSR_ALLOW_KERNEL_DEBUGGER) != 0) { 313 return FALSE; 314 } 315 #endif /* CONFIG_CSR */ 316 return TRUE; 317 #else /* XNU_TARGET_OS_OSX */ 318 return PE_i_can_has_debugger(NULL); 319 #endif /* XNU_TARGET_OS_OSX */ 320 } 321 322 __startup_func 323 static void 324 panic_init(void) 325 { 326 unsigned long uuidlen = 0; 327 void *uuid; 328 329 uuid = getuuidfromheader(&_mh_execute_header, &uuidlen); 330 if ((uuid != NULL) && (uuidlen == sizeof(uuid_t))) { 331 kernel_uuid = uuid; 332 uuid_unparse_upper(*(uuid_t *)uuid, kernel_uuid_string); 333 } 334 335 /* 336 * Take the value of the debug boot-arg into account 337 */ 338 #if MACH_KDP 339 if (kernel_debugging_allowed() && debug_boot_arg) { 340 if (debug_boot_arg & DB_HALT) { 341 halt_in_debugger = 1; 342 } 343 344 #if defined(__arm__) || defined(__arm64__) 345 if (debug_boot_arg & DB_NMI) { 346 panicDebugging = TRUE; 347 } 348 #else 349 panicDebugging = TRUE; 350 #endif /* defined(__arm__) || defined(__arm64__) */ 351 } 352 353 if (!PE_parse_boot_argn("nested_panic_max", &max_debugger_entry_count, sizeof(max_debugger_entry_count))) { 354 max_debugger_entry_count = NESTEDDEBUGGERENTRYMAX; 355 } 356 357 #if defined(__arm__) || defined(__arm64__) 358 char kdpname[80]; 359 360 kdp_explicitly_requested = PE_parse_boot_argn("kdp_match_name", kdpname, sizeof(kdpname)); 361 #endif /* defined(__arm__) || defined(__arm64__) */ 362 363 #endif /* MACH_KDP */ 364 365 #if defined (__x86_64__) 366 /* 367 * By default we treat Debugger() the same as calls to panic(), unless 368 * we have debug boot-args present and the DB_KERN_DUMP_ON_NMI *NOT* set. 369 * If DB_KERN_DUMP_ON_NMI is *NOT* set, return from Debugger() is supported. 370 * This is because writing an on-device corefile is a destructive operation. 371 * 372 * Return from Debugger() is currently only implemented on x86 373 */ 374 if (PE_i_can_has_debugger(NULL) && !(debug_boot_arg & DB_KERN_DUMP_ON_NMI)) { 375 debugger_is_panic = FALSE; 376 } 377 #endif 378 } 379 STARTUP(TUNABLES, STARTUP_RANK_MIDDLE, panic_init); 380 381 #if defined (__x86_64__) 382 void 383 extended_debug_log_init(void) 384 { 385 assert(coprocessor_paniclog_flush); 386 /* 387 * Allocate an extended panic log buffer that has space for the panic 388 * stackshot at the end. Update the debug buf pointers appropriately 389 * to point at this new buffer. 390 * 391 * iBoot pre-initializes the panic region with the NULL character. We set this here 392 * so we can accurately calculate the CRC for the region without needing to flush the 393 * full region over SMC. 394 */ 395 char *new_debug_buf = kalloc_flags(EXTENDED_DEBUG_BUF_SIZE, Z_WAITOK | Z_ZERO); 396 397 panic_info = (struct macos_panic_header *)new_debug_buf; 398 debug_buf_ptr = debug_buf_base = (new_debug_buf + offsetof(struct macos_panic_header, mph_data)); 399 debug_buf_size = (EXTENDED_DEBUG_BUF_SIZE - offsetof(struct macos_panic_header, mph_data)); 400 401 extended_debug_log_enabled = TRUE; 402 403 /* 404 * Insert a compiler barrier so we don't free the other panic stackshot buffer 405 * until after we've marked the new one as available 406 */ 407 __compiler_barrier(); 408 kmem_free(kernel_map, panic_stackshot_buf, panic_stackshot_buf_len); 409 panic_stackshot_buf = 0; 410 panic_stackshot_buf_len = 0; 411 } 412 #endif /* defined (__x86_64__) */ 413 414 void 415 debug_log_init(void) 416 { 417 #if defined(__arm__) || defined(__arm64__) 418 if (!gPanicBase) { 419 printf("debug_log_init: Error!! gPanicBase is still not initialized\n"); 420 return; 421 } 422 /* Shift debug buf start location and size by the length of the panic header */ 423 debug_buf_base = (char *)gPanicBase + sizeof(struct embedded_panic_header); 424 debug_buf_ptr = debug_buf_base; 425 debug_buf_size = gPanicSize - sizeof(struct embedded_panic_header); 426 #else 427 kern_return_t kr = KERN_SUCCESS; 428 bzero(panic_info, DEBUG_BUF_SIZE); 429 430 assert(debug_buf_base != NULL); 431 assert(debug_buf_ptr != NULL); 432 assert(debug_buf_size != 0); 433 434 /* 435 * We allocate a buffer to store a panic time stackshot. If we later discover that this is a 436 * system that supports flushing a stackshot via an extended debug log (see above), we'll free this memory 437 * as it's not necessary on this platform. This information won't be available until the IOPlatform has come 438 * up. 439 */ 440 kr = kmem_alloc(kernel_map, &panic_stackshot_buf, PANIC_STACKSHOT_BUFSIZE, VM_KERN_MEMORY_DIAG); 441 assert(kr == KERN_SUCCESS); 442 if (kr == KERN_SUCCESS) { 443 panic_stackshot_buf_len = PANIC_STACKSHOT_BUFSIZE; 444 } 445 #endif 446 } 447 448 void 449 phys_carveout_init(void) 450 { 451 if (!PE_i_can_has_debugger(NULL)) { 452 return; 453 } 454 455 unsigned int phys_carveout_mb = 0; 456 457 if (!PE_parse_boot_argn("phys_carveout_mb", &phys_carveout_mb, 458 sizeof(phys_carveout_mb))) { 459 return; 460 } 461 if (phys_carveout_mb == 0) { 462 return; 463 } 464 465 size_t size = 0; 466 if (os_mul_overflow(phys_carveout_mb, 1024 * 1024, &size)) { 467 printf("phys_carveout_mb size overflowed (%uMB)\n", 468 phys_carveout_mb); 469 return; 470 } 471 472 kern_return_t kr = kmem_alloc_contig(kernel_map, &phys_carveout, size, 473 VM_MAP_PAGE_MASK(kernel_map), 0, 0, KMA_NOPAGEWAIT, 474 VM_KERN_MEMORY_DIAG); 475 if (kr != KERN_SUCCESS) { 476 printf("failed to allocate %uMB for phys_carveout_mb: %u\n", 477 phys_carveout_mb, (unsigned int)kr); 478 return; 479 } 480 481 phys_carveout_pa = kvtophys(phys_carveout); 482 phys_carveout_size = size; 483 } 484 485 static void 486 DebuggerLock(void) 487 { 488 int my_cpu = cpu_number(); 489 int debugger_exp_cpu = DEBUGGER_NO_CPU; 490 assert(ml_get_interrupts_enabled() == FALSE); 491 492 if (atomic_load(&debugger_cpu) == my_cpu) { 493 return; 494 } 495 496 while (!atomic_compare_exchange_strong(&debugger_cpu, &debugger_exp_cpu, my_cpu)) { 497 debugger_exp_cpu = DEBUGGER_NO_CPU; 498 } 499 500 return; 501 } 502 503 static void 504 DebuggerUnlock(void) 505 { 506 assert(atomic_load_explicit(&debugger_cpu, memory_order_relaxed) == cpu_number()); 507 508 /* 509 * We don't do an atomic exchange here in case 510 * there's another CPU spinning to acquire the debugger_lock 511 * and we never get a chance to update it. We already have the 512 * lock so we can simply store DEBUGGER_NO_CPU and follow with 513 * a barrier. 514 */ 515 atomic_store(&debugger_cpu, DEBUGGER_NO_CPU); 516 OSMemoryBarrier(); 517 518 return; 519 } 520 521 static kern_return_t 522 DebuggerHaltOtherCores(boolean_t proceed_on_failure) 523 { 524 #if defined(__arm__) || defined(__arm64__) 525 return DebuggerXCallEnter(proceed_on_failure); 526 #else /* defined(__arm__) || defined(__arm64__) */ 527 #pragma unused(proceed_on_failure) 528 mp_kdp_enter(proceed_on_failure); 529 return KERN_SUCCESS; 530 #endif 531 } 532 533 static void 534 DebuggerResumeOtherCores(void) 535 { 536 #if defined(__arm__) || defined(__arm64__) 537 DebuggerXCallReturn(); 538 #else /* defined(__arm__) || defined(__arm64__) */ 539 mp_kdp_exit(); 540 #endif 541 } 542 543 static void 544 DebuggerSaveState(debugger_op db_op, const char *db_message, const char *db_panic_str, 545 va_list *db_panic_args, uint64_t db_panic_options, void *db_panic_data_ptr, 546 boolean_t db_proceed_on_sync_failure, unsigned long db_panic_caller) 547 { 548 CPUDEBUGGEROP = db_op; 549 550 /* Preserve the original panic message */ 551 if (CPUDEBUGGERCOUNT == 1 || CPUPANICSTR == NULL) { 552 CPUDEBUGGERMSG = db_message; 553 CPUPANICSTR = db_panic_str; 554 CPUPANICARGS = db_panic_args; 555 CPUPANICDATAPTR = db_panic_data_ptr; 556 CPUPANICCALLER = db_panic_caller; 557 } else if (CPUDEBUGGERCOUNT > 1 && db_panic_str != NULL) { 558 kprintf("Nested panic detected:"); 559 if (db_panic_str != NULL) { 560 _doprnt(db_panic_str, db_panic_args, PE_kputc, 0); 561 } 562 } 563 564 CPUDEBUGGERSYNC = db_proceed_on_sync_failure; 565 CPUDEBUGGERRET = KERN_SUCCESS; 566 567 /* Reset these on any nested panics */ 568 CPUPANICOPTS = db_panic_options; 569 570 return; 571 } 572 573 /* 574 * Save the requested debugger state/action into the current processor's 575 * percu state and trap to the debugger. 576 */ 577 kern_return_t 578 DebuggerTrapWithState(debugger_op db_op, const char *db_message, const char *db_panic_str, 579 va_list *db_panic_args, uint64_t db_panic_options, void *db_panic_data_ptr, 580 boolean_t db_proceed_on_sync_failure, unsigned long db_panic_caller) 581 { 582 kern_return_t ret; 583 584 assert(ml_get_interrupts_enabled() == FALSE); 585 DebuggerSaveState(db_op, db_message, db_panic_str, db_panic_args, 586 db_panic_options, db_panic_data_ptr, 587 db_proceed_on_sync_failure, db_panic_caller); 588 589 /* 590 * On ARM this generates an uncategorized exception -> sleh code -> 591 * DebuggerCall -> kdp_trap -> handle_debugger_trap 592 * So that is how XNU ensures that only one core can panic. 593 * The rest of the cores are halted by IPI if possible; if that 594 * fails it will fall back to dbgwrap. 595 */ 596 TRAP_DEBUGGER; 597 598 ret = CPUDEBUGGERRET; 599 600 DebuggerSaveState(DBOP_NONE, NULL, NULL, NULL, 0, NULL, FALSE, 0); 601 602 return ret; 603 } 604 605 void __attribute__((noinline)) 606 Assert( 607 const char *file, 608 int line, 609 const char *expression 610 ) 611 { 612 #if CONFIG_NONFATAL_ASSERTS 613 static TUNABLE(bool, mach_assert, "assertions", true); 614 615 if (!mach_assert) { 616 kprintf("%s:%d non-fatal Assertion: %s", file, line, expression); 617 return; 618 } 619 #endif 620 621 panic_plain("%s:%d Assertion failed: %s", file, line, expression); 622 } 623 624 boolean_t 625 debug_is_current_cpu_in_panic_state(void) 626 { 627 return current_debugger_state()->db_entry_count > 0; 628 } 629 630 void 631 Debugger(const char *message) 632 { 633 DebuggerWithContext(0, NULL, message, DEBUGGER_OPTION_NONE); 634 } 635 636 void 637 DebuggerWithContext(unsigned int reason, void *ctx, const char *message, 638 uint64_t debugger_options_mask) 639 { 640 spl_t previous_interrupts_state; 641 boolean_t old_doprnt_hide_pointers = doprnt_hide_pointers; 642 643 previous_interrupts_state = ml_set_interrupts_enabled(FALSE); 644 disable_preemption(); 645 646 CPUDEBUGGERCOUNT++; 647 648 if (CPUDEBUGGERCOUNT > max_debugger_entry_count) { 649 static boolean_t in_panic_kprintf = FALSE; 650 651 /* Notify any listeners that we've started a panic */ 652 uint32_t panic_details = 0; 653 if (debugger_options_mask & DEBUGGER_OPTION_PANICLOGANDREBOOT) { 654 panic_details |= kPanicDetailsForcePowerOff; 655 } 656 PEHaltRestartInternal(kPEPanicBegin, panic_details); 657 658 if (!in_panic_kprintf) { 659 in_panic_kprintf = TRUE; 660 kprintf("Detected nested debugger entry count exceeding %d\n", 661 max_debugger_entry_count); 662 in_panic_kprintf = FALSE; 663 } 664 665 if (!panicDebugging) { 666 kdp_machine_reboot_type(kPEPanicRestartCPU, debugger_options_mask); 667 } 668 669 panic_spin_forever(); 670 } 671 672 /* Handle any necessary platform specific actions before we proceed */ 673 PEInitiatePanic(); 674 675 #if DEVELOPMENT || DEBUG 676 DEBUGGER_DEBUGGING_NESTED_PANIC_IF_REQUESTED((debugger_options_mask & DEBUGGER_OPTION_RECURPANIC_ENTRY)); 677 #endif 678 679 doprnt_hide_pointers = FALSE; 680 681 if (ctx != NULL) { 682 DebuggerSaveState(DBOP_DEBUGGER, message, 683 NULL, NULL, debugger_options_mask, NULL, TRUE, 0); 684 handle_debugger_trap(reason, 0, 0, ctx); 685 DebuggerSaveState(DBOP_NONE, NULL, NULL, 686 NULL, 0, NULL, FALSE, 0); 687 } else { 688 DebuggerTrapWithState(DBOP_DEBUGGER, message, 689 NULL, NULL, debugger_options_mask, NULL, TRUE, 0); 690 } 691 692 CPUDEBUGGERCOUNT--; 693 doprnt_hide_pointers = old_doprnt_hide_pointers; 694 enable_preemption(); 695 ml_set_interrupts_enabled(previous_interrupts_state); 696 } 697 698 static struct kdp_callout { 699 struct kdp_callout * callout_next; 700 kdp_callout_fn_t callout_fn; 701 boolean_t callout_in_progress; 702 void * callout_arg; 703 } * kdp_callout_list = NULL; 704 705 /* 706 * Called from kernel context to register a kdp event callout. 707 */ 708 void 709 kdp_register_callout(kdp_callout_fn_t fn, void * arg) 710 { 711 struct kdp_callout * kcp; 712 struct kdp_callout * list_head; 713 714 kcp = kalloc(sizeof(*kcp)); 715 if (kcp == NULL) { 716 panic("kdp_register_callout() kalloc failed"); 717 } 718 719 kcp->callout_fn = fn; 720 kcp->callout_arg = arg; 721 kcp->callout_in_progress = FALSE; 722 723 /* Lock-less list insertion using compare and exchange. */ 724 do { 725 list_head = kdp_callout_list; 726 kcp->callout_next = list_head; 727 } while (!OSCompareAndSwapPtr(list_head, kcp, &kdp_callout_list)); 728 } 729 730 static void 731 kdp_callouts(kdp_event_t event) 732 { 733 struct kdp_callout *kcp = kdp_callout_list; 734 735 while (kcp) { 736 if (!kcp->callout_in_progress) { 737 kcp->callout_in_progress = TRUE; 738 kcp->callout_fn(kcp->callout_arg, event); 739 kcp->callout_in_progress = FALSE; 740 } 741 kcp = kcp->callout_next; 742 } 743 } 744 745 #if defined(__arm__) || defined(__arm64__) 746 /* 747 * Register an additional buffer with data to include in the panic log 748 * 749 * <rdar://problem/50137705> tracks supporting more than one buffer 750 * 751 * Note that producer_name and buf should never be de-allocated as we reference these during panic. 752 */ 753 void 754 register_additional_panic_data_buffer(const char *producer_name, void *buf, int len) 755 { 756 if (panic_data_buffers != NULL) { 757 panic("register_additional_panic_data_buffer called with buffer already registered"); 758 } 759 760 if (producer_name == NULL || (strlen(producer_name) == 0)) { 761 panic("register_additional_panic_data_buffer called with invalid producer_name"); 762 } 763 764 if (buf == NULL) { 765 panic("register_additional_panic_data_buffer called with invalid buffer pointer"); 766 } 767 768 if ((len <= 0) || (len > ADDITIONAL_PANIC_DATA_BUFFER_MAX_LEN)) { 769 panic("register_additional_panic_data_buffer called with invalid length"); 770 } 771 772 struct additional_panic_data_buffer *new_panic_data_buffer = kalloc(sizeof(struct additional_panic_data_buffer)); 773 new_panic_data_buffer->producer_name = producer_name; 774 new_panic_data_buffer->buf = buf; 775 new_panic_data_buffer->len = len; 776 777 if (!OSCompareAndSwapPtr(NULL, new_panic_data_buffer, &panic_data_buffers)) { 778 panic("register_additional_panic_data_buffer called with buffer already registered"); 779 } 780 781 return; 782 } 783 #endif /* defined(__arm__) || defined(__arm64__) */ 784 785 /* 786 * An overview of the xnu panic path: 787 * 788 * Several panic wrappers (panic(), panic_with_options(), etc.) all funnel into panic_trap_to_debugger(). 789 * panic_trap_to_debugger() sets the panic state in the current processor's debugger_state prior 790 * to trapping into the debugger. Once we trap to the debugger, we end up in handle_debugger_trap() 791 * which tries to acquire the panic lock by atomically swapping the current CPU number into debugger_cpu. 792 * debugger_cpu acts as a synchronization point, from which the winning CPU can halt the other cores and 793 * continue to debugger_collect_diagnostics() where we write the paniclog, corefile (if appropriate) and proceed 794 * according to the device's boot-args. 795 */ 796 #undef panic 797 void 798 panic(const char *str, ...) 799 { 800 va_list panic_str_args; 801 802 va_start(panic_str_args, str); 803 panic_trap_to_debugger(str, &panic_str_args, 0, NULL, 0, NULL, (unsigned long)(char *)__builtin_return_address(0)); 804 va_end(panic_str_args); 805 } 806 807 void 808 panic_with_options(unsigned int reason, void *ctx, uint64_t debugger_options_mask, const char *str, ...) 809 { 810 va_list panic_str_args; 811 812 va_start(panic_str_args, str); 813 panic_trap_to_debugger(str, &panic_str_args, reason, ctx, (debugger_options_mask & ~DEBUGGER_INTERNAL_OPTIONS_MASK), 814 NULL, (unsigned long)(char *)__builtin_return_address(0)); 815 va_end(panic_str_args); 816 } 817 818 #if defined (__x86_64__) 819 /* 820 * panic_with_thread_context() is used on x86 platforms to specify a different thread that should be backtraced in the paniclog. 821 * We don't generally need this functionality on embedded platforms because embedded platforms include a panic time stackshot 822 * from customer devices. We plumb the thread pointer via the debugger trap mechanism and backtrace the kernel stack from the 823 * thread when writing the panic log. 824 * 825 * NOTE: panic_with_thread_context() should be called with an explicit thread reference held on the passed thread. 826 */ 827 void 828 panic_with_thread_context(unsigned int reason, void *ctx, uint64_t debugger_options_mask, thread_t thread, const char *str, ...) 829 { 830 va_list panic_str_args; 831 __assert_only os_ref_count_t th_ref_count; 832 833 assert_thread_magic(thread); 834 th_ref_count = os_ref_get_count(&thread->ref_count); 835 assertf(th_ref_count > 0, "panic_with_thread_context called with invalid thread %p with refcount %u", thread, th_ref_count); 836 837 /* Take a reference on the thread so it doesn't disappear by the time we try to backtrace it */ 838 thread_reference(thread); 839 840 va_start(panic_str_args, str); 841 panic_trap_to_debugger(str, &panic_str_args, reason, ctx, ((debugger_options_mask & ~DEBUGGER_INTERNAL_OPTIONS_MASK) | DEBUGGER_INTERNAL_OPTION_THREAD_BACKTRACE), 842 thread, (unsigned long)(char *)__builtin_return_address(0)); 843 844 va_end(panic_str_args); 845 } 846 #endif /* defined (__x86_64__) */ 847 848 #pragma clang diagnostic push 849 #pragma clang diagnostic ignored "-Wmissing-noreturn" 850 void 851 panic_trap_to_debugger(const char *panic_format_str, va_list *panic_args, unsigned int reason, void *ctx, 852 uint64_t panic_options_mask, void *panic_data_ptr, unsigned long panic_caller) 853 { 854 #pragma clang diagnostic pop 855 856 #if defined(__x86_64__) && (DEVELOPMENT || DEBUG) 857 /* Turn off I/O tracing once we've panicked */ 858 mmiotrace_enabled = 0; 859 #endif 860 861 ml_panic_trap_to_debugger(panic_format_str, panic_args, reason, ctx, panic_options_mask, panic_caller); 862 863 CPUDEBUGGERCOUNT++; 864 865 if (CPUDEBUGGERCOUNT > max_debugger_entry_count) { 866 static boolean_t in_panic_kprintf = FALSE; 867 868 /* Notify any listeners that we've started a panic */ 869 uint32_t panic_details = 0; 870 if (panic_options_mask & DEBUGGER_OPTION_PANICLOGANDREBOOT) { 871 panic_details |= kPanicDetailsForcePowerOff; 872 } 873 PEHaltRestartInternal(kPEPanicBegin, panic_details); 874 875 if (!in_panic_kprintf) { 876 in_panic_kprintf = TRUE; 877 kprintf("Detected nested debugger entry count exceeding %d\n", 878 max_debugger_entry_count); 879 in_panic_kprintf = FALSE; 880 } 881 882 if (!panicDebugging) { 883 kdp_machine_reboot_type(kPEPanicRestartCPU, panic_options_mask); 884 } 885 886 panic_spin_forever(); 887 } 888 889 /* Handle any necessary platform specific actions before we proceed */ 890 PEInitiatePanic(); 891 892 #if DEVELOPMENT || DEBUG 893 DEBUGGER_DEBUGGING_NESTED_PANIC_IF_REQUESTED((panic_options_mask & DEBUGGER_OPTION_RECURPANIC_ENTRY)); 894 #endif 895 896 PE_panic_hook(panic_format_str); 897 898 #if defined (__x86_64__) 899 plctrace_disable(); 900 #endif 901 902 if (write_trace_on_panic && kdebug_enable) { 903 if (get_preemption_level() == 0 && !ml_at_interrupt_context()) { 904 ml_set_interrupts_enabled(TRUE); 905 KDBG_RELEASE(TRACE_PANIC); 906 kdbg_dump_trace_to_file(KDBG_TRACE_PANIC_FILENAME); 907 } 908 } 909 910 ml_set_interrupts_enabled(FALSE); 911 disable_preemption(); 912 913 #if defined (__x86_64__) 914 pmSafeMode(x86_lcpu(), PM_SAFE_FL_SAFE); 915 #endif /* defined (__x86_64__) */ 916 917 /* Never hide pointers from panic logs. */ 918 doprnt_hide_pointers = FALSE; 919 920 if (ctx != NULL) { 921 /* 922 * We called into panic from a trap, no need to trap again. Set the 923 * state on the current CPU and then jump to handle_debugger_trap. 924 */ 925 DebuggerSaveState(DBOP_PANIC, "panic", 926 panic_format_str, panic_args, 927 panic_options_mask, panic_data_ptr, TRUE, panic_caller); 928 handle_debugger_trap(reason, 0, 0, ctx); 929 } 930 931 #if defined(__arm64__) 932 /* 933 * Signal to fastsim that it should open debug ports (nop on hardware) 934 */ 935 __asm__ volatile ("HINT 0x45"); 936 #endif /* defined(__arm64__) */ 937 938 DebuggerTrapWithState(DBOP_PANIC, "panic", panic_format_str, 939 panic_args, panic_options_mask, panic_data_ptr, TRUE, panic_caller); 940 941 /* 942 * Not reached. 943 */ 944 panic_stop(); 945 __builtin_unreachable(); 946 } 947 948 void 949 panic_spin_forever(void) 950 { 951 paniclog_append_noflush("\nPlease go to https://panic.apple.com to report this panic\n"); 952 953 for (;;) { 954 } 955 } 956 957 static void 958 kdp_machine_reboot_type(unsigned int type, uint64_t debugger_flags) 959 { 960 printf("Attempting system restart...\n"); 961 if ((type == kPEPanicRestartCPU) && (debugger_flags & DEBUGGER_OPTION_SKIP_PANICEND_CALLOUTS)) { 962 PEHaltRestart(kPEPanicRestartCPUNoCallouts); 963 } else { 964 PEHaltRestart(type); 965 } 966 halt_all_cpus(TRUE); 967 } 968 969 void 970 kdp_machine_reboot(void) 971 { 972 kdp_machine_reboot_type(kPEPanicRestartCPU, 0); 973 } 974 975 /* 976 * Gather and save diagnostic information about a panic (or Debugger call). 977 * 978 * On embedded, Debugger and Panic are treated very similarly -- WDT uses Debugger so we can 979 * theoretically return from it. On desktop, Debugger is treated as a conventional debugger -- i.e no 980 * paniclog is written and no core is written unless we request a core on NMI. 981 * 982 * This routine handles kicking off local coredumps, paniclogs, calling into the Debugger/KDP (if it's configured), 983 * and calling out to any other functions we have for collecting diagnostic info. 984 */ 985 static void 986 debugger_collect_diagnostics(unsigned int exception, unsigned int code, unsigned int subcode, void *state) 987 { 988 #if DEVELOPMENT || DEBUG 989 DEBUGGER_DEBUGGING_NESTED_PANIC_IF_REQUESTED((debugger_panic_options & DEBUGGER_OPTION_RECURPANIC_PRELOG)); 990 #endif 991 992 #if defined(__x86_64__) 993 kprintf("Debugger called: <%s>\n", debugger_message ? debugger_message : ""); 994 #endif 995 /* 996 * DB_HALT (halt_in_debugger) can be requested on startup, we shouldn't generate 997 * a coredump/paniclog for this type of debugger entry. If KDP isn't configured, 998 * we'll just spin in kdp_raise_exception. 999 */ 1000 if (debugger_current_op == DBOP_DEBUGGER && halt_in_debugger) { 1001 kdp_raise_exception(exception, code, subcode, state); 1002 if (debugger_safe_to_return && !debugger_is_panic) { 1003 return; 1004 } 1005 } 1006 1007 if ((debugger_current_op == DBOP_PANIC) || 1008 ((debugger_current_op == DBOP_DEBUGGER) && debugger_is_panic)) { 1009 /* 1010 * Attempt to notify listeners once and only once that we've started 1011 * panicking. Only do this for Debugger() calls if we're treating 1012 * Debugger() calls like panic(). 1013 */ 1014 uint32_t panic_details = 0; 1015 if (debugger_panic_options & DEBUGGER_OPTION_PANICLOGANDREBOOT) { 1016 panic_details |= kPanicDetailsForcePowerOff; 1017 } 1018 PEHaltRestartInternal(kPEPanicBegin, panic_details); 1019 1020 /* 1021 * Set the begin pointer in the panic log structure. We key off of this 1022 * static variable rather than contents from the panic header itself in case someone 1023 * has stomped over the panic_info structure. Also initializes the header magic. 1024 */ 1025 static boolean_t began_writing_paniclog = FALSE; 1026 if (!began_writing_paniclog) { 1027 PE_init_panicheader(); 1028 began_writing_paniclog = TRUE; 1029 } else { 1030 /* 1031 * If we reached here, update the panic header to keep it as consistent 1032 * as possible during a nested panic 1033 */ 1034 PE_update_panicheader_nestedpanic(); 1035 } 1036 } 1037 1038 /* 1039 * Write panic string if this was a panic. 1040 * 1041 * TODO: Consider moving to SavePanicInfo as this is part of the panic log. 1042 */ 1043 if (debugger_current_op == DBOP_PANIC) { 1044 paniclog_append_noflush("panic(cpu %d caller 0x%lx): ", (unsigned) cpu_number(), debugger_panic_caller); 1045 if (debugger_panic_str) { 1046 _doprnt(debugger_panic_str, debugger_panic_args, consdebug_putc, 0); 1047 } 1048 paniclog_append_noflush("\n"); 1049 } 1050 #if defined(__x86_64__) 1051 else if (((debugger_current_op == DBOP_DEBUGGER) && debugger_is_panic)) { 1052 paniclog_append_noflush("Debugger called: <%s>\n", debugger_message ? debugger_message : ""); 1053 } 1054 1055 /* 1056 * Debugger() is treated like panic() on embedded -- for example we use it for WDT 1057 * panics (so we need to write a paniclog). On desktop Debugger() is used in the 1058 * conventional sense. 1059 */ 1060 if (debugger_current_op == DBOP_PANIC || ((debugger_current_op == DBOP_DEBUGGER) && debugger_is_panic)) 1061 #endif /* __x86_64__ */ 1062 { 1063 kdp_callouts(KDP_EVENT_PANICLOG); 1064 1065 /* 1066 * Write paniclog and panic stackshot (if supported) 1067 * TODO: Need to clear panic log when return from debugger 1068 * hooked up for embedded 1069 */ 1070 SavePanicInfo(debugger_message, debugger_panic_data, debugger_panic_options); 1071 1072 #if DEVELOPMENT || DEBUG 1073 DEBUGGER_DEBUGGING_NESTED_PANIC_IF_REQUESTED((debugger_panic_options & DEBUGGER_OPTION_RECURPANIC_POSTLOG)); 1074 #endif 1075 1076 /* DEBUGGER_OPTION_PANICLOGANDREBOOT is used for two finger resets on embedded so we get a paniclog */ 1077 if (debugger_panic_options & DEBUGGER_OPTION_PANICLOGANDREBOOT) { 1078 PEHaltRestart(kPEPanicDiagnosticsDone); 1079 PEHaltRestart(kPEPanicRestartCPUNoCallouts); 1080 } 1081 } 1082 1083 #if CONFIG_KDP_INTERACTIVE_DEBUGGING 1084 /* 1085 * If reboot on panic is enabled and the caller of panic indicated that we should skip 1086 * local coredumps, don't try to write these and instead go straight to reboot. This 1087 * allows us to persist any data that's stored in the panic log. 1088 */ 1089 if ((debugger_panic_options & DEBUGGER_OPTION_SKIP_LOCAL_COREDUMP) && 1090 (debug_boot_arg & DB_REBOOT_POST_CORE)) { 1091 PEHaltRestart(kPEPanicDiagnosticsDone); 1092 kdp_machine_reboot_type(kPEPanicRestartCPU, debugger_panic_options); 1093 } 1094 1095 /* 1096 * Consider generating a local corefile if the infrastructure is configured 1097 * and we haven't disabled on-device coredumps. 1098 */ 1099 if (on_device_corefile_enabled()) { 1100 if (!kdp_has_polled_corefile()) { 1101 if (debug_boot_arg & (DB_KERN_DUMP_ON_PANIC | DB_KERN_DUMP_ON_NMI)) { 1102 paniclog_append_noflush("skipping local kernel core because core file could not be opened prior to panic (error : 0x%x)\n", 1103 kdp_polled_corefile_error()); 1104 #if defined(__arm__) || defined(__arm64__) 1105 panic_info->eph_panic_flags |= EMBEDDED_PANIC_HEADER_FLAG_COREDUMP_FAILED; 1106 paniclog_flush(); 1107 #else /* defined(__arm__) || defined(__arm64__) */ 1108 if (panic_info->mph_panic_log_offset != 0) { 1109 panic_info->mph_panic_flags |= MACOS_PANIC_HEADER_FLAG_COREDUMP_FAILED; 1110 paniclog_flush(); 1111 } 1112 #endif /* defined(__arm__) || defined(__arm64__) */ 1113 } 1114 } 1115 #if XNU_MONITOR 1116 else if ((pmap_get_cpu_data()->ppl_state == PPL_STATE_PANIC) && (debug_boot_arg & (DB_KERN_DUMP_ON_PANIC | DB_KERN_DUMP_ON_NMI))) { 1117 paniclog_append_noflush("skipping local kernel core because the PPL is in PANIC state\n"); 1118 panic_info->eph_panic_flags |= EMBEDDED_PANIC_HEADER_FLAG_COREDUMP_FAILED; 1119 paniclog_flush(); 1120 } 1121 #endif /* XNU_MONITOR */ 1122 else { 1123 int ret = -1; 1124 1125 #if defined (__x86_64__) 1126 /* On x86 we don't do a coredump on Debugger unless the DB_KERN_DUMP_ON_NMI boot-arg is specified. */ 1127 if (debugger_current_op != DBOP_DEBUGGER || (debug_boot_arg & DB_KERN_DUMP_ON_NMI)) 1128 #endif 1129 { 1130 /* 1131 * Doing an on-device coredump leaves the disk driver in a state 1132 * that can not be resumed. 1133 */ 1134 debugger_safe_to_return = FALSE; 1135 begin_panic_transfer(); 1136 ret = kern_dump(KERN_DUMP_DISK); 1137 abort_panic_transfer(); 1138 1139 #if DEVELOPMENT || DEBUG 1140 DEBUGGER_DEBUGGING_NESTED_PANIC_IF_REQUESTED((debugger_panic_options & DEBUGGER_OPTION_RECURPANIC_POSTCORE)); 1141 #endif 1142 } 1143 1144 /* 1145 * If DB_REBOOT_POST_CORE is set, then reboot if coredump is sucessfully saved 1146 * or if option to ignore failures is set. 1147 */ 1148 if ((debug_boot_arg & DB_REBOOT_POST_CORE) && 1149 ((ret == 0) || (debugger_panic_options & DEBUGGER_OPTION_ATTEMPTCOREDUMPANDREBOOT))) { 1150 PEHaltRestart(kPEPanicDiagnosticsDone); 1151 kdp_machine_reboot_type(kPEPanicRestartCPU, debugger_panic_options); 1152 } 1153 } 1154 } 1155 1156 if (debugger_current_op == DBOP_PANIC || 1157 ((debugger_current_op == DBOP_DEBUGGER) && debugger_is_panic)) { 1158 PEHaltRestart(kPEPanicDiagnosticsDone); 1159 } 1160 1161 if (debug_boot_arg & DB_REBOOT_ALWAYS) { 1162 kdp_machine_reboot_type(kPEPanicRestartCPU, debugger_panic_options); 1163 } 1164 1165 /* If KDP is configured, try to trap to the debugger */ 1166 #if defined(__arm__) || defined(__arm64__) 1167 if (kdp_explicitly_requested && (current_debugger != NO_CUR_DB)) { 1168 #else 1169 if (current_debugger != NO_CUR_DB) { 1170 #endif 1171 kdp_raise_exception(exception, code, subcode, state); 1172 /* 1173 * Only return if we entered via Debugger and it's safe to return 1174 * (we halted the other cores successfully, this isn't a nested panic, etc) 1175 */ 1176 if (debugger_current_op == DBOP_DEBUGGER && 1177 debugger_safe_to_return && 1178 kernel_debugger_entry_count == 1 && 1179 !debugger_is_panic) { 1180 return; 1181 } 1182 } 1183 1184 #if defined(__arm__) || defined(__arm64__) 1185 if (PE_i_can_has_debugger(NULL) && panicDebugging) { 1186 /* If panic debugging is configured and we're on a dev fused device, spin for astris to connect */ 1187 panic_spin_shmcon(); 1188 } 1189 #endif /* defined(__arm__) || defined(__arm64__) */ 1190 1191 #else /* CONFIG_KDP_INTERACTIVE_DEBUGGING */ 1192 1193 PEHaltRestart(kPEPanicDiagnosticsDone); 1194 1195 #endif /* CONFIG_KDP_INTERACTIVE_DEBUGGING */ 1196 1197 if (!panicDebugging) { 1198 kdp_machine_reboot_type(kPEPanicRestartCPU, debugger_panic_options); 1199 } 1200 1201 panic_spin_forever(); 1202 } 1203 1204 #if INTERRUPT_MASKED_DEBUG 1205 uint64_t debugger_trap_timestamps[9]; 1206 # define DEBUGGER_TRAP_TIMESTAMP(i) debugger_trap_timestamps[i] = mach_absolute_time(); 1207 #else 1208 # define DEBUGGER_TRAP_TIMESTAMP(i) 1209 #endif 1210 1211 void 1212 handle_debugger_trap(unsigned int exception, unsigned int code, unsigned int subcode, void *state) 1213 { 1214 unsigned int initial_not_in_kdp = not_in_kdp; 1215 kern_return_t ret; 1216 debugger_op db_prev_op = debugger_current_op; 1217 1218 DEBUGGER_TRAP_TIMESTAMP(0); 1219 1220 DebuggerLock(); 1221 ret = DebuggerHaltOtherCores(CPUDEBUGGERSYNC); 1222 1223 DEBUGGER_TRAP_TIMESTAMP(1); 1224 1225 #if INTERRUPT_MASKED_DEBUG 1226 if (serialmode & SERIALMODE_OUTPUT) { 1227 ml_spin_debug_reset(current_thread()); 1228 } 1229 #endif 1230 if (ret != KERN_SUCCESS) { 1231 CPUDEBUGGERRET = ret; 1232 DebuggerUnlock(); 1233 return; 1234 } 1235 1236 /* Update the global panic/debugger nested entry level */ 1237 kernel_debugger_entry_count = CPUDEBUGGERCOUNT; 1238 if (kernel_debugger_entry_count > 0) { 1239 console_suspend(); 1240 } 1241 1242 /* 1243 * TODO: Should we do anything special for nested panics here? i.e. if we've trapped more than twice 1244 * should we call into the debugger if it's configured and then reboot if the panic log has been written? 1245 */ 1246 1247 if (CPUDEBUGGEROP == DBOP_NONE) { 1248 /* If there was no debugger context setup, we trapped due to a software breakpoint */ 1249 debugger_current_op = DBOP_BREAKPOINT; 1250 } else { 1251 /* Not safe to return from a nested panic/debugger call */ 1252 if (debugger_current_op == DBOP_PANIC || 1253 debugger_current_op == DBOP_DEBUGGER) { 1254 debugger_safe_to_return = FALSE; 1255 } 1256 1257 debugger_current_op = CPUDEBUGGEROP; 1258 1259 /* Only overwrite the panic message if there is none already - save the data from the first call */ 1260 if (debugger_panic_str == NULL) { 1261 debugger_panic_str = CPUPANICSTR; 1262 debugger_panic_args = CPUPANICARGS; 1263 debugger_panic_data = CPUPANICDATAPTR; 1264 debugger_message = CPUDEBUGGERMSG; 1265 debugger_panic_caller = CPUPANICCALLER; 1266 } 1267 1268 debugger_panic_options = CPUPANICOPTS; 1269 } 1270 1271 /* 1272 * Clear the op from the processor debugger context so we can handle 1273 * breakpoints in the debugger 1274 */ 1275 CPUDEBUGGEROP = DBOP_NONE; 1276 1277 DEBUGGER_TRAP_TIMESTAMP(2); 1278 1279 kdp_callouts(KDP_EVENT_ENTER); 1280 not_in_kdp = 0; 1281 1282 DEBUGGER_TRAP_TIMESTAMP(3); 1283 1284 if (debugger_current_op == DBOP_BREAKPOINT) { 1285 kdp_raise_exception(exception, code, subcode, state); 1286 } else if (debugger_current_op == DBOP_STACKSHOT) { 1287 CPUDEBUGGERRET = do_stackshot(); 1288 #if PGO 1289 } else if (debugger_current_op == DBOP_RESET_PGO_COUNTERS) { 1290 CPUDEBUGGERRET = do_pgo_reset_counters(); 1291 #endif 1292 } else { 1293 debugger_collect_diagnostics(exception, code, subcode, state); 1294 } 1295 1296 DEBUGGER_TRAP_TIMESTAMP(4); 1297 1298 not_in_kdp = initial_not_in_kdp; 1299 kdp_callouts(KDP_EVENT_EXIT); 1300 1301 DEBUGGER_TRAP_TIMESTAMP(5); 1302 1303 if (debugger_current_op != DBOP_BREAKPOINT) { 1304 debugger_panic_str = NULL; 1305 debugger_panic_args = NULL; 1306 debugger_panic_data = NULL; 1307 debugger_panic_options = 0; 1308 debugger_message = NULL; 1309 } 1310 1311 /* Restore the previous debugger state */ 1312 debugger_current_op = db_prev_op; 1313 1314 DEBUGGER_TRAP_TIMESTAMP(6); 1315 1316 DebuggerResumeOtherCores(); 1317 1318 DEBUGGER_TRAP_TIMESTAMP(7); 1319 1320 DebuggerUnlock(); 1321 1322 DEBUGGER_TRAP_TIMESTAMP(8); 1323 1324 return; 1325 } 1326 1327 __attribute__((noinline, not_tail_called)) 1328 void 1329 log(__unused int level, char *fmt, ...) 1330 { 1331 void *caller = __builtin_return_address(0); 1332 va_list listp; 1333 va_list listp2; 1334 1335 1336 #ifdef lint 1337 level++; 1338 #endif /* lint */ 1339 #ifdef MACH_BSD 1340 va_start(listp, fmt); 1341 va_copy(listp2, listp); 1342 1343 disable_preemption(); 1344 _doprnt(fmt, &listp, cons_putc_locked, 0); 1345 enable_preemption(); 1346 1347 va_end(listp); 1348 1349 os_log_with_args(OS_LOG_DEFAULT, OS_LOG_TYPE_DEFAULT, fmt, listp2, caller); 1350 va_end(listp2); 1351 #endif 1352 } 1353 1354 /* 1355 * Per <rdar://problem/24974766>, skip appending log messages to 1356 * the new logging infrastructure in contexts where safety is 1357 * uncertain. These contexts include: 1358 * - When we're in the debugger 1359 * - We're in a panic 1360 * - Interrupts are disabled 1361 * - Or Pre-emption is disabled 1362 * In all the above cases, it is potentially unsafe to log messages. 1363 */ 1364 1365 boolean_t 1366 oslog_is_safe(void) 1367 { 1368 return kernel_debugger_entry_count == 0 && 1369 not_in_kdp == 1 && 1370 get_preemption_level() == 0 && 1371 ml_get_interrupts_enabled() == TRUE; 1372 } 1373 1374 boolean_t 1375 debug_mode_active(void) 1376 { 1377 return (0 != kernel_debugger_entry_count != 0) || (0 == not_in_kdp); 1378 } 1379 1380 void 1381 debug_putc(char c) 1382 { 1383 if ((debug_buf_size != 0) && 1384 ((debug_buf_ptr - debug_buf_base) < (int)debug_buf_size)) { 1385 *debug_buf_ptr = c; 1386 debug_buf_ptr++; 1387 } 1388 } 1389 1390 #if defined (__x86_64__) 1391 struct pasc { 1392 unsigned a: 7; 1393 unsigned b: 7; 1394 unsigned c: 7; 1395 unsigned d: 7; 1396 unsigned e: 7; 1397 unsigned f: 7; 1398 unsigned g: 7; 1399 unsigned h: 7; 1400 } __attribute__((packed)); 1401 1402 typedef struct pasc pasc_t; 1403 1404 /* 1405 * In-place packing routines -- inefficient, but they're called at most once. 1406 * Assumes "buflen" is a multiple of 8. Used for compressing paniclogs on x86. 1407 */ 1408 int 1409 packA(char *inbuf, uint32_t length, uint32_t buflen) 1410 { 1411 unsigned int i, j = 0; 1412 pasc_t pack; 1413 1414 length = MIN(((length + 7) & ~7), buflen); 1415 1416 for (i = 0; i < length; i += 8) { 1417 pack.a = inbuf[i]; 1418 pack.b = inbuf[i + 1]; 1419 pack.c = inbuf[i + 2]; 1420 pack.d = inbuf[i + 3]; 1421 pack.e = inbuf[i + 4]; 1422 pack.f = inbuf[i + 5]; 1423 pack.g = inbuf[i + 6]; 1424 pack.h = inbuf[i + 7]; 1425 bcopy((char *) &pack, inbuf + j, 7); 1426 j += 7; 1427 } 1428 return j; 1429 } 1430 1431 void 1432 unpackA(char *inbuf, uint32_t length) 1433 { 1434 pasc_t packs; 1435 unsigned i = 0; 1436 length = (length * 8) / 7; 1437 1438 while (i < length) { 1439 packs = *(pasc_t *)&inbuf[i]; 1440 bcopy(&inbuf[i + 7], &inbuf[i + 8], MAX(0, (int) (length - i - 8))); 1441 inbuf[i++] = packs.a; 1442 inbuf[i++] = packs.b; 1443 inbuf[i++] = packs.c; 1444 inbuf[i++] = packs.d; 1445 inbuf[i++] = packs.e; 1446 inbuf[i++] = packs.f; 1447 inbuf[i++] = packs.g; 1448 inbuf[i++] = packs.h; 1449 } 1450 } 1451 #endif /* defined (__x86_64__) */ 1452 1453 extern char *proc_name_address(void *); 1454 extern char *proc_longname_address(void *); 1455 1456 __private_extern__ void 1457 panic_display_process_name(void) 1458 { 1459 proc_name_t proc_name = {}; 1460 task_t ctask = 0; 1461 void *cbsd_info = 0; 1462 vm_size_t size; 1463 1464 size = ml_nofault_copy((vm_offset_t)¤t_thread()->task, 1465 (vm_offset_t)&ctask, sizeof(task_t)); 1466 if (size != sizeof(task_t)) { 1467 goto out; 1468 } 1469 1470 size = ml_nofault_copy((vm_offset_t)&ctask->bsd_info, 1471 (vm_offset_t)&cbsd_info, sizeof(cbsd_info)); 1472 if (size != sizeof(cbsd_info)) { 1473 goto out; 1474 } 1475 1476 if (cbsd_info == NULL) { 1477 goto out; 1478 } 1479 1480 size = ml_nofault_copy((vm_offset_t)proc_longname_address(cbsd_info), 1481 (vm_offset_t)&proc_name, sizeof(proc_name)); 1482 1483 if (size == 0 || proc_name[0] == '\0') { 1484 size = ml_nofault_copy((vm_offset_t)proc_name_address(cbsd_info), 1485 (vm_offset_t)&proc_name, 1486 MIN(sizeof(command_t), sizeof(proc_name))); 1487 if (size > 0) { 1488 proc_name[size - 1] = '\0'; 1489 } 1490 } 1491 1492 out: 1493 proc_name[sizeof(proc_name) - 1] = '\0'; 1494 paniclog_append_noflush("\nProcess name corresponding to current thread: %s\n", 1495 proc_name[0] != '\0' ? proc_name : "Unknown"); 1496 } 1497 1498 unsigned 1499 panic_active(void) 1500 { 1501 return debugger_panic_str != (char *) 0; 1502 } 1503 1504 void 1505 populate_model_name(char *model_string) 1506 { 1507 strlcpy(model_name, model_string, sizeof(model_name)); 1508 } 1509 1510 void 1511 panic_display_model_name(void) 1512 { 1513 char tmp_model_name[sizeof(model_name)]; 1514 1515 if (ml_nofault_copy((vm_offset_t) &model_name, (vm_offset_t) &tmp_model_name, sizeof(model_name)) != sizeof(model_name)) { 1516 return; 1517 } 1518 1519 tmp_model_name[sizeof(tmp_model_name) - 1] = '\0'; 1520 1521 if (tmp_model_name[0] != 0) { 1522 paniclog_append_noflush("System model name: %s\n", tmp_model_name); 1523 } 1524 } 1525 1526 void 1527 panic_display_kernel_uuid(void) 1528 { 1529 char tmp_kernel_uuid[sizeof(kernel_uuid_string)]; 1530 1531 if (ml_nofault_copy((vm_offset_t) &kernel_uuid_string, (vm_offset_t) &tmp_kernel_uuid, sizeof(kernel_uuid_string)) != sizeof(kernel_uuid_string)) { 1532 return; 1533 } 1534 1535 if (tmp_kernel_uuid[0] != '\0') { 1536 paniclog_append_noflush("Kernel UUID: %s\n", tmp_kernel_uuid); 1537 } 1538 } 1539 1540 void 1541 panic_display_kernel_aslr(void) 1542 { 1543 kc_format_t kc_format; 1544 1545 PE_get_primary_kc_format(&kc_format); 1546 1547 if (kc_format == KCFormatFileset) { 1548 void *kch = PE_get_kc_header(KCKindPrimary); 1549 1550 paniclog_append_noflush("KernelCache slide: 0x%016lx\n", (unsigned long) vm_kernel_slide); 1551 paniclog_append_noflush("KernelCache base: %p\n", (void*) kch); 1552 paniclog_append_noflush("Kernel slide: 0x%016lx\n", vm_kernel_stext - (unsigned long)kch + vm_kernel_slide); 1553 } else if (vm_kernel_slide) { 1554 paniclog_append_noflush("Kernel slide: 0x%016lx\n", (unsigned long) vm_kernel_slide); 1555 } 1556 paniclog_append_noflush("Kernel text base: %p\n", (void *) vm_kernel_stext); 1557 #if defined(__arm64__) 1558 if (kc_format == KCFormatFileset) { 1559 extern vm_offset_t segTEXTEXECB; 1560 paniclog_append_noflush("Kernel text exec base: 0x%016lx\n", (unsigned long)segTEXTEXECB); 1561 } 1562 #endif 1563 } 1564 1565 void 1566 panic_display_hibb(void) 1567 { 1568 #if defined(__i386__) || defined (__x86_64__) 1569 paniclog_append_noflush("__HIB text base: %p\n", (void *) vm_hib_base); 1570 #endif 1571 } 1572 1573 extern unsigned int stack_total; 1574 extern unsigned long long stack_allocs; 1575 1576 #if defined (__x86_64__) 1577 extern unsigned int inuse_ptepages_count; 1578 extern long long alloc_ptepages_count; 1579 #endif 1580 1581 __private_extern__ void 1582 panic_display_zprint(void) 1583 { 1584 if (panic_include_zprint == TRUE) { 1585 struct zone zone_copy; 1586 1587 paniclog_append_noflush("%-20s %10s %10s\n", "Zone Name", "Cur Size", "Free Size"); 1588 zone_index_foreach(i) { 1589 if (ml_nofault_copy((vm_offset_t)&zone_array[i], 1590 (vm_offset_t)&zone_copy, sizeof(struct zone)) == sizeof(struct zone)) { 1591 if (zone_copy.z_wired_cur > atop(1024 * 1024)) { 1592 paniclog_append_noflush("%-8s%-20s %10llu %10lu\n", 1593 zone_heap_name(&zone_copy), 1594 zone_copy.z_name, (uint64_t)zone_size_wired(&zone_copy), 1595 (uintptr_t)zone_size_free(&zone_copy)); 1596 } 1597 } 1598 } 1599 1600 paniclog_append_noflush("%-20s %10lu\n", "Kernel Stacks", 1601 (uintptr_t)(kernel_stack_size * stack_total)); 1602 #if defined (__x86_64__) 1603 paniclog_append_noflush("%-20s %10lu\n", "PageTables", 1604 (uintptr_t)ptoa(inuse_ptepages_count)); 1605 #endif 1606 paniclog_append_noflush("%-20s %10lu\n", "Kalloc.Large", 1607 (uintptr_t)kalloc_large_total); 1608 1609 if (panic_kext_memory_info) { 1610 mach_memory_info_t *mem_info = panic_kext_memory_info; 1611 paniclog_append_noflush("\n%-5s %10s\n", "Kmod", "Size"); 1612 for (uint32_t i = 0; i < (panic_kext_memory_size / sizeof(mach_zone_info_t)); i++) { 1613 if (((mem_info[i].flags & VM_KERN_SITE_TYPE) == VM_KERN_SITE_KMOD) && 1614 (mem_info[i].size > (1024 * 1024))) { 1615 paniclog_append_noflush("%-5lld %10lld\n", mem_info[i].site, mem_info[i].size); 1616 } 1617 } 1618 } 1619 } 1620 } 1621 1622 #if CONFIG_ECC_LOGGING 1623 __private_extern__ void 1624 panic_display_ecc_errors(void) 1625 { 1626 uint32_t count = ecc_log_get_correction_count(); 1627 1628 if (count > 0) { 1629 paniclog_append_noflush("ECC Corrections:%u\n", count); 1630 } 1631 } 1632 #endif /* CONFIG_ECC_LOGGING */ 1633 1634 #if CONFIG_ZLEAKS 1635 void panic_print_symbol_name(vm_address_t search); 1636 1637 /* 1638 * Prints the backtrace most suspected of being a leaker, if we paniced in the zone allocator. 1639 * top_ztrace and panic_include_ztrace comes from osfmk/kern/zalloc.c 1640 */ 1641 __private_extern__ void 1642 panic_display_ztrace(void) 1643 { 1644 if (panic_include_ztrace == TRUE) { 1645 unsigned int i = 0; 1646 boolean_t keepsyms = FALSE; 1647 1648 PE_parse_boot_argn("keepsyms", &keepsyms, sizeof(keepsyms)); 1649 struct ztrace top_ztrace_copy; 1650 1651 /* Make sure not to trip another panic if there's something wrong with memory */ 1652 if (ml_nofault_copy((vm_offset_t)top_ztrace, (vm_offset_t)&top_ztrace_copy, sizeof(struct ztrace)) == sizeof(struct ztrace)) { 1653 paniclog_append_noflush("\nBacktrace suspected of leaking: (outstanding bytes: %lu)\n", (uintptr_t)top_ztrace_copy.zt_size); 1654 /* Print the backtrace addresses */ 1655 for (i = 0; (i < top_ztrace_copy.zt_depth && i < MAX_ZTRACE_DEPTH); i++) { 1656 paniclog_append_noflush("%p ", top_ztrace_copy.zt_stack[i]); 1657 if (keepsyms) { 1658 panic_print_symbol_name((vm_address_t)top_ztrace_copy.zt_stack[i]); 1659 } 1660 paniclog_append_noflush("\n"); 1661 } 1662 /* Print any kexts in that backtrace, along with their link addresses so we can properly blame them */ 1663 kmod_panic_dump((vm_offset_t *)&top_ztrace_copy.zt_stack[0], top_ztrace_copy.zt_depth); 1664 } else { 1665 paniclog_append_noflush("\nCan't access top_ztrace...\n"); 1666 } 1667 paniclog_append_noflush("\n"); 1668 } 1669 } 1670 #endif /* CONFIG_ZLEAKS */ 1671 1672 #if !CONFIG_TELEMETRY 1673 int 1674 telemetry_gather(user_addr_t buffer __unused, uint32_t *length __unused, boolean_t mark __unused) 1675 { 1676 return KERN_NOT_SUPPORTED; 1677 } 1678 #endif 1679 1680 #include <machine/machine_cpu.h> 1681 1682 uint32_t kern_feature_overrides = 0; 1683 1684 boolean_t 1685 kern_feature_override(uint32_t fmask) 1686 { 1687 if (kern_feature_overrides == 0) { 1688 uint32_t fdisables = 0; 1689 /* 1690 * Expected to be first invoked early, in a single-threaded 1691 * environment 1692 */ 1693 if (PE_parse_boot_argn("validation_disables", &fdisables, sizeof(fdisables))) { 1694 fdisables |= KF_INITIALIZED; 1695 kern_feature_overrides = fdisables; 1696 } else { 1697 kern_feature_overrides |= KF_INITIALIZED; 1698 } 1699 } 1700 return (kern_feature_overrides & fmask) == fmask; 1701 } 1702 1703 boolean_t 1704 on_device_corefile_enabled(void) 1705 { 1706 assert(startup_phase >= STARTUP_SUB_TUNABLES); 1707 #if CONFIG_KDP_INTERACTIVE_DEBUGGING 1708 if (debug_boot_arg == 0) { 1709 return FALSE; 1710 } 1711 if (debug_boot_arg & DB_DISABLE_LOCAL_CORE) { 1712 return FALSE; 1713 } 1714 #if !XNU_TARGET_OS_OSX 1715 /* 1716 * outside of macOS, if there's a debug boot-arg set and local 1717 * cores aren't explicitly disabled, we always write a corefile. 1718 */ 1719 return TRUE; 1720 #else /* !XNU_TARGET_OS_OSX */ 1721 /* 1722 * on macOS, if corefiles on panic are requested and local cores 1723 * aren't disabled we write a local core. 1724 */ 1725 if (debug_boot_arg & (DB_KERN_DUMP_ON_NMI | DB_KERN_DUMP_ON_PANIC)) { 1726 return TRUE; 1727 } 1728 #endif /* !XNU_TARGET_OS_OSX */ 1729 #endif /* CONFIG_KDP_INTERACTIVE_DEBUGGING */ 1730 return FALSE; 1731 } 1732 1733 boolean_t 1734 panic_stackshot_to_disk_enabled(void) 1735 { 1736 assert(startup_phase >= STARTUP_SUB_TUNABLES); 1737 #if defined(__x86_64__) 1738 if (PEGetCoprocessorVersion() < kCoprocessorVersion2) { 1739 /* Only enabled on pre-Gibraltar machines where it hasn't been disabled explicitly */ 1740 if ((debug_boot_arg != 0) && (debug_boot_arg & DB_DISABLE_STACKSHOT_TO_DISK)) { 1741 return FALSE; 1742 } 1743 1744 return TRUE; 1745 } 1746 #endif 1747 return FALSE; 1748 } 1749 1750 #if DEBUG || DEVELOPMENT 1751 const char * 1752 sysctl_debug_get_preoslog(size_t *size) 1753 { 1754 int result = 0; 1755 void *preoslog_pa = NULL; 1756 int preoslog_size = 0; 1757 1758 result = IODTGetLoaderInfo("preoslog", &preoslog_pa, &preoslog_size); 1759 if (result || preoslog_pa == NULL || preoslog_size == 0) { 1760 kprintf("Couldn't obtain preoslog region: result = %d, preoslog_pa = %p, preoslog_size = %d\n", result, preoslog_pa, preoslog_size); 1761 *size = 0; 1762 return NULL; 1763 } 1764 1765 /* 1766 * Beware: 1767 * On release builds, we would need to call IODTFreeLoaderInfo("preoslog", preoslog_pa, preoslog_size) to free the preoslog buffer. 1768 * On Development & Debug builds, we retain the buffer so it can be extracted from coredumps. 1769 */ 1770 *size = preoslog_size; 1771 return (char *)(ml_static_ptovirt((vm_offset_t)(preoslog_pa))); 1772 } 1773 #endif /* DEBUG || DEVELOPMENT */