]> git.saurik.com Git - apple/xnu.git/blame - bsd/kern/kdebug.c
xnu-6153.141.1.tar.gz
[apple/xnu.git] / bsd / kern / kdebug.c
CommitLineData
1c79356b 1/*
cb323159 2 * Copyright (c) 2000-2019 Apple Inc. All rights reserved.
1c79356b 3 *
91447636 4 * @Apple_LICENSE_HEADER_START@
39037602 5 *
e5568f75
A
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
39037602 11 *
e5568f75
A
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1c79356b
A
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
e5568f75
A
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
39037602 19 *
2d21ac55 20 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b
A
21 */
22
91447636
A
23#include <sys/errno.h>
24#include <sys/param.h>
0c530ab8 25#include <sys/systm.h>
91447636
A
26#include <sys/proc_internal.h>
27#include <sys/vm.h>
28#include <sys/sysctl.h>
29#include <sys/kdebug.h>
39037602
A
30#include <sys/kauth.h>
31#include <sys/ktrace.h>
91447636 32#include <sys/sysproto.h>
6d2010ae 33#include <sys/bsdtask_info.h>
fe8ab488 34#include <sys/random.h>
91447636 35
1c79356b
A
36#include <mach/clock_types.h>
37#include <mach/mach_types.h>
55e303ae 38#include <mach/mach_time.h>
39037602 39#include <mach/mach_vm.h>
cb323159 40#include <machine/atomic.h>
1c79356b
A
41#include <machine/machine_routines.h>
42
39037602
A
43#include <mach/machine.h>
44#include <mach/vm_map.h>
45
b0d623f7 46#if defined(__i386__) || defined(__x86_64__)
6d2010ae
A
47#include <i386/rtclock_protos.h>
48#include <i386/mp.h>
49#include <i386/machine_routines.h>
5ba3f43e 50#include <i386/tsc.h>
b0d623f7 51#endif
6d2010ae
A
52
53#include <kern/clock.h>
54
1c79356b
A
55#include <kern/thread.h>
56#include <kern/task.h>
2d21ac55 57#include <kern/debug.h>
6d2010ae
A
58#include <kern/kalloc.h>
59#include <kern/cpu_data.h>
d41d1dae 60#include <kern/assert.h>
39236c6e 61#include <kern/telemetry.h>
3e170ce0 62#include <kern/sched_prim.h>
1c79356b
A
63#include <vm/vm_kern.h>
64#include <sys/lock.h>
39037602
A
65#include <kperf/kperf.h>
66#include <pexpert/device_tree.h>
1c79356b 67
0c530ab8 68#include <sys/malloc.h>
b0d623f7 69#include <sys/mcache.h>
0c530ab8 70
b0d623f7
A
71#include <sys/vnode.h>
72#include <sys/vnode_internal.h>
73#include <sys/fcntl.h>
6d2010ae
A
74#include <sys/file_internal.h>
75#include <sys/ubc.h>
0a7de745 76#include <sys/param.h> /* for isset() */
b0d623f7 77
0a7de745 78#include <mach/mach_host.h> /* for host_info() */
0c530ab8
A
79#include <libkern/OSAtomic.h>
80
6d2010ae 81#include <machine/pal_routines.h>
39037602 82#include <machine/atomic.h>
04b8595b 83
39236c6e
A
84/*
85 * IOP(s)
86 *
39236c6e
A
87 * IOP(s) are auxiliary cores that want to participate in kdebug event logging.
88 * They are registered dynamically. Each is assigned a cpu_id at registration.
89 *
90 * NOTE: IOP trace events may not use the same clock hardware as "normal"
91 * cpus. There is an effort made to synchronize the IOP timebase with the
92 * AP, but it should be understood that there may be discrepancies.
93 *
94 * Once registered, an IOP is permanent, it cannot be unloaded/unregistered.
95 * The current implementation depends on this for thread safety.
96 *
97 * New registrations occur by allocating an kd_iop struct and assigning
98 * a provisional cpu_id of list_head->cpu_id + 1. Then a CAS to claim the
99 * list_head pointer resolves any races.
100 *
101 * You may safely walk the kd_iops list at any time, without holding locks.
102 *
103 * When allocating buffers, the current kd_iops head is captured. Any operations
104 * that depend on the buffer state (such as flushing IOP traces on reads,
105 * etc.) should use the captured list head. This will allow registrations to
106 * take place while trace is in use.
107 */
108
109typedef struct kd_iop {
0a7de745
A
110 kd_callback_t callback;
111 uint32_t cpu_id;
112 uint64_t last_timestamp; /* Prevent timer rollback */
113 struct kd_iop* next;
39236c6e
A
114} kd_iop_t;
115
116static kd_iop_t* kd_iops = NULL;
117
39037602
A
118/*
119 * Typefilter(s)
120 *
121 * A typefilter is a 8KB bitmap that is used to selectively filter events
122 * being recorded. It is able to individually address every class & subclass.
123 *
124 * There is a shared typefilter in the kernel which is lazily allocated. Once
125 * allocated, the shared typefilter is never deallocated. The shared typefilter
126 * is also mapped on demand into userspace processes that invoke kdebug_trace
127 * API from Libsyscall. When mapped into a userspace process, the memory is
128 * read only, and does not have a fixed address.
129 *
130 * It is a requirement that the kernel's shared typefilter always pass DBG_TRACE
131 * events. This is enforced automatically, by having the needed bits set any
132 * time the shared typefilter is mutated.
133 */
134
135typedef uint8_t* typefilter_t;
136
137static typefilter_t kdbg_typefilter;
138static mach_port_t kdbg_typefilter_memory_entry;
139
140/*
141 * There are 3 combinations of page sizes:
142 *
143 * 4KB / 4KB
144 * 4KB / 16KB
145 * 16KB / 16KB
146 *
147 * The typefilter is exactly 8KB. In the first two scenarios, we would like
148 * to use 2 pages exactly; in the third scenario we must make certain that
149 * a full page is allocated so we do not inadvertantly share 8KB of random
150 * data to userspace. The round_page_32 macro rounds to kernel page size.
151 */
152#define TYPEFILTER_ALLOC_SIZE MAX(round_page_32(KDBG_TYPEFILTER_BITMAP_SIZE), KDBG_TYPEFILTER_BITMAP_SIZE)
153
0a7de745
A
154static typefilter_t
155typefilter_create(void)
39037602
A
156{
157 typefilter_t tf;
158 if (KERN_SUCCESS == kmem_alloc(kernel_map, (vm_offset_t*)&tf, TYPEFILTER_ALLOC_SIZE, VM_KERN_MEMORY_DIAG)) {
159 memset(&tf[KDBG_TYPEFILTER_BITMAP_SIZE], 0, TYPEFILTER_ALLOC_SIZE - KDBG_TYPEFILTER_BITMAP_SIZE);
160 return tf;
161 }
162 return NULL;
163}
164
0a7de745
A
165static void
166typefilter_deallocate(typefilter_t tf)
39037602 167{
5ba3f43e 168 assert(tf != NULL);
39037602
A
169 assert(tf != kdbg_typefilter);
170 kmem_free(kernel_map, (vm_offset_t)tf, TYPEFILTER_ALLOC_SIZE);
171}
172
0a7de745
A
173static void
174typefilter_copy(typefilter_t dst, typefilter_t src)
39037602 175{
5ba3f43e
A
176 assert(src != NULL);
177 assert(dst != NULL);
39037602
A
178 memcpy(dst, src, KDBG_TYPEFILTER_BITMAP_SIZE);
179}
180
0a7de745
A
181static void
182typefilter_reject_all(typefilter_t tf)
39037602 183{
5ba3f43e 184 assert(tf != NULL);
39037602
A
185 memset(tf, 0, KDBG_TYPEFILTER_BITMAP_SIZE);
186}
187
0a7de745
A
188static void
189typefilter_allow_all(typefilter_t tf)
d9a64523
A
190{
191 assert(tf != NULL);
192 memset(tf, ~0, KDBG_TYPEFILTER_BITMAP_SIZE);
193}
194
0a7de745
A
195static void
196typefilter_allow_class(typefilter_t tf, uint8_t class)
39037602 197{
5ba3f43e 198 assert(tf != NULL);
39037602
A
199 const uint32_t BYTES_PER_CLASS = 256 / 8; // 256 subclasses, 1 bit each
200 memset(&tf[class * BYTES_PER_CLASS], 0xFF, BYTES_PER_CLASS);
201}
202
0a7de745
A
203static void
204typefilter_allow_csc(typefilter_t tf, uint16_t csc)
39037602 205{
5ba3f43e 206 assert(tf != NULL);
39037602
A
207 setbit(tf, csc);
208}
209
0a7de745
A
210static bool
211typefilter_is_debugid_allowed(typefilter_t tf, uint32_t id)
39037602 212{
5ba3f43e 213 assert(tf != NULL);
39037602
A
214 return isset(tf, KDBG_EXTRACT_CSC(id));
215}
216
0a7de745
A
217static mach_port_t
218typefilter_create_memory_entry(typefilter_t tf)
39037602 219{
5ba3f43e 220 assert(tf != NULL);
39037602
A
221
222 mach_port_t memory_entry = MACH_PORT_NULL;
223 memory_object_size_t size = TYPEFILTER_ALLOC_SIZE;
224
225 mach_make_memory_entry_64(kernel_map,
0a7de745
A
226 &size,
227 (memory_object_offset_t)tf,
228 VM_PROT_READ,
229 &memory_entry,
230 MACH_PORT_NULL);
39037602
A
231
232 return memory_entry;
233}
234
235static int kdbg_copyin_typefilter(user_addr_t addr, size_t size);
236static void kdbg_enable_typefilter(void);
237static void kdbg_disable_typefilter(void);
238
239/*
240 * External prototypes
241 */
242
0a7de745
A
243void task_act_iterate_wth_args(task_t, void (*)(thread_t, void *), void *);
244int cpu_number(void); /* XXX <machine/...> include path broken */
39037602
A
245void commpage_update_kdebug_state(void); /* XXX sign */
246
247extern int log_leaks;
5ba3f43e
A
248
249/*
250 * This flag is for testing purposes only -- it's highly experimental and tools
251 * have not been updated to support it.
252 */
253static bool kdbg_continuous_time = false;
254
255static inline uint64_t
256kdbg_timestamp(void)
257{
258 if (kdbg_continuous_time) {
259 return mach_continuous_time();
260 } else {
261 return mach_absolute_time();
262 }
263}
39037602 264
d9a64523
A
265static int kdbg_debug = 0;
266
39037602
A
267#if KDEBUG_MOJO_TRACE
268#include <sys/kdebugevents.h>
269static void kdebug_serial_print( /* forward */
0a7de745
A
270 uint32_t, uint32_t, uint64_t,
271 uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
39037602 272#endif
0c530ab8 273
0c530ab8 274int kdbg_control(int *, u_int, user_addr_t, size_t *);
39037602
A
275
276static int kdbg_read(user_addr_t, size_t *, vnode_t, vfs_context_t, uint32_t);
277static int kdbg_readcpumap(user_addr_t, size_t *);
278static int kdbg_readthrmap_v3(user_addr_t, size_t, int);
279static int kdbg_readcurthrmap(user_addr_t, size_t *);
280static int kdbg_setreg(kd_regtype *);
281static int kdbg_setpidex(kd_regtype *);
282static int kdbg_setpid(kd_regtype *);
283static void kdbg_thrmap_init(void);
cb323159
A
284static int kdbg_reinit(bool);
285static int kdbg_bootstrap(bool);
5ba3f43e 286static int kdbg_test(size_t flavor);
39037602 287
cb323159 288static int kdbg_write_v1_header(bool write_thread_map, vnode_t vp, vfs_context_t ctx);
39037602
A
289static int kdbg_write_thread_map(vnode_t vp, vfs_context_t ctx);
290static int kdbg_copyout_thread_map(user_addr_t buffer, size_t *buffer_size);
291static void kdbg_clear_thread_map(void);
292
cb323159 293static bool kdbg_wait(uint64_t timeout_ms, bool locked_wait);
39037602 294static void kdbg_wakeup(void);
0c530ab8 295
3e170ce0 296int kdbg_cpumap_init_internal(kd_iop_t* iops, uint32_t cpu_count,
0a7de745 297 uint8_t** cpumap, uint32_t* cpumap_size);
3e170ce0 298
39037602 299static kd_threadmap *kdbg_thrmap_init_internal(unsigned int count,
0a7de745
A
300 unsigned int *mapsize,
301 unsigned int *mapcount);
3e170ce0 302
cb323159 303static bool kdebug_current_proc_enabled(uint32_t debugid);
3e170ce0
A
304static errno_t kdebug_check_trace_string(uint32_t debugid, uint64_t str_id);
305
306int kdbg_write_v3_header(user_addr_t, size_t *, int);
307int kdbg_write_v3_chunk_header(user_addr_t buffer, uint32_t tag,
0a7de745
A
308 uint32_t sub_tag, uint64_t length,
309 vnode_t vp, vfs_context_t ctx);
3e170ce0
A
310
311user_addr_t kdbg_write_v3_event_chunk_header(user_addr_t buffer, uint32_t tag,
0a7de745
A
312 uint64_t length, vnode_t vp,
313 vfs_context_t ctx);
39236c6e 314
39037602 315// Helper functions
316670eb 316
cb323159 317static int create_buffers(bool);
0c530ab8
A
318static void delete_buffers(void);
319
39037602
A
320extern int tasks_count;
321extern int threads_count;
2d21ac55
A
322extern void IOSleep(int);
323
9bccf70c
A
324/* trace enable status */
325unsigned int kdebug_enable = 0;
326
fe8ab488 327/* A static buffer to record events prior to the start of regular logging */
5ba3f43e
A
328
329#define KD_EARLY_BUFFER_SIZE (16 * 1024)
330#define KD_EARLY_BUFFER_NBUFS (KD_EARLY_BUFFER_SIZE / sizeof(kd_buf))
331#if CONFIG_EMBEDDED
332/*
333 * On embedded, the space for this is carved out by osfmk/arm/data.s -- clang
334 * has problems aligning to greater than 4K.
335 */
336extern kd_buf kd_early_buffer[KD_EARLY_BUFFER_NBUFS];
337#else /* CONFIG_EMBEDDED */
338__attribute__((aligned(KD_EARLY_BUFFER_SIZE)))
339static kd_buf kd_early_buffer[KD_EARLY_BUFFER_NBUFS];
340#endif /* !CONFIG_EMBEDDED */
341
342static unsigned int kd_early_index = 0;
343static bool kd_early_overflow = false;
344static bool kd_early_done = false;
6d2010ae 345
39037602
A
346#define SLOW_NOLOG 0x01
347#define SLOW_CHECKS 0x02
91447636 348
0a7de745
A
349#define EVENTS_PER_STORAGE_UNIT 2048
350#define MIN_STORAGE_UNITS_PER_CPU 4
b0d623f7 351
6d2010ae
A
352#define POINTER_FROM_KDS_PTR(x) (&kd_bufs[x.buffer_index].kdsb_addr[x.offset])
353
6d2010ae
A
354union kds_ptr {
355 struct {
356 uint32_t buffer_index:21;
357 uint16_t offset:11;
358 };
359 uint32_t raw;
360};
361
b0d623f7 362struct kd_storage {
0a7de745 363 union kds_ptr kds_next;
6d2010ae
A
364 uint32_t kds_bufindx;
365 uint32_t kds_bufcnt;
366 uint32_t kds_readlast;
cb323159 367 bool kds_lostevents;
6d2010ae 368 uint64_t kds_timestamp;
0c530ab8 369
0a7de745 370 kd_buf kds_records[EVENTS_PER_STORAGE_UNIT];
0c530ab8
A
371};
372
5ba3f43e
A
373#define MAX_BUFFER_SIZE (1024 * 1024 * 128)
374#define N_STORAGE_UNITS_PER_BUFFER (MAX_BUFFER_SIZE / sizeof(struct kd_storage))
375static_assert(N_STORAGE_UNITS_PER_BUFFER <= 0x7ff,
0a7de745 376 "shoudn't overflow kds_ptr.offset");
b0d623f7 377
b0d623f7 378struct kd_storage_buffers {
0a7de745
A
379 struct kd_storage *kdsb_addr;
380 uint32_t kdsb_size;
b0d623f7
A
381};
382
6d2010ae 383#define KDS_PTR_NULL 0xffffffff
b0d623f7 384struct kd_storage_buffers *kd_bufs = NULL;
5ba3f43e
A
385int n_storage_units = 0;
386unsigned int n_storage_buffers = 0;
387int n_storage_threshold = 0;
388int kds_waiter = 0;
b0d623f7 389
6d2010ae 390#pragma pack(0)
b0d623f7 391struct kd_bufinfo {
6d2010ae
A
392 union kds_ptr kd_list_head;
393 union kds_ptr kd_list_tail;
cb323159 394 bool kd_lostevents;
6d2010ae
A
395 uint32_t _pad;
396 uint64_t kd_prev_timebase;
397 uint32_t num_bufs;
0a7de745 398} __attribute__((aligned(MAX_CPU_CACHE_LINE_SIZE)));
b0d623f7 399
3e170ce0
A
400
401/*
402 * In principle, this control block can be shared in DRAM with other
403 * coprocessors and runtimes, for configuring what tracing is enabled.
404 */
6d2010ae
A
405struct kd_ctrl_page_t {
406 union kds_ptr kds_free_list;
0a7de745
A
407 uint32_t enabled :1;
408 uint32_t _pad0 :31;
409 int kds_inuse_count;
6d2010ae
A
410 uint32_t kdebug_flags;
411 uint32_t kdebug_slowcheck;
39037602 412 uint64_t oldest_time;
39236c6e
A
413 /*
414 * The number of kd_bufinfo structs allocated may not match the current
415 * number of active cpus. We capture the iops list head at initialization
416 * which we could use to calculate the number of cpus we allocated data for,
417 * unless it happens to be null. To avoid that case, we explicitly also
418 * capture a cpu count.
419 */
420 kd_iop_t* kdebug_iops;
421 uint32_t kdebug_cpus;
39037602
A
422} kd_ctrl_page = {
423 .kds_free_list = {.raw = KDS_PTR_NULL},
424 .kdebug_slowcheck = SLOW_NOLOG,
425 .oldest_time = 0
426};
39236c6e 427
6d2010ae
A
428#pragma pack()
429
0c530ab8
A
430struct kd_bufinfo *kdbip = NULL;
431
0a7de745
A
432#define KDCOPYBUF_COUNT 8192
433#define KDCOPYBUF_SIZE (KDCOPYBUF_COUNT * sizeof(kd_buf))
3e170ce0 434
0a7de745
A
435#define PAGE_4KB 4096
436#define PAGE_16KB 16384
3e170ce0 437
0c530ab8
A
438kd_buf *kdcopybuf = NULL;
439
316670eb 440unsigned int nkdbufs = 0;
0a7de745
A
441unsigned int kdlog_beg = 0;
442unsigned int kdlog_end = 0;
443unsigned int kdlog_value1 = 0;
444unsigned int kdlog_value2 = 0;
445unsigned int kdlog_value3 = 0;
446unsigned int kdlog_value4 = 0;
1c79356b 447
6d2010ae 448static lck_spin_t * kdw_spin_lock;
b0d623f7 449static lck_spin_t * kds_spin_lock;
1c79356b
A
450
451kd_threadmap *kd_mapptr = 0;
452unsigned int kd_mapsize = 0;
453unsigned int kd_mapcount = 0;
b0d623f7 454
0a7de745
A
455off_t RAW_file_offset = 0;
456int RAW_file_written = 0;
6d2010ae 457
0a7de745 458#define RAW_FLUSH_SIZE (2 * 1024 * 1024)
6d2010ae 459
3e170ce0
A
460/*
461 * A globally increasing counter for identifying strings in trace. Starts at
462 * 1 because 0 is a reserved return value.
463 */
464__attribute__((aligned(MAX_CPU_CACHE_LINE_SIZE)))
465static uint64_t g_curr_str_id = 1;
6d2010ae 466
3e170ce0
A
467#define STR_ID_SIG_OFFSET (48)
468#define STR_ID_MASK ((1ULL << STR_ID_SIG_OFFSET) - 1)
469#define STR_ID_SIG_MASK (~STR_ID_MASK)
316670eb 470
3e170ce0
A
471/*
472 * A bit pattern for identifying string IDs generated by
473 * kdebug_trace_string(2).
474 */
475static uint64_t g_str_id_signature = (0x70acULL << STR_ID_SIG_OFFSET);
316670eb 476
0a7de745
A
477#define INTERRUPT 0x01050000
478#define MACH_vmfault 0x01300008
479#define BSC_SysCall 0x040c0000
480#define MACH_SysCall 0x010c0000
6d2010ae 481
9bccf70c 482/* task to string structure */
0a7de745
A
483struct tts {
484 task_t task; /* from procs task */
485 pid_t pid; /* from procs p_pid */
486 char task_comm[20];/* from procs p_comm */
9bccf70c
A
487};
488
489typedef struct tts tts_t;
490
0a7de745 491struct krt {
6d2010ae
A
492 kd_threadmap *map; /* pointer to the map buffer */
493 int count;
494 int maxcount;
495 struct tts *atts;
1c79356b
A
496};
497
cb323159
A
498/*
499 * TRACE file formats...
500 *
501 * RAW_VERSION0
502 *
503 * uint32_t #threadmaps
504 * kd_threadmap[]
505 * kd_buf[]
506 *
507 * RAW_VERSION1
508 *
509 * RAW_header, with version_no set to RAW_VERSION1
510 * kd_threadmap[]
511 * Empty space to pad alignment to the nearest page boundary.
512 * kd_buf[]
513 *
514 * RAW_VERSION1+
515 *
516 * RAW_header, with version_no set to RAW_VERSION1
517 * kd_threadmap[]
518 * kd_cpumap_header, with version_no set to RAW_VERSION1
519 * kd_cpumap[]
520 * Empty space to pad alignment to the nearest page boundary.
521 * kd_buf[]
522 *
523 * V1+ implementation details...
524 *
525 * It would have been nice to add the cpumap data "correctly", but there were
526 * several obstacles. Existing code attempts to parse both V1 and V0 files.
527 * Due to the fact that V0 has no versioning or header, the test looks like
528 * this:
529 *
530 * // Read header
531 * if (header.version_no != RAW_VERSION1) { // Assume V0 }
532 *
533 * If we add a VERSION2 file format, all existing code is going to treat that
534 * as a VERSION0 file when reading it, and crash terribly when trying to read
535 * RAW_VERSION2 threadmap entries.
536 *
537 * To differentiate between a V1 and V1+ file, read as V1 until you reach
538 * the padding bytes. Then:
539 *
540 * boolean_t is_v1plus = FALSE;
541 * if (padding_bytes >= sizeof(kd_cpumap_header)) {
542 * kd_cpumap_header header = // read header;
543 * if (header.version_no == RAW_VERSION1) {
544 * is_v1plus = TRUE;
545 * }
546 * }
547 *
548 */
549
550#define RAW_VERSION3 0x00001000
551
552// Version 3 header
553// The header chunk has the tag 0x00001000 which also serves as a magic word
554// that identifies the file as a version 3 trace file. The header payload is
555// a set of fixed fields followed by a variable number of sub-chunks:
556/*
557 * ____________________________________________________________________________
558 | Offset | Size | Field |
559 | ----------------------------------------------------------------------------
560 | 0 | 4 | Tag (0x00001000) |
561 | 4 | 4 | Sub-tag. Represents the version of the header. |
562 | 8 | 8 | Length of header payload (40+8x) |
563 | 16 | 8 | Time base info. Two 32-bit numbers, numer/denom, |
564 | | | for converting timestamps to nanoseconds. |
565 | 24 | 8 | Timestamp of trace start. |
566 | 32 | 8 | Wall time seconds since Unix epoch. |
567 | | | As returned by gettimeofday(). |
568 | 40 | 4 | Wall time microseconds. As returned by gettimeofday(). |
569 | 44 | 4 | Local time zone offset in minutes. ( " ) |
570 | 48 | 4 | Type of daylight savings time correction to apply. ( " ) |
571 | 52 | 4 | Flags. 1 = 64-bit. Remaining bits should be written |
572 | | | as 0 and ignored when reading. |
573 | 56 | 8x | Variable number of sub-chunks. None are required. |
574 | | | Ignore unknown chunks. |
575 | ----------------------------------------------------------------------------
576 */
577// NOTE: The header sub-chunks are considered part of the header chunk,
578// so they must be included in the header chunk’s length field.
579// The CPU map is an optional sub-chunk of the header chunk. It provides
580// information about the CPUs that are referenced from the trace events.
581typedef struct {
582 uint32_t tag;
583 uint32_t sub_tag;
584 uint64_t length;
585 uint32_t timebase_numer;
586 uint32_t timebase_denom;
587 uint64_t timestamp;
588 uint64_t walltime_secs;
589 uint32_t walltime_usecs;
590 uint32_t timezone_minuteswest;
591 uint32_t timezone_dst;
592 uint32_t flags;
593} __attribute__((packed)) kd_header_v3;
594
595typedef struct {
596 uint32_t tag;
597 uint32_t sub_tag;
598 uint64_t length;
599} __attribute__((packed)) kd_chunk_header_v3;
600
601#define V3_CONFIG 0x00001b00
602#define V3_CPU_MAP 0x00001c00
603#define V3_THREAD_MAP 0x00001d00
604#define V3_RAW_EVENTS 0x00001e00
605#define V3_NULL_CHUNK 0x00002000
606
607// The current version of all kernel managed chunks is 1. The
608// V3_CURRENT_CHUNK_VERSION is added to ease the simple case
609// when most/all the kernel managed chunks have the same version.
610
611#define V3_CURRENT_CHUNK_VERSION 1
612#define V3_HEADER_VERSION V3_CURRENT_CHUNK_VERSION
613#define V3_CPUMAP_VERSION V3_CURRENT_CHUNK_VERSION
614#define V3_THRMAP_VERSION V3_CURRENT_CHUNK_VERSION
615#define V3_EVENT_DATA_VERSION V3_CURRENT_CHUNK_VERSION
616
1c79356b
A
617typedef struct krt krt_t;
618
39236c6e 619static uint32_t
cb323159 620kdbg_cpu_count(bool early_trace)
39236c6e
A
621{
622 if (early_trace) {
5ba3f43e
A
623#if CONFIG_EMBEDDED
624 return ml_get_cpu_count();
625#else
39236c6e 626 return max_ncpus;
5ba3f43e 627#endif
39236c6e
A
628 }
629
630 host_basic_info_data_t hinfo;
631 mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
632 host_info((host_t)1 /* BSD_HOST */, HOST_BASIC_INFO, (host_info_t)&hinfo, &count);
633 assert(hinfo.logical_cpu_max > 0);
634 return hinfo.logical_cpu_max;
635}
636
637#if MACH_ASSERT
5ba3f43e 638#if CONFIG_EMBEDDED
cb323159 639static bool
5ba3f43e
A
640kdbg_iop_list_is_valid(kd_iop_t* iop)
641{
0a7de745
A
642 if (iop) {
643 /* Is list sorted by cpu_id? */
644 kd_iop_t* temp = iop;
645 do {
646 assert(!temp->next || temp->next->cpu_id == temp->cpu_id - 1);
cb323159 647 assert(temp->next || (temp->cpu_id == kdbg_cpu_count(false) || temp->cpu_id == kdbg_cpu_count(true)));
0a7de745
A
648 } while ((temp = temp->next));
649
650 /* Does each entry have a function and a name? */
651 temp = iop;
652 do {
653 assert(temp->callback.func);
654 assert(strlen(temp->callback.iop_name) < sizeof(temp->callback.iop_name));
655 } while ((temp = temp->next));
656 }
657
cb323159 658 return true;
5ba3f43e
A
659}
660
cb323159 661static bool
5ba3f43e
A
662kdbg_iop_list_contains_cpu_id(kd_iop_t* list, uint32_t cpu_id)
663{
664 while (list) {
0a7de745 665 if (list->cpu_id == cpu_id) {
cb323159 666 return true;
0a7de745 667 }
5ba3f43e
A
668 list = list->next;
669 }
670
cb323159 671 return false;
5ba3f43e
A
672}
673#endif /* CONFIG_EMBEDDED */
39236c6e
A
674#endif /* MACH_ASSERT */
675
676static void
677kdbg_iop_list_callback(kd_iop_t* iop, kd_callback_type type, void* arg)
678{
679 while (iop) {
680 iop->callback.func(iop->callback.context, type, arg);
681 iop = iop->next;
682 }
683}
684
cb323159 685static lck_grp_t *kdebug_lck_grp = NULL;
0a7de745 686
6d2010ae 687static void
cb323159 688kdbg_set_tracing_enabled(bool enabled, uint32_t trace_type)
1c79356b 689{
cb323159
A
690 /*
691 * Drain any events from IOPs before making the state change. On
692 * enabling, this removes any stale events from before tracing. On
693 * disabling, this saves any events up to the point tracing is disabled.
694 */
695 kdbg_iop_list_callback(kd_ctrl_page.kdebug_iops, KD_CALLBACK_SYNC_FLUSH,
696 NULL);
697
698 int s = ml_set_interrupts_enabled(false);
0a7de745 699 lck_spin_lock_grp(kds_spin_lock, kdebug_lck_grp);
cb323159 700
6d2010ae 701 if (enabled) {
5ba3f43e 702 /*
cb323159 703 * The oldest valid time is now; reject past events from IOPs.
5ba3f43e
A
704 */
705 kd_ctrl_page.oldest_time = kdbg_timestamp();
316670eb 706 kdebug_enable |= trace_type;
6d2010ae
A
707 kd_ctrl_page.kdebug_slowcheck &= ~SLOW_NOLOG;
708 kd_ctrl_page.enabled = 1;
39037602 709 commpage_update_kdebug_state();
6d2010ae 710 } else {
0a7de745 711 kdebug_enable &= ~(KDEBUG_ENABLE_TRACE | KDEBUG_ENABLE_PPT);
6d2010ae
A
712 kd_ctrl_page.kdebug_slowcheck |= SLOW_NOLOG;
713 kd_ctrl_page.enabled = 0;
39037602 714 commpage_update_kdebug_state();
6d2010ae
A
715 }
716 lck_spin_unlock(kds_spin_lock);
717 ml_set_interrupts_enabled(s);
39236c6e
A
718
719 if (enabled) {
cb323159
A
720 kdbg_iop_list_callback(kd_ctrl_page.kdebug_iops,
721 KD_CALLBACK_KDEBUG_ENABLED, NULL);
39236c6e 722 } else {
cb323159
A
723 kdbg_iop_list_callback(kd_ctrl_page.kdebug_iops,
724 KD_CALLBACK_KDEBUG_DISABLED, NULL);
39236c6e 725 }
1c79356b
A
726}
727
6d2010ae 728static void
cb323159 729kdbg_set_flags(int slowflag, int enableflag, bool enabled)
6d2010ae 730{
cb323159 731 int s = ml_set_interrupts_enabled(false);
0a7de745 732 lck_spin_lock_grp(kds_spin_lock, kdebug_lck_grp);
6d2010ae
A
733
734 if (enabled) {
735 kd_ctrl_page.kdebug_slowcheck |= slowflag;
736 kdebug_enable |= enableflag;
737 } else {
738 kd_ctrl_page.kdebug_slowcheck &= ~slowflag;
739 kdebug_enable &= ~enableflag;
740 }
0a7de745 741
6d2010ae
A
742 lck_spin_unlock(kds_spin_lock);
743 ml_set_interrupts_enabled(s);
744}
745
39037602
A
746/*
747 * Disable wrapping and return true if trace wrapped, false otherwise.
748 */
cb323159 749static bool
6d2010ae
A
750disable_wrap(uint32_t *old_slowcheck, uint32_t *old_flags)
751{
cb323159
A
752 bool wrapped;
753 int s = ml_set_interrupts_enabled(false);
0a7de745 754 lck_spin_lock_grp(kds_spin_lock, kdebug_lck_grp);
6d2010ae
A
755
756 *old_slowcheck = kd_ctrl_page.kdebug_slowcheck;
757 *old_flags = kd_ctrl_page.kdebug_flags;
758
39037602 759 wrapped = kd_ctrl_page.kdebug_flags & KDBG_WRAPPED;
6d2010ae
A
760 kd_ctrl_page.kdebug_flags &= ~KDBG_WRAPPED;
761 kd_ctrl_page.kdebug_flags |= KDBG_NOWRAP;
762
763 lck_spin_unlock(kds_spin_lock);
764 ml_set_interrupts_enabled(s);
39037602
A
765
766 return wrapped;
6d2010ae
A
767}
768
d9a64523
A
769static void
770enable_wrap(uint32_t old_slowcheck)
6d2010ae 771{
cb323159 772 int s = ml_set_interrupts_enabled(false);
0a7de745 773 lck_spin_lock_grp(kds_spin_lock, kdebug_lck_grp);
6d2010ae
A
774
775 kd_ctrl_page.kdebug_flags &= ~KDBG_NOWRAP;
776
0a7de745 777 if (!(old_slowcheck & SLOW_NOLOG)) {
6d2010ae 778 kd_ctrl_page.kdebug_slowcheck &= ~SLOW_NOLOG;
0a7de745 779 }
6d2010ae 780
6d2010ae
A
781 lck_spin_unlock(kds_spin_lock);
782 ml_set_interrupts_enabled(s);
783}
784
0c530ab8 785static int
cb323159 786create_buffers(bool early_trace)
0c530ab8 787{
5ba3f43e
A
788 unsigned int i;
789 unsigned int p_buffer_size;
790 unsigned int f_buffer_size;
791 unsigned int f_buffers;
39037602 792 int error = 0;
b0d623f7 793
39236c6e
A
794 /*
795 * For the duration of this allocation, trace code will only reference
796 * kdebug_iops. Any iops registered after this enabling will not be
797 * messaged until the buffers are reallocated.
798 *
799 * TLDR; Must read kd_iops once and only once!
800 */
801 kd_ctrl_page.kdebug_iops = kd_iops;
6d2010ae 802
5ba3f43e
A
803#if CONFIG_EMBEDDED
804 assert(kdbg_iop_list_is_valid(kd_ctrl_page.kdebug_iops));
805#endif
39236c6e
A
806
807 /*
808 * If the list is valid, it is sorted, newest -> oldest. Each iop entry
809 * has a cpu_id of "the older entry + 1", so the highest cpu_id will
810 * be the list head + 1.
811 */
6d2010ae 812
39236c6e 813 kd_ctrl_page.kdebug_cpus = kd_ctrl_page.kdebug_iops ? kd_ctrl_page.kdebug_iops->cpu_id + 1 : kdbg_cpu_count(early_trace);
6d2010ae 814
3e170ce0 815 if (kmem_alloc(kernel_map, (vm_offset_t *)&kdbip, sizeof(struct kd_bufinfo) * kd_ctrl_page.kdebug_cpus, VM_KERN_MEMORY_DIAG) != KERN_SUCCESS) {
39236c6e
A
816 error = ENOSPC;
817 goto out;
6d2010ae 818 }
6d2010ae 819
0a7de745 820 if (nkdbufs < (kd_ctrl_page.kdebug_cpus * EVENTS_PER_STORAGE_UNIT * MIN_STORAGE_UNITS_PER_CPU)) {
39236c6e 821 n_storage_units = kd_ctrl_page.kdebug_cpus * MIN_STORAGE_UNITS_PER_CPU;
0a7de745 822 } else {
b0d623f7 823 n_storage_units = nkdbufs / EVENTS_PER_STORAGE_UNIT;
0a7de745 824 }
0c530ab8 825
b0d623f7 826 nkdbufs = n_storage_units * EVENTS_PER_STORAGE_UNIT;
2d21ac55 827
b0d623f7
A
828 f_buffers = n_storage_units / N_STORAGE_UNITS_PER_BUFFER;
829 n_storage_buffers = f_buffers;
0c530ab8 830
b0d623f7
A
831 f_buffer_size = N_STORAGE_UNITS_PER_BUFFER * sizeof(struct kd_storage);
832 p_buffer_size = (n_storage_units % N_STORAGE_UNITS_PER_BUFFER) * sizeof(struct kd_storage);
833
0a7de745 834 if (p_buffer_size) {
b0d623f7 835 n_storage_buffers++;
0a7de745 836 }
b0d623f7
A
837
838 kd_bufs = NULL;
0c530ab8
A
839
840 if (kdcopybuf == 0) {
0a7de745 841 if (kmem_alloc(kernel_map, (vm_offset_t *)&kdcopybuf, (vm_size_t)KDCOPYBUF_SIZE, VM_KERN_MEMORY_DIAG) != KERN_SUCCESS) {
b0d623f7
A
842 error = ENOSPC;
843 goto out;
844 }
0c530ab8 845 }
3e170ce0 846 if (kmem_alloc(kernel_map, (vm_offset_t *)&kd_bufs, (vm_size_t)(n_storage_buffers * sizeof(struct kd_storage_buffers)), VM_KERN_MEMORY_DIAG) != KERN_SUCCESS) {
b0d623f7
A
847 error = ENOSPC;
848 goto out;
0c530ab8 849 }
b0d623f7 850 bzero(kd_bufs, n_storage_buffers * sizeof(struct kd_storage_buffers));
0c530ab8 851
b0d623f7 852 for (i = 0; i < f_buffers; i++) {
3e170ce0 853 if (kmem_alloc(kernel_map, (vm_offset_t *)&kd_bufs[i].kdsb_addr, (vm_size_t)f_buffer_size, VM_KERN_MEMORY_DIAG) != KERN_SUCCESS) {
b0d623f7
A
854 error = ENOSPC;
855 goto out;
856 }
6d2010ae
A
857 bzero(kd_bufs[i].kdsb_addr, f_buffer_size);
858
b0d623f7 859 kd_bufs[i].kdsb_size = f_buffer_size;
0c530ab8 860 }
b0d623f7 861 if (p_buffer_size) {
3e170ce0 862 if (kmem_alloc(kernel_map, (vm_offset_t *)&kd_bufs[i].kdsb_addr, (vm_size_t)p_buffer_size, VM_KERN_MEMORY_DIAG) != KERN_SUCCESS) {
b0d623f7
A
863 error = ENOSPC;
864 goto out;
865 }
6d2010ae
A
866 bzero(kd_bufs[i].kdsb_addr, p_buffer_size);
867
b0d623f7
A
868 kd_bufs[i].kdsb_size = p_buffer_size;
869 }
6d2010ae 870 n_storage_units = 0;
b0d623f7
A
871
872 for (i = 0; i < n_storage_buffers; i++) {
873 struct kd_storage *kds;
0a7de745
A
874 int n_elements;
875 int n;
b0d623f7
A
876
877 n_elements = kd_bufs[i].kdsb_size / sizeof(struct kd_storage);
878 kds = kd_bufs[i].kdsb_addr;
879
880 for (n = 0; n < n_elements; n++) {
6d2010ae
A
881 kds[n].kds_next.buffer_index = kd_ctrl_page.kds_free_list.buffer_index;
882 kds[n].kds_next.offset = kd_ctrl_page.kds_free_list.offset;
b0d623f7 883
6d2010ae
A
884 kd_ctrl_page.kds_free_list.buffer_index = i;
885 kd_ctrl_page.kds_free_list.offset = n;
b0d623f7 886 }
6d2010ae 887 n_storage_units += n_elements;
0c530ab8 888 }
6d2010ae 889
39236c6e 890 bzero((char *)kdbip, sizeof(struct kd_bufinfo) * kd_ctrl_page.kdebug_cpus);
b0d623f7 891
5ba3f43e 892 for (i = 0; i < kd_ctrl_page.kdebug_cpus; i++) {
6d2010ae
A
893 kdbip[i].kd_list_head.raw = KDS_PTR_NULL;
894 kdbip[i].kd_list_tail.raw = KDS_PTR_NULL;
cb323159 895 kdbip[i].kd_lostevents = false;
6d2010ae
A
896 kdbip[i].num_bufs = 0;
897 }
0a7de745 898
6d2010ae
A
899 kd_ctrl_page.kdebug_flags |= KDBG_BUFINIT;
900
901 kd_ctrl_page.kds_inuse_count = 0;
902 n_storage_threshold = n_storage_units / 2;
b0d623f7 903out:
0a7de745 904 if (error) {
b0d623f7 905 delete_buffers();
0a7de745 906 }
0c530ab8 907
0a7de745 908 return error;
0c530ab8
A
909}
910
0c530ab8
A
911static void
912delete_buffers(void)
4452a7af 913{
5ba3f43e 914 unsigned int i;
0a7de745 915
b0d623f7
A
916 if (kd_bufs) {
917 for (i = 0; i < n_storage_buffers; i++) {
6d2010ae 918 if (kd_bufs[i].kdsb_addr) {
b0d623f7 919 kmem_free(kernel_map, (vm_offset_t)kd_bufs[i].kdsb_addr, (vm_size_t)kd_bufs[i].kdsb_size);
6d2010ae 920 }
b0d623f7
A
921 }
922 kmem_free(kernel_map, (vm_offset_t)kd_bufs, (vm_size_t)(n_storage_buffers * sizeof(struct kd_storage_buffers)));
0c530ab8 923
b0d623f7
A
924 kd_bufs = NULL;
925 n_storage_buffers = 0;
0c530ab8
A
926 }
927 if (kdcopybuf) {
928 kmem_free(kernel_map, (vm_offset_t)kdcopybuf, KDCOPYBUF_SIZE);
b0d623f7 929
0c530ab8
A
930 kdcopybuf = NULL;
931 }
6d2010ae 932 kd_ctrl_page.kds_free_list.raw = KDS_PTR_NULL;
b0d623f7 933
6d2010ae 934 if (kdbip) {
39236c6e 935 kmem_free(kernel_map, (vm_offset_t)kdbip, sizeof(struct kd_bufinfo) * kd_ctrl_page.kdebug_cpus);
0a7de745 936
6d2010ae
A
937 kdbip = NULL;
938 }
0a7de745 939 kd_ctrl_page.kdebug_iops = NULL;
39236c6e 940 kd_ctrl_page.kdebug_cpus = 0;
6d2010ae 941 kd_ctrl_page.kdebug_flags &= ~KDBG_BUFINIT;
0c530ab8
A
942}
943
6d2010ae
A
944void
945release_storage_unit(int cpu, uint32_t kdsp_raw)
0c530ab8 946{
b0d623f7 947 int s = 0;
0a7de745 948 struct kd_storage *kdsp_actual;
6d2010ae
A
949 struct kd_bufinfo *kdbp;
950 union kds_ptr kdsp;
951
952 kdsp.raw = kdsp_raw;
953
cb323159 954 s = ml_set_interrupts_enabled(false);
0a7de745 955 lck_spin_lock_grp(kds_spin_lock, kdebug_lck_grp);
b0d623f7 956
6d2010ae
A
957 kdbp = &kdbip[cpu];
958
959 if (kdsp.raw == kdbp->kd_list_head.raw) {
b0d623f7 960 /*
6d2010ae 961 * it's possible for the storage unit pointed to
b0d623f7 962 * by kdsp to have already been stolen... so
6d2010ae 963 * check to see if it's still the head of the list
0a7de745 964 * now that we're behind the lock that protects
b0d623f7
A
965 * adding and removing from the queue...
966 * since we only ever release and steal units from
6d2010ae 967 * that position, if it's no longer the head
b0d623f7
A
968 * we having nothing to do in this context
969 */
6d2010ae
A
970 kdsp_actual = POINTER_FROM_KDS_PTR(kdsp);
971 kdbp->kd_list_head = kdsp_actual->kds_next;
39236c6e 972
6d2010ae
A
973 kdsp_actual->kds_next = kd_ctrl_page.kds_free_list;
974 kd_ctrl_page.kds_free_list = kdsp;
975
976 kd_ctrl_page.kds_inuse_count--;
b0d623f7
A
977 }
978 lck_spin_unlock(kds_spin_lock);
979 ml_set_interrupts_enabled(s);
980}
981
cb323159 982bool
6d2010ae 983allocate_storage_unit(int cpu)
b0d623f7 984{
39037602
A
985 union kds_ptr kdsp;
986 struct kd_storage *kdsp_actual, *kdsp_next_actual;
987 struct kd_bufinfo *kdbp, *kdbp_vict, *kdbp_try;
988 uint64_t oldest_ts, ts;
cb323159 989 bool retval = true;
39037602
A
990 int s = 0;
991
cb323159 992 s = ml_set_interrupts_enabled(false);
0a7de745 993 lck_spin_lock_grp(kds_spin_lock, kdebug_lck_grp);
b0d623f7 994
6d2010ae
A
995 kdbp = &kdbip[cpu];
996
997 /* If someone beat us to the allocate, return success */
998 if (kdbp->kd_list_tail.raw != KDS_PTR_NULL) {
999 kdsp_actual = POINTER_FROM_KDS_PTR(kdbp->kd_list_tail);
1000
0a7de745 1001 if (kdsp_actual->kds_bufindx < EVENTS_PER_STORAGE_UNIT) {
6d2010ae 1002 goto out;
0a7de745 1003 }
6d2010ae 1004 }
d9a64523 1005
6d2010ae 1006 if ((kdsp = kd_ctrl_page.kds_free_list).raw != KDS_PTR_NULL) {
d9a64523
A
1007 /*
1008 * If there's a free page, grab it from the free list.
1009 */
6d2010ae
A
1010 kdsp_actual = POINTER_FROM_KDS_PTR(kdsp);
1011 kd_ctrl_page.kds_free_list = kdsp_actual->kds_next;
1012
1013 kd_ctrl_page.kds_inuse_count++;
1014 } else {
d9a64523
A
1015 /*
1016 * Otherwise, we're going to lose events and repurpose the oldest
1017 * storage unit we can find.
1018 */
6d2010ae
A
1019 if (kd_ctrl_page.kdebug_flags & KDBG_NOWRAP) {
1020 kd_ctrl_page.kdebug_slowcheck |= SLOW_NOLOG;
cb323159
A
1021 kdbp->kd_lostevents = true;
1022 retval = false;
b0d623f7
A
1023 goto out;
1024 }
1025 kdbp_vict = NULL;
39037602 1026 oldest_ts = UINT64_MAX;
b0d623f7 1027
39236c6e 1028 for (kdbp_try = &kdbip[0]; kdbp_try < &kdbip[kd_ctrl_page.kdebug_cpus]; kdbp_try++) {
6d2010ae 1029 if (kdbp_try->kd_list_head.raw == KDS_PTR_NULL) {
b0d623f7
A
1030 /*
1031 * no storage unit to steal
1032 */
1033 continue;
1034 }
6d2010ae
A
1035
1036 kdsp_actual = POINTER_FROM_KDS_PTR(kdbp_try->kd_list_head);
1037
1038 if (kdsp_actual->kds_bufcnt < EVENTS_PER_STORAGE_UNIT) {
b0d623f7
A
1039 /*
1040 * make sure we don't steal the storage unit
6d2010ae
A
1041 * being actively recorded to... need to
1042 * move on because we don't want an out-of-order
1043 * set of events showing up later
b0d623f7
A
1044 */
1045 continue;
1046 }
b0d623f7 1047
39037602
A
1048 /*
1049 * When wrapping, steal the storage unit with the
1050 * earliest timestamp on its last event, instead of the
1051 * earliest timestamp on the first event. This allows a
1052 * storage unit with more recent events to be preserved,
1053 * even if the storage unit contains events that are
1054 * older than those found in other CPUs.
1055 */
1056 ts = kdbg_get_timestamp(&kdsp_actual->kds_records[EVENTS_PER_STORAGE_UNIT - 1]);
b0d623f7 1057 if (ts < oldest_ts) {
b0d623f7
A
1058 oldest_ts = ts;
1059 kdbp_vict = kdbp_try;
1060 }
1061 }
b0d623f7
A
1062 if (kdbp_vict == NULL) {
1063 kdebug_enable = 0;
6d2010ae 1064 kd_ctrl_page.enabled = 0;
39037602 1065 commpage_update_kdebug_state();
cb323159 1066 retval = false;
6d2010ae 1067 goto out;
b0d623f7 1068 }
b0d623f7 1069 kdsp = kdbp_vict->kd_list_head;
6d2010ae 1070 kdsp_actual = POINTER_FROM_KDS_PTR(kdsp);
6d2010ae 1071 kdbp_vict->kd_list_head = kdsp_actual->kds_next;
b0d623f7 1072
316670eb
A
1073 if (kdbp_vict->kd_list_head.raw != KDS_PTR_NULL) {
1074 kdsp_next_actual = POINTER_FROM_KDS_PTR(kdbp_vict->kd_list_head);
cb323159 1075 kdsp_next_actual->kds_lostevents = true;
0a7de745 1076 } else {
cb323159 1077 kdbp_vict->kd_lostevents = true;
0a7de745 1078 }
316670eb 1079
d9a64523
A
1080 if (kd_ctrl_page.oldest_time < oldest_ts) {
1081 kd_ctrl_page.oldest_time = oldest_ts;
1082 }
6d2010ae 1083 kd_ctrl_page.kdebug_flags |= KDBG_WRAPPED;
b0d623f7 1084 }
5ba3f43e 1085 kdsp_actual->kds_timestamp = kdbg_timestamp();
6d2010ae 1086 kdsp_actual->kds_next.raw = KDS_PTR_NULL;
0a7de745 1087 kdsp_actual->kds_bufcnt = 0;
6d2010ae
A
1088 kdsp_actual->kds_readlast = 0;
1089
1090 kdsp_actual->kds_lostevents = kdbp->kd_lostevents;
cb323159 1091 kdbp->kd_lostevents = false;
d9a64523 1092 kdsp_actual->kds_bufindx = 0;
b0d623f7 1093
0a7de745 1094 if (kdbp->kd_list_head.raw == KDS_PTR_NULL) {
b0d623f7 1095 kdbp->kd_list_head = kdsp;
0a7de745 1096 } else {
6d2010ae 1097 POINTER_FROM_KDS_PTR(kdbp->kd_list_tail)->kds_next = kdsp;
0a7de745 1098 }
b0d623f7
A
1099 kdbp->kd_list_tail = kdsp;
1100out:
1101 lck_spin_unlock(kds_spin_lock);
6d2010ae 1102 ml_set_interrupts_enabled(s);
b0d623f7 1103
0a7de745 1104 return retval;
b0d623f7 1105}
39236c6e
A
1106
1107int
1108kernel_debug_register_callback(kd_callback_t callback)
1109{
1110 kd_iop_t* iop;
3e170ce0 1111 if (kmem_alloc(kernel_map, (vm_offset_t *)&iop, sizeof(kd_iop_t), VM_KERN_MEMORY_DIAG) == KERN_SUCCESS) {
39236c6e 1112 memcpy(&iop->callback, &callback, sizeof(kd_callback_t));
0a7de745 1113
39236c6e
A
1114 /*
1115 * <rdar://problem/13351477> Some IOP clients are not providing a name.
1116 *
1117 * Remove when fixed.
1118 */
1119 {
cb323159 1120 bool is_valid_name = false;
0a7de745 1121 for (uint32_t length = 0; length < sizeof(callback.iop_name); ++length) {
39236c6e 1122 /* This is roughly isprintable(c) */
0a7de745 1123 if (callback.iop_name[length] > 0x20 && callback.iop_name[length] < 0x7F) {
39236c6e 1124 continue;
0a7de745 1125 }
39236c6e 1126 if (callback.iop_name[length] == 0) {
0a7de745 1127 if (length) {
cb323159 1128 is_valid_name = true;
0a7de745 1129 }
39236c6e
A
1130 break;
1131 }
1132 }
0a7de745 1133
39236c6e
A
1134 if (!is_valid_name) {
1135 strlcpy(iop->callback.iop_name, "IOP-???", sizeof(iop->callback.iop_name));
1136 }
1137 }
1138
1139 iop->last_timestamp = 0;
0a7de745 1140
39236c6e
A
1141 do {
1142 /*
1143 * We use two pieces of state, the old list head
1144 * pointer, and the value of old_list_head->cpu_id.
1145 * If we read kd_iops more than once, it can change
1146 * between reads.
1147 *
1148 * TLDR; Must not read kd_iops more than once per loop.
1149 */
1150 iop->next = kd_iops;
cb323159 1151 iop->cpu_id = iop->next ? (iop->next->cpu_id + 1) : kdbg_cpu_count(false);
39236c6e
A
1152
1153 /*
1154 * Header says OSCompareAndSwapPtr has a memory barrier
1155 */
1156 } while (!OSCompareAndSwapPtr(iop->next, iop, (void* volatile*)&kd_iops));
1157
1158 return iop->cpu_id;
1159 }
1160
1161 return 0;
1162}
1163
1164void
1165kernel_debug_enter(
0a7de745
A
1166 uint32_t coreid,
1167 uint32_t debugid,
1168 uint64_t timestamp,
1169 uintptr_t arg1,
1170 uintptr_t arg2,
1171 uintptr_t arg3,
1172 uintptr_t arg4,
1173 uintptr_t threadid
39236c6e
A
1174 )
1175{
0a7de745
A
1176 uint32_t bindx;
1177 kd_buf *kd;
39236c6e
A
1178 struct kd_bufinfo *kdbp;
1179 struct kd_storage *kdsp_actual;
1180 union kds_ptr kds_raw;
1181
1182 if (kd_ctrl_page.kdebug_slowcheck) {
0a7de745 1183 if ((kd_ctrl_page.kdebug_slowcheck & SLOW_NOLOG) || !(kdebug_enable & (KDEBUG_ENABLE_TRACE | KDEBUG_ENABLE_PPT))) {
39236c6e 1184 goto out1;
0a7de745
A
1185 }
1186
39236c6e 1187 if (kd_ctrl_page.kdebug_flags & KDBG_TYPEFILTER_CHECK) {
0a7de745 1188 if (typefilter_is_debugid_allowed(kdbg_typefilter, debugid)) {
39037602 1189 goto record_event;
0a7de745 1190 }
39236c6e 1191 goto out1;
0a7de745
A
1192 } else if (kd_ctrl_page.kdebug_flags & KDBG_RANGECHECK) {
1193 if (debugid >= kdlog_beg && debugid <= kdlog_end) {
39236c6e 1194 goto record_event;
0a7de745 1195 }
39236c6e 1196 goto out1;
0a7de745 1197 } else if (kd_ctrl_page.kdebug_flags & KDBG_VALCHECK) {
3e170ce0 1198 if ((debugid & KDBG_EVENTID_MASK) != kdlog_value1 &&
0a7de745
A
1199 (debugid & KDBG_EVENTID_MASK) != kdlog_value2 &&
1200 (debugid & KDBG_EVENTID_MASK) != kdlog_value3 &&
1201 (debugid & KDBG_EVENTID_MASK) != kdlog_value4) {
39236c6e 1202 goto out1;
0a7de745 1203 }
39236c6e
A
1204 }
1205 }
39037602 1206
5ba3f43e
A
1207record_event:
1208 if (timestamp < kd_ctrl_page.oldest_time) {
1209 goto out1;
39037602
A
1210 }
1211
5ba3f43e
A
1212#if CONFIG_EMBEDDED
1213 /*
0a7de745
A
1214 * When start_kern_tracing is called by the kernel to trace very
1215 * early kernel events, it saves data to a secondary buffer until
1216 * it is possible to initialize ktrace, and then dumps the events
1217 * into the ktrace buffer using this method. In this case, iops will
1218 * be NULL, and the coreid will be zero. It is not possible to have
1219 * a valid IOP coreid of zero, so pass if both iops is NULL and coreid
1220 * is zero.
1221 */
5ba3f43e
A
1222 assert(kdbg_iop_list_contains_cpu_id(kd_ctrl_page.kdebug_iops, coreid) || (kd_ctrl_page.kdebug_iops == NULL && coreid == 0));
1223#endif
39236c6e
A
1224
1225 disable_preemption();
1226
0a7de745 1227 if (kd_ctrl_page.enabled == 0) {
39236c6e 1228 goto out;
0a7de745 1229 }
39236c6e
A
1230
1231 kdbp = &kdbip[coreid];
1232 timestamp &= KDBG_TIMESTAMP_MASK;
1233
04b8595b 1234#if KDEBUG_MOJO_TRACE
0a7de745 1235 if (kdebug_enable & KDEBUG_ENABLE_SERIAL) {
04b8595b 1236 kdebug_serial_print(coreid, debugid, timestamp,
0a7de745
A
1237 arg1, arg2, arg3, arg4, threadid);
1238 }
04b8595b
A
1239#endif
1240
39236c6e
A
1241retry_q:
1242 kds_raw = kdbp->kd_list_tail;
1243
1244 if (kds_raw.raw != KDS_PTR_NULL) {
1245 kdsp_actual = POINTER_FROM_KDS_PTR(kds_raw);
1246 bindx = kdsp_actual->kds_bufindx;
5ba3f43e 1247 } else {
39236c6e 1248 kdsp_actual = NULL;
5ba3f43e
A
1249 bindx = EVENTS_PER_STORAGE_UNIT;
1250 }
0a7de745 1251
39236c6e 1252 if (kdsp_actual == NULL || bindx >= EVENTS_PER_STORAGE_UNIT) {
cb323159 1253 if (allocate_storage_unit(coreid) == false) {
39236c6e
A
1254 /*
1255 * this can only happen if wrapping
1256 * has been disabled
1257 */
1258 goto out;
1259 }
1260 goto retry_q;
1261 }
0a7de745 1262 if (!OSCompareAndSwap(bindx, bindx + 1, &kdsp_actual->kds_bufindx)) {
39236c6e 1263 goto retry_q;
0a7de745 1264 }
39236c6e
A
1265
1266 // IOP entries can be allocated before xnu allocates and inits the buffer
0a7de745 1267 if (timestamp < kdsp_actual->kds_timestamp) {
39236c6e 1268 kdsp_actual->kds_timestamp = timestamp;
0a7de745 1269 }
39236c6e
A
1270
1271 kd = &kdsp_actual->kds_records[bindx];
1272
1273 kd->debugid = debugid;
1274 kd->arg1 = arg1;
1275 kd->arg2 = arg2;
1276 kd->arg3 = arg3;
1277 kd->arg4 = arg4;
1278 kd->arg5 = threadid;
0a7de745 1279
39236c6e
A
1280 kdbg_set_timestamp_and_cpu(kd, timestamp, coreid);
1281
1282 OSAddAtomic(1, &kdsp_actual->kds_bufcnt);
1283out:
1284 enable_preemption();
1285out1:
1286 if ((kds_waiter && kd_ctrl_page.kds_inuse_count >= n_storage_threshold)) {
39037602 1287 kdbg_wakeup();
39236c6e
A
1288 }
1289}
1290
d9a64523
A
1291/*
1292 * Check if the given debug ID is allowed to be traced on the current process.
1293 *
1294 * Returns true if allowed and false otherwise.
1295 */
1296static inline bool
1297kdebug_debugid_procfilt_allowed(uint32_t debugid)
1298{
1299 uint32_t procfilt_flags = kd_ctrl_page.kdebug_flags &
0a7de745 1300 (KDBG_PIDCHECK | KDBG_PIDEXCLUDE);
d9a64523
A
1301
1302 if (!procfilt_flags) {
1303 return true;
1304 }
1305
1306 /*
1307 * DBG_TRACE and MACH_SCHED tracepoints ignore the process filter.
1308 */
1309 if ((debugid & 0xffff0000) == MACHDBG_CODE(DBG_MACH_SCHED, 0) ||
0a7de745 1310 (debugid >> 24 == DBG_TRACE)) {
d9a64523
A
1311 return true;
1312 }
1313
1314 struct proc *curproc = current_proc();
1315 /*
1316 * If the process is missing (early in boot), allow it.
1317 */
1318 if (!curproc) {
1319 return true;
1320 }
1321
1322 if (procfilt_flags & KDBG_PIDCHECK) {
1323 /*
1324 * Allow only processes marked with the kdebug bit.
1325 */
1326 return curproc->p_kdebug;
1327 } else if (procfilt_flags & KDBG_PIDEXCLUDE) {
1328 /*
1329 * Exclude any process marked with the kdebug bit.
1330 */
1331 return !curproc->p_kdebug;
1332 } else {
1333 panic("kdebug: invalid procfilt flags %x", kd_ctrl_page.kdebug_flags);
1334 __builtin_unreachable();
1335 }
1336}
1337
a1c7dba1 1338static void
b0d623f7 1339kernel_debug_internal(
d9a64523 1340 uint32_t debugid,
39037602
A
1341 uintptr_t arg1,
1342 uintptr_t arg2,
1343 uintptr_t arg3,
1344 uintptr_t arg4,
d9a64523
A
1345 uintptr_t arg5,
1346 uint64_t flags)
b0d623f7 1347{
d9a64523
A
1348 uint64_t now;
1349 uint32_t bindx;
1350 kd_buf *kd;
1351 int cpu;
b0d623f7 1352 struct kd_bufinfo *kdbp;
6d2010ae 1353 struct kd_storage *kdsp_actual;
d9a64523
A
1354 union kds_ptr kds_raw;
1355 bool only_filter = flags & KDBG_FLAG_FILTERED;
1356 bool observe_procfilt = !(flags & KDBG_FLAG_NOPROCFILT);
b0d623f7 1357
6d2010ae 1358 if (kd_ctrl_page.kdebug_slowcheck) {
39037602 1359 if ((kd_ctrl_page.kdebug_slowcheck & SLOW_NOLOG) ||
0a7de745 1360 !(kdebug_enable & (KDEBUG_ENABLE_TRACE | KDEBUG_ENABLE_PPT))) {
6d2010ae 1361 goto out1;
39037602
A
1362 }
1363
d9a64523 1364 if (!ml_at_interrupt_context() && observe_procfilt &&
0a7de745 1365 !kdebug_debugid_procfilt_allowed(debugid)) {
d9a64523 1366 goto out1;
6d2010ae 1367 }
316670eb
A
1368
1369 if (kd_ctrl_page.kdebug_flags & KDBG_TYPEFILTER_CHECK) {
0a7de745 1370 if (typefilter_is_debugid_allowed(kdbg_typefilter, debugid)) {
316670eb 1371 goto record_event;
0a7de745 1372 }
316670eb 1373
39037602 1374 goto out1;
d9a64523 1375 } else if (only_filter) {
316670eb 1376 goto out1;
0a7de745 1377 } else if (kd_ctrl_page.kdebug_flags & KDBG_RANGECHECK) {
39236c6e 1378 /* Always record trace system info */
0a7de745 1379 if (KDBG_EXTRACT_CLASS(debugid) == DBG_TRACE) {
316670eb 1380 goto record_event;
0a7de745 1381 }
d9a64523 1382
0a7de745 1383 if (debugid < kdlog_beg || debugid > kdlog_end) {
39236c6e 1384 goto out1;
0a7de745
A
1385 }
1386 } else if (kd_ctrl_page.kdebug_flags & KDBG_VALCHECK) {
39236c6e 1387 /* Always record trace system info */
0a7de745 1388 if (KDBG_EXTRACT_CLASS(debugid) == DBG_TRACE) {
39236c6e 1389 goto record_event;
0a7de745 1390 }
d9a64523 1391
3e170ce0
A
1392 if ((debugid & KDBG_EVENTID_MASK) != kdlog_value1 &&
1393 (debugid & KDBG_EVENTID_MASK) != kdlog_value2 &&
1394 (debugid & KDBG_EVENTID_MASK) != kdlog_value3 &&
0a7de745 1395 (debugid & KDBG_EVENTID_MASK) != kdlog_value4) {
6d2010ae 1396 goto out1;
0a7de745 1397 }
6d2010ae 1398 }
d9a64523 1399 } else if (only_filter) {
39037602 1400 goto out1;
b0d623f7 1401 }
39037602 1402
316670eb 1403record_event:
6d2010ae 1404 disable_preemption();
39236c6e 1405
0a7de745 1406 if (kd_ctrl_page.enabled == 0) {
39236c6e 1407 goto out;
0a7de745 1408 }
39236c6e 1409
6d2010ae 1410 cpu = cpu_number();
b0d623f7 1411 kdbp = &kdbip[cpu];
04b8595b
A
1412
1413#if KDEBUG_MOJO_TRACE
0a7de745 1414 if (kdebug_enable & KDEBUG_ENABLE_SERIAL) {
04b8595b 1415 kdebug_serial_print(cpu, debugid,
0a7de745
A
1416 kdbg_timestamp() & KDBG_TIMESTAMP_MASK,
1417 arg1, arg2, arg3, arg4, arg5);
1418 }
04b8595b
A
1419#endif
1420
6d2010ae 1421retry_q:
316670eb
A
1422 kds_raw = kdbp->kd_list_tail;
1423
1424 if (kds_raw.raw != KDS_PTR_NULL) {
1425 kdsp_actual = POINTER_FROM_KDS_PTR(kds_raw);
6d2010ae 1426 bindx = kdsp_actual->kds_bufindx;
5ba3f43e 1427 } else {
6d2010ae 1428 kdsp_actual = NULL;
5ba3f43e 1429 bindx = EVENTS_PER_STORAGE_UNIT;
d9a64523 1430 }
5ba3f43e 1431
6d2010ae 1432 if (kdsp_actual == NULL || bindx >= EVENTS_PER_STORAGE_UNIT) {
cb323159 1433 if (allocate_storage_unit(cpu) == false) {
b0d623f7
A
1434 /*
1435 * this can only happen if wrapping
1436 * has been disabled
1437 */
1438 goto out;
1439 }
6d2010ae 1440 goto retry_q;
b0d623f7 1441 }
d9a64523 1442
5ba3f43e 1443 now = kdbg_timestamp() & KDBG_TIMESTAMP_MASK;
6d2010ae 1444
0a7de745 1445 if (!OSCompareAndSwap(bindx, bindx + 1, &kdsp_actual->kds_bufindx)) {
6d2010ae 1446 goto retry_q;
0a7de745 1447 }
6d2010ae
A
1448
1449 kd = &kdsp_actual->kds_records[bindx];
b0d623f7 1450
1c79356b
A
1451 kd->debugid = debugid;
1452 kd->arg1 = arg1;
1453 kd->arg2 = arg2;
1454 kd->arg3 = arg3;
1455 kd->arg4 = arg4;
0c530ab8 1456 kd->arg5 = arg5;
39037602 1457
b0d623f7 1458 kdbg_set_timestamp_and_cpu(kd, now, cpu);
1c79356b 1459
6d2010ae 1460 OSAddAtomic(1, &kdsp_actual->kds_bufcnt);
39037602
A
1461
1462#if KPERF
1463 kperf_kdebug_callback(debugid, __builtin_frame_address(0));
1464#endif
0c530ab8 1465out:
6d2010ae
A
1466 enable_preemption();
1467out1:
fe8ab488 1468 if (kds_waiter && kd_ctrl_page.kds_inuse_count >= n_storage_threshold) {
0a7de745
A
1469 uint32_t etype;
1470 uint32_t stype;
39037602 1471
3e170ce0
A
1472 etype = debugid & KDBG_EVENTID_MASK;
1473 stype = debugid & KDBG_CSC_MASK;
6d2010ae
A
1474
1475 if (etype == INTERRUPT || etype == MACH_vmfault ||
1476 stype == BSC_SysCall || stype == MACH_SysCall) {
39037602 1477 kdbg_wakeup();
6d2010ae
A
1478 }
1479 }
1c79356b
A
1480}
1481
cb323159 1482__attribute__((noinline))
1c79356b 1483void
b0d623f7 1484kernel_debug(
0a7de745
A
1485 uint32_t debugid,
1486 uintptr_t arg1,
1487 uintptr_t arg2,
1488 uintptr_t arg3,
1489 uintptr_t arg4,
b0d623f7 1490 __unused uintptr_t arg5)
1c79356b 1491{
d9a64523 1492 kernel_debug_internal(debugid, arg1, arg2, arg3, arg4,
0a7de745 1493 (uintptr_t)thread_tid(current_thread()), 0);
0c530ab8 1494}
21362eb3 1495
cb323159 1496__attribute__((noinline))
0c530ab8 1497void
b0d623f7 1498kernel_debug1(
0a7de745
A
1499 uint32_t debugid,
1500 uintptr_t arg1,
1501 uintptr_t arg2,
1502 uintptr_t arg3,
1503 uintptr_t arg4,
1504 uintptr_t arg5)
0c530ab8 1505{
d9a64523
A
1506 kernel_debug_internal(debugid, arg1, arg2, arg3, arg4, arg5, 0);
1507}
1508
cb323159 1509__attribute__((noinline))
d9a64523
A
1510void
1511kernel_debug_flags(
1512 uint32_t debugid,
1513 uintptr_t arg1,
1514 uintptr_t arg2,
1515 uintptr_t arg3,
1516 uintptr_t arg4,
1517 uint64_t flags)
1518{
1519 kernel_debug_internal(debugid, arg1, arg2, arg3, arg4,
0a7de745 1520 (uintptr_t)thread_tid(current_thread()), flags);
39037602
A
1521}
1522
cb323159 1523__attribute__((noinline))
39037602
A
1524void
1525kernel_debug_filtered(
d9a64523 1526 uint32_t debugid,
39037602
A
1527 uintptr_t arg1,
1528 uintptr_t arg2,
1529 uintptr_t arg3,
1530 uintptr_t arg4)
1531{
d9a64523 1532 kernel_debug_flags(debugid, arg1, arg2, arg3, arg4, KDBG_FLAG_FILTERED);
fe8ab488
A
1533}
1534
1535void
39037602 1536kernel_debug_string_early(const char *message)
fe8ab488
A
1537{
1538 uintptr_t arg[4] = {0, 0, 0, 0};
1539
1540 /* Stuff the message string in the args and log it. */
39037602 1541 strncpy((char *)arg, message, MIN(sizeof(arg), strlen(message)));
fe8ab488 1542 KERNEL_DEBUG_EARLY(
04b8595b 1543 TRACE_INFO_STRING,
fe8ab488
A
1544 arg[0], arg[1], arg[2], arg[3]);
1545}
1546
39037602
A
1547#define SIMPLE_STR_LEN (64)
1548static_assert(SIMPLE_STR_LEN % sizeof(uintptr_t) == 0);
1549
1550void
1551kernel_debug_string_simple(uint32_t eventid, const char *str)
1552{
a39ff7e2
A
1553 if (!kdebug_enable) {
1554 return;
1555 }
1556
39037602
A
1557 /* array of uintptr_ts simplifies emitting the string as arguments */
1558 uintptr_t str_buf[(SIMPLE_STR_LEN / sizeof(uintptr_t)) + 1] = { 0 };
1559 size_t len = strlcpy((char *)str_buf, str, SIMPLE_STR_LEN + 1);
1560
1561 uintptr_t thread_id = (uintptr_t)thread_tid(current_thread());
1562 uint32_t debugid = eventid | DBG_FUNC_START;
1563
1564 /* string can fit in a single tracepoint */
1565 if (len <= (4 * sizeof(uintptr_t))) {
1566 debugid |= DBG_FUNC_END;
1567 }
1568
d9a64523 1569 kernel_debug_internal(debugid, str_buf[0],
0a7de745
A
1570 str_buf[1],
1571 str_buf[2],
1572 str_buf[3], thread_id, 0);
39037602
A
1573
1574 debugid &= KDBG_EVENTID_MASK;
1575 int i = 4;
1576 size_t written = 4 * sizeof(uintptr_t);
1577
1578 for (; written < len; i += 4, written += 4 * sizeof(uintptr_t)) {
1579 /* if this is the last tracepoint to be emitted */
1580 if ((written + (4 * sizeof(uintptr_t))) >= len) {
1581 debugid |= DBG_FUNC_END;
1582 }
d9a64523 1583 kernel_debug_internal(debugid, str_buf[i],
0a7de745
A
1584 str_buf[i + 1],
1585 str_buf[i + 2],
1586 str_buf[i + 3], thread_id, 0);
39037602
A
1587 }
1588}
1589
0a7de745 1590extern int master_cpu; /* MACH_KERNEL_PRIVATE */
fe8ab488
A
1591/*
1592 * Used prior to start_kern_tracing() being called.
1593 * Log temporarily into a static buffer.
1594 */
1595void
1596kernel_debug_early(
0a7de745
A
1597 uint32_t debugid,
1598 uintptr_t arg1,
1599 uintptr_t arg2,
1600 uintptr_t arg3,
1601 uintptr_t arg4)
fe8ab488 1602{
0a7de745
A
1603#if defined(__x86_64__)
1604 extern int early_boot;
1605 /*
1606 * Note that "early" isn't early enough in some cases where
1607 * we're invoked before gsbase is set on x86, hence the
1608 * check of "early_boot".
1609 */
1610 if (early_boot) {
1611 return;
1612 }
1613#endif
1614
5ba3f43e
A
1615 /* If early tracing is over, use the normal path. */
1616 if (kd_early_done) {
fe8ab488 1617 KERNEL_DEBUG_CONSTANT(debugid, arg1, arg2, arg3, arg4, 0);
04b8595b
A
1618 return;
1619 }
fe8ab488 1620
5ba3f43e
A
1621 /* Do nothing if the buffer is full or we're not on the boot cpu. */
1622 kd_early_overflow = kd_early_index >= KD_EARLY_BUFFER_NBUFS;
1623 if (kd_early_overflow || cpu_number() != master_cpu) {
fe8ab488 1624 return;
5ba3f43e 1625 }
fe8ab488
A
1626
1627 kd_early_buffer[kd_early_index].debugid = debugid;
1628 kd_early_buffer[kd_early_index].timestamp = mach_absolute_time();
1629 kd_early_buffer[kd_early_index].arg1 = arg1;
1630 kd_early_buffer[kd_early_index].arg2 = arg2;
1631 kd_early_buffer[kd_early_index].arg3 = arg3;
1632 kd_early_buffer[kd_early_index].arg4 = arg4;
1633 kd_early_buffer[kd_early_index].arg5 = 0;
1634 kd_early_index++;
1635}
1636
1637/*
5ba3f43e 1638 * Transfer the contents of the temporary buffer into the trace buffers.
fe8ab488
A
1639 * Precede that by logging the rebase time (offset) - the TSC-based time (in ns)
1640 * when mach_absolute_time is set to 0.
1641 */
1642static void
1643kernel_debug_early_end(void)
1644{
5ba3f43e 1645 if (cpu_number() != master_cpu) {
fe8ab488 1646 panic("kernel_debug_early_end() not call on boot processor");
5ba3f43e 1647 }
fe8ab488 1648
5ba3f43e
A
1649 /* reset the current oldest time to allow early events */
1650 kd_ctrl_page.oldest_time = 0;
1651
1652#if !CONFIG_EMBEDDED
fe8ab488 1653 /* Fake sentinel marking the start of kernel time relative to TSC */
5ba3f43e 1654 kernel_debug_enter(0,
0a7de745
A
1655 TRACE_TIMESTAMPS,
1656 0,
1657 (uint32_t)(tsc_rebase_abs_time >> 32),
1658 (uint32_t)tsc_rebase_abs_time,
1659 tsc_at_boot,
1660 0,
1661 0);
5ba3f43e
A
1662#endif
1663 for (unsigned int i = 0; i < kd_early_index; i++) {
1664 kernel_debug_enter(0,
0a7de745
A
1665 kd_early_buffer[i].debugid,
1666 kd_early_buffer[i].timestamp,
1667 kd_early_buffer[i].arg1,
1668 kd_early_buffer[i].arg2,
1669 kd_early_buffer[i].arg3,
1670 kd_early_buffer[i].arg4,
1671 0);
fe8ab488
A
1672 }
1673
1674 /* Cut events-lost event on overflow */
5ba3f43e
A
1675 if (kd_early_overflow) {
1676 KDBG_RELEASE(TRACE_LOST_EVENTS, 1);
1677 }
1678
1679 kd_early_done = true;
fe8ab488
A
1680
1681 /* This trace marks the start of kernel tracing */
39037602
A
1682 kernel_debug_string_early("early trace done");
1683}
1684
1685void
1686kernel_debug_disable(void)
1687{
1688 if (kdebug_enable) {
cb323159 1689 kdbg_set_tracing_enabled(false, 0);
39037602 1690 }
3e170ce0
A
1691}
1692
1693/*
1694 * Returns non-zero if debugid is in a reserved class.
1695 */
1696static int
1697kdebug_validate_debugid(uint32_t debugid)
1698{
1699 uint8_t debugid_class;
1700
1701 debugid_class = KDBG_EXTRACT_CLASS(debugid);
1702 switch (debugid_class) {
0a7de745
A
1703 case DBG_TRACE:
1704 return EPERM;
3e170ce0
A
1705 }
1706
1707 return 0;
0c530ab8 1708}
6601e61a 1709
39037602
A
1710/*
1711 * Support syscall SYS_kdebug_typefilter.
1712 */
1713int
1714kdebug_typefilter(__unused struct proc* p,
0a7de745
A
1715 struct kdebug_typefilter_args* uap,
1716 __unused int *retval)
39037602
A
1717{
1718 int ret = KERN_SUCCESS;
1719
1720 if (uap->addr == USER_ADDR_NULL ||
1721 uap->size == USER_ADDR_NULL) {
1722 return EINVAL;
1723 }
1724
1725 /*
1726 * The atomic load is to close a race window with setting the typefilter
1727 * and memory entry values. A description follows:
1728 *
1729 * Thread 1 (writer)
1730 *
1731 * Allocate Typefilter
1732 * Allocate MemoryEntry
1733 * Write Global MemoryEntry Ptr
1734 * Atomic Store (Release) Global Typefilter Ptr
1735 *
1736 * Thread 2 (reader, AKA us)
1737 *
1738 * if ((Atomic Load (Acquire) Global Typefilter Ptr) == NULL)
1739 * return;
1740 *
1741 * Without the atomic store, it isn't guaranteed that the write of
1742 * Global MemoryEntry Ptr is visible before we can see the write of
1743 * Global Typefilter Ptr.
1744 *
1745 * Without the atomic load, it isn't guaranteed that the loads of
1746 * Global MemoryEntry Ptr aren't speculated.
1747 *
1748 * The global pointers transition from NULL -> valid once and only once,
1749 * and never change after becoming valid. This means that having passed
1750 * the first atomic load test of Global Typefilter Ptr, this function
1751 * can then safely use the remaining global state without atomic checks.
1752 */
cb323159 1753 if (!os_atomic_load(&kdbg_typefilter, acquire)) {
39037602
A
1754 return EINVAL;
1755 }
1756
1757 assert(kdbg_typefilter_memory_entry);
1758
1759 mach_vm_offset_t user_addr = 0;
1760 vm_map_t user_map = current_map();
1761
1762 ret = mach_to_bsd_errno(
0a7de745
A
1763 mach_vm_map_kernel(user_map, // target map
1764 &user_addr, // [in, out] target address
1765 TYPEFILTER_ALLOC_SIZE, // initial size
1766 0, // mask (alignment?)
1767 VM_FLAGS_ANYWHERE, // flags
1768 VM_MAP_KERNEL_FLAGS_NONE,
1769 VM_KERN_MEMORY_NONE,
1770 kdbg_typefilter_memory_entry, // port (memory entry!)
1771 0, // offset (in memory entry)
cb323159 1772 false, // should copy
0a7de745
A
1773 VM_PROT_READ, // cur_prot
1774 VM_PROT_READ, // max_prot
1775 VM_INHERIT_SHARE)); // inherit behavior on fork
39037602
A
1776
1777 if (ret == KERN_SUCCESS) {
1778 vm_size_t user_ptr_size = vm_map_is_64bit(user_map) ? 8 : 4;
1779 ret = copyout(CAST_DOWN(void *, &user_addr), uap->addr, user_ptr_size );
1780
1781 if (ret != KERN_SUCCESS) {
1782 mach_vm_deallocate(user_map, user_addr, TYPEFILTER_ALLOC_SIZE);
1783 }
1784 }
1785
1786 return ret;
1787}
1788
6d2010ae 1789/*
a1c7dba1 1790 * Support syscall SYS_kdebug_trace. U64->K32 args may get truncated in kdebug_trace64
6d2010ae
A
1791 */
1792int
a1c7dba1
A
1793kdebug_trace(struct proc *p, struct kdebug_trace_args *uap, int32_t *retval)
1794{
1795 struct kdebug_trace64_args uap64;
1796
1797 uap64.code = uap->code;
1798 uap64.arg1 = uap->arg1;
1799 uap64.arg2 = uap->arg2;
1800 uap64.arg3 = uap->arg3;
1801 uap64.arg4 = uap->arg4;
1802
1803 return kdebug_trace64(p, &uap64, retval);
1804}
1805
1806/*
39037602
A
1807 * Support syscall SYS_kdebug_trace64. 64-bit args on K32 will get truncated
1808 * to fit in 32-bit record format.
1809 *
1810 * It is intentional that error conditions are not checked until kdebug is
1811 * enabled. This is to match the userspace wrapper behavior, which is optimizing
1812 * for non-error case performance.
a1c7dba1 1813 */
0a7de745
A
1814int
1815kdebug_trace64(__unused struct proc *p, struct kdebug_trace64_args *uap, __unused int32_t *retval)
0c530ab8 1816{
3e170ce0 1817 int err;
a1c7dba1 1818
0a7de745
A
1819 if (__probable(kdebug_enable == 0)) {
1820 return 0;
1821 }
39037602 1822
3e170ce0
A
1823 if ((err = kdebug_validate_debugid(uap->code)) != 0) {
1824 return err;
a1c7dba1
A
1825 }
1826
d9a64523 1827 kernel_debug_internal(uap->code, (uintptr_t)uap->arg1,
0a7de745
A
1828 (uintptr_t)uap->arg2, (uintptr_t)uap->arg3, (uintptr_t)uap->arg4,
1829 (uintptr_t)thread_tid(current_thread()), 0);
91447636 1830
0a7de745 1831 return 0;
6d2010ae 1832}
1c79356b 1833
3e170ce0
A
1834/*
1835 * Adding enough padding to contain a full tracepoint for the last
1836 * portion of the string greatly simplifies the logic of splitting the
1837 * string between tracepoints. Full tracepoints can be generated using
1838 * the buffer itself, without having to manually add zeros to pad the
1839 * arguments.
1840 */
1841
1842/* 2 string args in first tracepoint and 9 string data tracepoints */
1843#define STR_BUF_ARGS (2 + (9 * 4))
1844/* times the size of each arg on K64 */
1845#define MAX_STR_LEN (STR_BUF_ARGS * sizeof(uint64_t))
1846/* on K32, ending straddles a tracepoint, so reserve blanks */
1847#define STR_BUF_SIZE (MAX_STR_LEN + (2 * sizeof(uint32_t)))
1848
1849/*
1850 * This function does no error checking and assumes that it is called with
1851 * the correct arguments, including that the buffer pointed to by str is at
1852 * least STR_BUF_SIZE bytes. However, str must be aligned to word-size and
1853 * be NUL-terminated. In cases where a string can fit evenly into a final
1854 * tracepoint without its NUL-terminator, this function will not end those
1855 * strings with a NUL in trace. It's up to clients to look at the function
1856 * qualifier for DBG_FUNC_END in this case, to end the string.
1857 */
1858static uint64_t
1859kernel_debug_string_internal(uint32_t debugid, uint64_t str_id, void *vstr,
0a7de745 1860 size_t str_len)
3e170ce0
A
1861{
1862 /* str must be word-aligned */
1863 uintptr_t *str = vstr;
1864 size_t written = 0;
1865 uintptr_t thread_id;
1866 int i;
1867 uint32_t trace_debugid = TRACEDBG_CODE(DBG_TRACE_STRING,
0a7de745 1868 TRACE_STRING_GLOBAL);
3e170ce0
A
1869
1870 thread_id = (uintptr_t)thread_tid(current_thread());
1871
1872 /* if the ID is being invalidated, just emit that */
1873 if (str_id != 0 && str_len == 0) {
d9a64523 1874 kernel_debug_internal(trace_debugid | DBG_FUNC_START | DBG_FUNC_END,
0a7de745 1875 (uintptr_t)debugid, (uintptr_t)str_id, 0, 0, thread_id, 0);
3e170ce0
A
1876 return str_id;
1877 }
1878
1879 /* generate an ID, if necessary */
1880 if (str_id == 0) {
1881 str_id = OSIncrementAtomic64((SInt64 *)&g_curr_str_id);
1882 str_id = (str_id & STR_ID_MASK) | g_str_id_signature;
1883 }
1884
1885 trace_debugid |= DBG_FUNC_START;
1886 /* string can fit in a single tracepoint */
1887 if (str_len <= (2 * sizeof(uintptr_t))) {
1888 trace_debugid |= DBG_FUNC_END;
1889 }
1890
d9a64523 1891 kernel_debug_internal(trace_debugid, (uintptr_t)debugid, (uintptr_t)str_id,
0a7de745 1892 str[0], str[1], thread_id, 0);
3e170ce0
A
1893
1894 trace_debugid &= KDBG_EVENTID_MASK;
1895 i = 2;
1896 written += 2 * sizeof(uintptr_t);
1897
1898 for (; written < str_len; i += 4, written += 4 * sizeof(uintptr_t)) {
1899 if ((written + (4 * sizeof(uintptr_t))) >= str_len) {
1900 trace_debugid |= DBG_FUNC_END;
1901 }
d9a64523 1902 kernel_debug_internal(trace_debugid, str[i],
0a7de745
A
1903 str[i + 1],
1904 str[i + 2],
1905 str[i + 3], thread_id, 0);
3e170ce0
A
1906 }
1907
1908 return str_id;
1909}
1910
1911/*
1912 * Returns true if the current process can emit events, and false otherwise.
1913 * Trace system and scheduling events circumvent this check, as do events
1914 * emitted in interrupt context.
1915 */
cb323159 1916static bool
3e170ce0
A
1917kdebug_current_proc_enabled(uint32_t debugid)
1918{
1919 /* can't determine current process in interrupt context */
1920 if (ml_at_interrupt_context()) {
cb323159 1921 return true;
3e170ce0
A
1922 }
1923
1924 /* always emit trace system and scheduling events */
1925 if ((KDBG_EXTRACT_CLASS(debugid) == DBG_TRACE ||
0a7de745 1926 (debugid & KDBG_CSC_MASK) == MACHDBG_CODE(DBG_MACH_SCHED, 0))) {
cb323159 1927 return true;
3e170ce0
A
1928 }
1929
1930 if (kd_ctrl_page.kdebug_flags & KDBG_PIDCHECK) {
1931 proc_t cur_proc = current_proc();
1932
1933 /* only the process with the kdebug bit set is allowed */
1934 if (cur_proc && !(cur_proc->p_kdebug)) {
cb323159 1935 return false;
3e170ce0
A
1936 }
1937 } else if (kd_ctrl_page.kdebug_flags & KDBG_PIDEXCLUDE) {
1938 proc_t cur_proc = current_proc();
1939
1940 /* every process except the one with the kdebug bit set is allowed */
1941 if (cur_proc && cur_proc->p_kdebug) {
cb323159 1942 return false;
3e170ce0
A
1943 }
1944 }
1945
cb323159 1946 return true;
3e170ce0
A
1947}
1948
cb323159 1949bool
3e170ce0
A
1950kdebug_debugid_enabled(uint32_t debugid)
1951{
3e170ce0
A
1952 /* if no filtering is enabled */
1953 if (!kd_ctrl_page.kdebug_slowcheck) {
cb323159 1954 return true;
3e170ce0
A
1955 }
1956
5ba3f43e
A
1957 return kdebug_debugid_explicitly_enabled(debugid);
1958}
1959
cb323159 1960bool
5ba3f43e
A
1961kdebug_debugid_explicitly_enabled(uint32_t debugid)
1962{
39037602
A
1963 if (kd_ctrl_page.kdebug_flags & KDBG_TYPEFILTER_CHECK) {
1964 return typefilter_is_debugid_allowed(kdbg_typefilter, debugid);
1965 } else if (KDBG_EXTRACT_CLASS(debugid) == DBG_TRACE) {
cb323159 1966 return true;
5ba3f43e 1967 } else if (kd_ctrl_page.kdebug_flags & KDBG_RANGECHECK) {
3e170ce0 1968 if (debugid < kdlog_beg || debugid > kdlog_end) {
cb323159 1969 return false;
3e170ce0
A
1970 }
1971 } else if (kd_ctrl_page.kdebug_flags & KDBG_VALCHECK) {
1972 if ((debugid & KDBG_EVENTID_MASK) != kdlog_value1 &&
0a7de745
A
1973 (debugid & KDBG_EVENTID_MASK) != kdlog_value2 &&
1974 (debugid & KDBG_EVENTID_MASK) != kdlog_value3 &&
1975 (debugid & KDBG_EVENTID_MASK) != kdlog_value4) {
cb323159 1976 return false;
3e170ce0
A
1977 }
1978 }
1979
cb323159
A
1980 return true;
1981}
1982
1983bool
1984kdebug_using_continuous_time(void)
1985{
1986 return kdebug_enable & KDEBUG_ENABLE_CONT_TIME;
3e170ce0
A
1987}
1988
1989/*
1990 * Returns 0 if a string can be traced with these arguments. Returns errno
1991 * value if error occurred.
1992 */
1993static errno_t
1994kdebug_check_trace_string(uint32_t debugid, uint64_t str_id)
1995{
1996 /* if there are function qualifiers on the debugid */
1997 if (debugid & ~KDBG_EVENTID_MASK) {
1998 return EINVAL;
1999 }
2000
2001 if (kdebug_validate_debugid(debugid)) {
2002 return EPERM;
2003 }
2004
2005 if (str_id != 0 && (str_id & STR_ID_SIG_MASK) != g_str_id_signature) {
2006 return EINVAL;
2007 }
2008
2009 return 0;
2010}
2011
2012/*
2013 * Implementation of KPI kernel_debug_string.
2014 */
2015int
2016kernel_debug_string(uint32_t debugid, uint64_t *str_id, const char *str)
2017{
2018 /* arguments to tracepoints must be word-aligned */
2019 __attribute__((aligned(sizeof(uintptr_t)))) char str_buf[STR_BUF_SIZE];
39037602 2020 static_assert(sizeof(str_buf) > MAX_STR_LEN);
3e170ce0
A
2021 vm_size_t len_copied;
2022 int err;
2023
2024 assert(str_id);
2025
2026 if (__probable(kdebug_enable == 0)) {
2027 return 0;
2028 }
2029
2030 if (!kdebug_current_proc_enabled(debugid)) {
2031 return 0;
2032 }
2033
2034 if (!kdebug_debugid_enabled(debugid)) {
2035 return 0;
2036 }
2037
2038 if ((err = kdebug_check_trace_string(debugid, *str_id)) != 0) {
2039 return err;
2040 }
2041
2042 if (str == NULL) {
2043 if (str_id == 0) {
2044 return EINVAL;
2045 }
2046
2047 *str_id = kernel_debug_string_internal(debugid, *str_id, NULL, 0);
2048 return 0;
2049 }
2050
2051 memset(str_buf, 0, sizeof(str_buf));
2052 len_copied = strlcpy(str_buf, str, MAX_STR_LEN + 1);
2053 *str_id = kernel_debug_string_internal(debugid, *str_id, str_buf,
0a7de745 2054 len_copied);
3e170ce0
A
2055 return 0;
2056}
2057
2058/*
2059 * Support syscall kdebug_trace_string.
2060 */
2061int
2062kdebug_trace_string(__unused struct proc *p,
0a7de745
A
2063 struct kdebug_trace_string_args *uap,
2064 uint64_t *retval)
3e170ce0
A
2065{
2066 __attribute__((aligned(sizeof(uintptr_t)))) char str_buf[STR_BUF_SIZE];
39037602 2067 static_assert(sizeof(str_buf) > MAX_STR_LEN);
3e170ce0
A
2068 size_t len_copied;
2069 int err;
2070
2071 if (__probable(kdebug_enable == 0)) {
2072 return 0;
2073 }
2074
2075 if (!kdebug_current_proc_enabled(uap->debugid)) {
2076 return 0;
2077 }
2078
2079 if (!kdebug_debugid_enabled(uap->debugid)) {
2080 return 0;
2081 }
2082
2083 if ((err = kdebug_check_trace_string(uap->debugid, uap->str_id)) != 0) {
2084 return err;
2085 }
2086
2087 if (uap->str == USER_ADDR_NULL) {
2088 if (uap->str_id == 0) {
2089 return EINVAL;
2090 }
2091
2092 *retval = kernel_debug_string_internal(uap->debugid, uap->str_id,
0a7de745 2093 NULL, 0);
3e170ce0
A
2094 return 0;
2095 }
2096
2097 memset(str_buf, 0, sizeof(str_buf));
2098 err = copyinstr(uap->str, str_buf, MAX_STR_LEN + 1, &len_copied);
2099
2100 /* it's alright to truncate the string, so allow ENAMETOOLONG */
2101 if (err == ENAMETOOLONG) {
2102 str_buf[MAX_STR_LEN] = '\0';
2103 } else if (err) {
2104 return err;
2105 }
2106
2107 if (len_copied <= 1) {
2108 return EINVAL;
2109 }
2110
2111 /* convert back to a length */
2112 len_copied--;
2113
2114 *retval = kernel_debug_string_internal(uap->debugid, uap->str_id, str_buf,
0a7de745 2115 len_copied);
3e170ce0
A
2116 return 0;
2117}
2118
6d2010ae
A
2119static void
2120kdbg_lock_init(void)
2121{
39037602 2122 static lck_grp_attr_t *kdebug_lck_grp_attr = NULL;
39037602
A
2123 static lck_attr_t *kdebug_lck_attr = NULL;
2124
2125 if (kd_ctrl_page.kdebug_flags & KDBG_LOCKINIT) {
6d2010ae 2126 return;
39037602 2127 }
91447636 2128
39037602
A
2129 assert(kdebug_lck_grp_attr == NULL);
2130 kdebug_lck_grp_attr = lck_grp_attr_alloc_init();
2131 kdebug_lck_grp = lck_grp_alloc_init("kdebug", kdebug_lck_grp_attr);
2132 kdebug_lck_attr = lck_attr_alloc_init();
91447636 2133
39037602
A
2134 kds_spin_lock = lck_spin_alloc_init(kdebug_lck_grp, kdebug_lck_attr);
2135 kdw_spin_lock = lck_spin_alloc_init(kdebug_lck_grp, kdebug_lck_attr);
91447636 2136
6d2010ae 2137 kd_ctrl_page.kdebug_flags |= KDBG_LOCKINIT;
91447636
A
2138}
2139
91447636 2140int
cb323159 2141kdbg_bootstrap(bool early_trace)
1c79356b 2142{
39037602 2143 kd_ctrl_page.kdebug_flags &= ~KDBG_WRAPPED;
91447636 2144
0a7de745 2145 return create_buffers(early_trace);
1c79356b
A
2146}
2147
0c530ab8 2148int
cb323159 2149kdbg_reinit(bool early_trace)
1c79356b 2150{
b0d623f7 2151 int ret = 0;
91447636 2152
b0d623f7
A
2153 /*
2154 * Disable trace collecting
2155 * First make sure we're not in
2156 * the middle of cutting a trace
2157 */
39037602 2158 kernel_debug_disable();
1c79356b 2159
b0d623f7
A
2160 /*
2161 * make sure the SLOW_NOLOG is seen
2162 * by everyone that might be trying
2163 * to cut a trace..
2164 */
2165 IOSleep(100);
1c79356b 2166
b0d623f7 2167 delete_buffers();
1c79356b 2168
39037602 2169 kdbg_clear_thread_map();
6d2010ae
A
2170 ret = kdbg_bootstrap(early_trace);
2171
2172 RAW_file_offset = 0;
2173 RAW_file_written = 0;
1c79356b 2174
0a7de745 2175 return ret;
1c79356b
A
2176}
2177
0c530ab8 2178void
5ba3f43e 2179kdbg_trace_data(struct proc *proc, long *arg_pid, long *arg_uniqueid)
55e303ae 2180{
0a7de745 2181 if (!proc) {
b0d623f7 2182 *arg_pid = 0;
0a7de745
A
2183 *arg_uniqueid = 0;
2184 } else {
b0d623f7 2185 *arg_pid = proc->p_pid;
5ba3f43e 2186 *arg_uniqueid = proc->p_uniqueid;
0a7de745
A
2187 if ((uint64_t) *arg_uniqueid != proc->p_uniqueid) {
2188 *arg_uniqueid = 0;
5ba3f43e
A
2189 }
2190 }
55e303ae
A
2191}
2192
2193
0c530ab8 2194void
cb323159
A
2195kdbg_trace_string(struct proc *proc, long *arg1, long *arg2, long *arg3,
2196 long *arg4)
1c79356b 2197{
b0d623f7
A
2198 if (!proc) {
2199 *arg1 = 0;
2200 *arg2 = 0;
2201 *arg3 = 0;
2202 *arg4 = 0;
2203 return;
2204 }
0a7de745 2205
cb323159
A
2206 const char *procname = proc_best_name(proc);
2207 size_t namelen = strlen(procname);
2208
2209 long args[4] = { 0 };
2210
2211 if (namelen > sizeof(args)) {
2212 namelen = sizeof(args);
0a7de745
A
2213 }
2214
cb323159 2215 strncpy((char *)args, procname, namelen);
1c79356b 2216
cb323159
A
2217 *arg1 = args[0];
2218 *arg2 = args[1];
2219 *arg3 = args[2];
2220 *arg4 = args[3];
1c79356b
A
2221}
2222
91447636 2223static void
0c530ab8 2224kdbg_resolve_map(thread_t th_act, void *opaque)
1c79356b 2225{
b0d623f7
A
2226 kd_threadmap *mapptr;
2227 krt_t *t = (krt_t *)opaque;
2228
2229 if (t->count < t->maxcount) {
2230 mapptr = &t->map[t->count];
2231 mapptr->thread = (uintptr_t)thread_tid(th_act);
2232
0a7de745
A
2233 (void) strlcpy(mapptr->command, t->atts->task_comm,
2234 sizeof(t->atts->task_comm));
b0d623f7
A
2235 /*
2236 * Some kernel threads have no associated pid.
2237 * We still need to mark the entry as valid.
2238 */
0a7de745 2239 if (t->atts->pid) {
b0d623f7 2240 mapptr->valid = t->atts->pid;
0a7de745 2241 } else {
b0d623f7 2242 mapptr->valid = 1;
0a7de745 2243 }
b0d623f7
A
2244
2245 t->count++;
2246 }
1c79356b
A
2247}
2248
39236c6e
A
2249/*
2250 *
2251 * Writes a cpumap for the given iops_list/cpu_count to the provided buffer.
2252 *
2253 * You may provide a buffer and size, or if you set the buffer to NULL, a
2254 * buffer of sufficient size will be allocated.
2255 *
2256 * If you provide a buffer and it is too small, sets cpumap_size to the number
2257 * of bytes required and returns EINVAL.
2258 *
2259 * On success, if you provided a buffer, cpumap_size is set to the number of
2260 * bytes written. If you did not provide a buffer, cpumap is set to the newly
2261 * allocated buffer and cpumap_size is set to the number of bytes allocated.
2262 *
2263 * NOTE: It may seem redundant to pass both iops and a cpu_count.
2264 *
2265 * We may be reporting data from "now", or from the "past".
2266 *
39236c6e
A
2267 * The "past" data would be for kdbg_readcpumap().
2268 *
2269 * If we do not pass both iops and cpu_count, and iops is NULL, this function
2270 * will need to read "now" state to get the number of cpus, which would be in
2271 * error if we were reporting "past" state.
2272 */
2273
2274int
2275kdbg_cpumap_init_internal(kd_iop_t* iops, uint32_t cpu_count, uint8_t** cpumap, uint32_t* cpumap_size)
2276{
2277 assert(cpumap);
2278 assert(cpumap_size);
2279 assert(cpu_count);
2280 assert(!iops || iops->cpu_id + 1 == cpu_count);
2281
2282 uint32_t bytes_needed = sizeof(kd_cpumap_header) + cpu_count * sizeof(kd_cpumap);
2283 uint32_t bytes_available = *cpumap_size;
2284 *cpumap_size = bytes_needed;
0a7de745 2285
39236c6e 2286 if (*cpumap == NULL) {
3e170ce0 2287 if (kmem_alloc(kernel_map, (vm_offset_t*)cpumap, (vm_size_t)*cpumap_size, VM_KERN_MEMORY_DIAG) != KERN_SUCCESS) {
39236c6e
A
2288 return ENOMEM;
2289 }
39037602 2290 bzero(*cpumap, *cpumap_size);
39236c6e
A
2291 } else if (bytes_available < bytes_needed) {
2292 return EINVAL;
2293 }
2294
2295 kd_cpumap_header* header = (kd_cpumap_header*)(uintptr_t)*cpumap;
2296
2297 header->version_no = RAW_VERSION1;
2298 header->cpu_count = cpu_count;
2299
2300 kd_cpumap* cpus = (kd_cpumap*)&header[1];
2301
2302 int32_t index = cpu_count - 1;
2303 while (iops) {
2304 cpus[index].cpu_id = iops->cpu_id;
2305 cpus[index].flags = KDBG_CPUMAP_IS_IOP;
39236c6e 2306 strlcpy(cpus[index].name, iops->callback.iop_name, sizeof(cpus->name));
0a7de745 2307
39236c6e
A
2308 iops = iops->next;
2309 index--;
2310 }
0a7de745 2311
39236c6e
A
2312 while (index >= 0) {
2313 cpus[index].cpu_id = index;
2314 cpus[index].flags = 0;
39236c6e
A
2315 strlcpy(cpus[index].name, "AP", sizeof(cpus->name));
2316
2317 index--;
2318 }
0a7de745 2319
39236c6e
A
2320 return KERN_SUCCESS;
2321}
2322
0c530ab8 2323void
39236c6e 2324kdbg_thrmap_init(void)
1c79356b 2325{
5ba3f43e 2326 ktrace_assert_lock_held();
39037602
A
2327
2328 if (kd_ctrl_page.kdebug_flags & KDBG_MAPINIT) {
39236c6e 2329 return;
39037602 2330 }
39236c6e
A
2331
2332 kd_mapptr = kdbg_thrmap_init_internal(0, &kd_mapsize, &kd_mapcount);
2333
39037602 2334 if (kd_mapptr) {
39236c6e 2335 kd_ctrl_page.kdebug_flags |= KDBG_MAPINIT;
39037602 2336 }
39236c6e
A
2337}
2338
39037602
A
2339static kd_threadmap *
2340kdbg_thrmap_init_internal(unsigned int count, unsigned int *mapsize, unsigned int *mapcount)
39236c6e 2341{
39037602
A
2342 kd_threadmap *mapptr;
2343 proc_t p;
2344 struct krt akrt;
2345 int tts_count = 0; /* number of task-to-string structures */
2346 struct tts *tts_mapptr;
2347 unsigned int tts_mapsize = 0;
2348 vm_offset_t kaddr;
1c79356b 2349
39037602
A
2350 assert(mapsize != NULL);
2351 assert(mapcount != NULL);
2d21ac55 2352
39037602
A
2353 *mapcount = threads_count;
2354 tts_count = tasks_count;
2d21ac55 2355
9bccf70c
A
2356 /*
2357 * The proc count could change during buffer allocation,
2358 * so introduce a small fudge factor to bump up the
0a7de745 2359 * buffer sizes. This gives new tasks some chance of
39236c6e 2360 * making into the tables. Bump up by 25%.
9bccf70c 2361 */
39037602
A
2362 *mapcount += *mapcount / 4;
2363 tts_count += tts_count / 4;
39236c6e
A
2364
2365 *mapsize = *mapcount * sizeof(kd_threadmap);
9bccf70c 2366
39037602
A
2367 if (count && count < *mapcount) {
2368 return 0;
2369 }
b0d623f7 2370
3e170ce0 2371 if ((kmem_alloc(kernel_map, &kaddr, (vm_size_t)*mapsize, VM_KERN_MEMORY_DIAG) == KERN_SUCCESS)) {
39236c6e
A
2372 bzero((void *)kaddr, *mapsize);
2373 mapptr = (kd_threadmap *)kaddr;
39037602
A
2374 } else {
2375 return 0;
2376 }
1c79356b 2377
9bccf70c 2378 tts_mapsize = tts_count * sizeof(struct tts);
9bccf70c 2379
3e170ce0 2380 if ((kmem_alloc(kernel_map, &kaddr, (vm_size_t)tts_mapsize, VM_KERN_MEMORY_DIAG) == KERN_SUCCESS)) {
39236c6e
A
2381 bzero((void *)kaddr, tts_mapsize);
2382 tts_mapptr = (struct tts *)kaddr;
2383 } else {
2384 kmem_free(kernel_map, (vm_offset_t)mapptr, *mapsize);
9bccf70c 2385
39037602 2386 return 0;
39236c6e 2387 }
39236c6e
A
2388
2389 /*
39037602
A
2390 * Save the proc's name and take a reference for each task associated
2391 * with a valid process.
39236c6e 2392 */
39037602 2393 proc_list_lock();
39236c6e 2394
39037602
A
2395 int i = 0;
2396 ALLPROC_FOREACH(p) {
2397 if (i >= tts_count) {
2398 break;
2399 }
2400 if (p->p_lflag & P_LEXIT) {
2401 continue;
2402 }
39236c6e
A
2403 if (p->task) {
2404 task_reference(p->task);
2405 tts_mapptr[i].task = p->task;
39037602
A
2406 tts_mapptr[i].pid = p->p_pid;
2407 (void)strlcpy(tts_mapptr[i].task_comm, proc_best_name(p), sizeof(tts_mapptr[i].task_comm));
39236c6e
A
2408 i++;
2409 }
9bccf70c 2410 }
39236c6e 2411 tts_count = i;
9bccf70c 2412
39236c6e 2413 proc_list_unlock();
9bccf70c 2414
39236c6e
A
2415 /*
2416 * Initialize thread map data
2417 */
2418 akrt.map = mapptr;
2419 akrt.count = 0;
2420 akrt.maxcount = *mapcount;
39037602 2421
39236c6e
A
2422 for (i = 0; i < tts_count; i++) {
2423 akrt.atts = &tts_mapptr[i];
2424 task_act_iterate_wth_args(tts_mapptr[i].task, kdbg_resolve_map, &akrt);
39037602 2425 task_deallocate((task_t)tts_mapptr[i].task);
b0d623f7 2426 }
39236c6e
A
2427 kmem_free(kernel_map, (vm_offset_t)tts_mapptr, tts_mapsize);
2428
2429 *mapcount = akrt.count;
2430
39037602 2431 return mapptr;
1c79356b
A
2432}
2433
91447636
A
2434static void
2435kdbg_clear(void)
1c79356b 2436{
3e170ce0 2437 /*
91447636
A
2438 * Clean up the trace buffer
2439 * First make sure we're not in
2440 * the middle of cutting a trace
2441 */
39037602 2442 kernel_debug_disable();
3e170ce0 2443 kdbg_disable_typefilter();
91447636 2444
0c530ab8
A
2445 /*
2446 * make sure the SLOW_NOLOG is seen
2447 * by everyone that might be trying
2448 * to cut a trace..
2449 */
2450 IOSleep(100);
2451
39037602
A
2452 /* reset kdebug state for each process */
2453 if (kd_ctrl_page.kdebug_flags & (KDBG_PIDCHECK | KDBG_PIDEXCLUDE)) {
2454 proc_list_lock();
2455 proc_t p;
2456 ALLPROC_FOREACH(p) {
2457 p->p_kdebug = 0;
2458 }
2459 proc_list_unlock();
2460 }
2461
6d2010ae
A
2462 kd_ctrl_page.kdebug_flags &= (unsigned int)~KDBG_CKTYPES;
2463 kd_ctrl_page.kdebug_flags &= ~(KDBG_NOWRAP | KDBG_RANGECHECK | KDBG_VALCHECK);
2464 kd_ctrl_page.kdebug_flags &= ~(KDBG_PIDCHECK | KDBG_PIDEXCLUDE);
39037602
A
2465
2466 kd_ctrl_page.oldest_time = 0;
2467
0c530ab8 2468 delete_buffers();
5ba3f43e 2469 nkdbufs = 0;
1c79356b
A
2470
2471 /* Clean up the thread map buffer */
39037602 2472 kdbg_clear_thread_map();
6d2010ae
A
2473
2474 RAW_file_offset = 0;
2475 RAW_file_written = 0;
1c79356b
A
2476}
2477
39037602
A
2478void
2479kdebug_reset(void)
2480{
5ba3f43e 2481 ktrace_assert_lock_held();
39037602
A
2482
2483 kdbg_lock_init();
2484
2485 kdbg_clear();
2486 if (kdbg_typefilter) {
2487 typefilter_reject_all(kdbg_typefilter);
2488 typefilter_allow_class(kdbg_typefilter, DBG_TRACE);
2489 }
2490}
2491
5ba3f43e
A
2492void
2493kdebug_free_early_buf(void)
2494{
d9a64523
A
2495#if !CONFIG_EMBEDDED
2496 /* Must be done with the buffer, so release it back to the VM.
2497 * On embedded targets this buffer is freed when the BOOTDATA segment is freed. */
5ba3f43e 2498 ml_static_mfree((vm_offset_t)&kd_early_buffer, sizeof(kd_early_buffer));
d9a64523 2499#endif
5ba3f43e
A
2500}
2501
0c530ab8 2502int
1c79356b
A
2503kdbg_setpid(kd_regtype *kdr)
2504{
b0d623f7 2505 pid_t pid;
0a7de745 2506 int flag, ret = 0;
b0d623f7
A
2507 struct proc *p;
2508
2509 pid = (pid_t)kdr->value1;
2510 flag = (int)kdr->value2;
2511
39037602 2512 if (pid >= 0) {
0a7de745 2513 if ((p = proc_find(pid)) == NULL) {
b0d623f7 2514 ret = ESRCH;
0a7de745 2515 } else {
b0d623f7
A
2516 if (flag == 1) {
2517 /*
2518 * turn on pid check for this and all pids
2519 */
6d2010ae
A
2520 kd_ctrl_page.kdebug_flags |= KDBG_PIDCHECK;
2521 kd_ctrl_page.kdebug_flags &= ~KDBG_PIDEXCLUDE;
cb323159 2522 kdbg_set_flags(SLOW_CHECKS, 0, true);
6d2010ae 2523
b0d623f7
A
2524 p->p_kdebug = 1;
2525 } else {
2526 /*
2527 * turn off pid check for this pid value
2528 * Don't turn off all pid checking though
2529 *
6d2010ae 2530 * kd_ctrl_page.kdebug_flags &= ~KDBG_PIDCHECK;
0a7de745 2531 */
b0d623f7
A
2532 p->p_kdebug = 0;
2533 }
2534 proc_rele(p);
2535 }
0a7de745 2536 } else {
b0d623f7 2537 ret = EINVAL;
0a7de745 2538 }
b0d623f7 2539
0a7de745 2540 return ret;
1c79356b
A
2541}
2542
2543/* This is for pid exclusion in the trace buffer */
0c530ab8 2544int
1c79356b
A
2545kdbg_setpidex(kd_regtype *kdr)
2546{
b0d623f7 2547 pid_t pid;
0a7de745 2548 int flag, ret = 0;
b0d623f7
A
2549 struct proc *p;
2550
2551 pid = (pid_t)kdr->value1;
2552 flag = (int)kdr->value2;
2553
39037602 2554 if (pid >= 0) {
0a7de745 2555 if ((p = proc_find(pid)) == NULL) {
b0d623f7 2556 ret = ESRCH;
0a7de745 2557 } else {
b0d623f7
A
2558 if (flag == 1) {
2559 /*
2560 * turn on pid exclusion
2561 */
6d2010ae
A
2562 kd_ctrl_page.kdebug_flags |= KDBG_PIDEXCLUDE;
2563 kd_ctrl_page.kdebug_flags &= ~KDBG_PIDCHECK;
cb323159 2564 kdbg_set_flags(SLOW_CHECKS, 0, true);
b0d623f7
A
2565
2566 p->p_kdebug = 1;
0a7de745 2567 } else {
b0d623f7
A
2568 /*
2569 * turn off pid exclusion for this pid value
2570 * Don't turn off all pid exclusion though
2571 *
6d2010ae 2572 * kd_ctrl_page.kdebug_flags &= ~KDBG_PIDEXCLUDE;
0a7de745 2573 */
b0d623f7
A
2574 p->p_kdebug = 0;
2575 }
2576 proc_rele(p);
2577 }
0a7de745 2578 } else {
b0d623f7 2579 ret = EINVAL;
0a7de745 2580 }
b0d623f7 2581
0a7de745 2582 return ret;
1c79356b
A
2583}
2584
39037602
A
2585/*
2586 * The following functions all operate on the "global" typefilter singleton.
2587 */
b0d623f7
A
2588
2589/*
39037602
A
2590 * The tf param is optional, you may pass either a valid typefilter or NULL.
2591 * If you pass a valid typefilter, you release ownership of that typefilter.
b0d623f7 2592 */
39037602
A
2593static int
2594kdbg_initialize_typefilter(typefilter_t tf)
1c79356b 2595{
5ba3f43e 2596 ktrace_assert_lock_held();
39037602
A
2597 assert(!kdbg_typefilter);
2598 assert(!kdbg_typefilter_memory_entry);
2599 typefilter_t deallocate_tf = NULL;
1c79356b 2600
39037602
A
2601 if (!tf && ((tf = deallocate_tf = typefilter_create()) == NULL)) {
2602 return ENOMEM;
2603 }
1c79356b 2604
39037602
A
2605 if ((kdbg_typefilter_memory_entry = typefilter_create_memory_entry(tf)) == MACH_PORT_NULL) {
2606 if (deallocate_tf) {
2607 typefilter_deallocate(deallocate_tf);
2608 }
2609 return ENOMEM;
2610 }
1c79356b 2611
39037602
A
2612 /*
2613 * The atomic store closes a race window with
2614 * the kdebug_typefilter syscall, which assumes
2615 * that any non-null kdbg_typefilter means a
2616 * valid memory_entry is available.
2617 */
cb323159 2618 os_atomic_store(&kdbg_typefilter, tf, release);
39037602
A
2619
2620 return KERN_SUCCESS;
1c79356b
A
2621}
2622
39037602
A
2623static int
2624kdbg_copyin_typefilter(user_addr_t addr, size_t size)
316670eb 2625{
39037602
A
2626 int ret = ENOMEM;
2627 typefilter_t tf;
3e170ce0 2628
5ba3f43e 2629 ktrace_assert_lock_held();
39037602
A
2630
2631 if (size != KDBG_TYPEFILTER_BITMAP_SIZE) {
2632 return EINVAL;
2633 }
2634
2635 if ((tf = typefilter_create())) {
2636 if ((ret = copyin(addr, tf, KDBG_TYPEFILTER_BITMAP_SIZE)) == 0) {
2637 /* The kernel typefilter must always allow DBG_TRACE */
2638 typefilter_allow_class(tf, DBG_TRACE);
2639
2640 /*
2641 * If this is the first typefilter; claim it.
2642 * Otherwise copy and deallocate.
2643 *
2644 * Allocating a typefilter for the copyin allows
2645 * the kernel to hold the invariant that DBG_TRACE
0a7de745 2646 * must always be allowed.
39037602
A
2647 */
2648 if (!kdbg_typefilter) {
2649 if ((ret = kdbg_initialize_typefilter(tf))) {
2650 return ret;
2651 }
2652 tf = NULL;
2653 } else {
2654 typefilter_copy(kdbg_typefilter, tf);
2655 }
2656
2657 kdbg_enable_typefilter();
2658 kdbg_iop_list_callback(kd_ctrl_page.kdebug_iops, KD_CALLBACK_TYPEFILTER_CHANGED, kdbg_typefilter);
2659 }
2660
0a7de745 2661 if (tf) {
39037602 2662 typefilter_deallocate(tf);
0a7de745 2663 }
316670eb 2664 }
316670eb 2665
39037602
A
2666 return ret;
2667}
2668
2669/*
2670 * Enable the flags in the control page for the typefilter. Assumes that
2671 * kdbg_typefilter has already been allocated, so events being written
2672 * don't see a bad typefilter.
2673 */
2674static void
2675kdbg_enable_typefilter(void)
2676{
2677 assert(kdbg_typefilter);
316670eb 2678 kd_ctrl_page.kdebug_flags &= ~(KDBG_RANGECHECK | KDBG_VALCHECK);
316670eb 2679 kd_ctrl_page.kdebug_flags |= KDBG_TYPEFILTER_CHECK;
cb323159 2680 kdbg_set_flags(SLOW_CHECKS, 0, true);
39037602 2681 commpage_update_kdebug_state();
316670eb
A
2682}
2683
39037602
A
2684/*
2685 * Disable the flags in the control page for the typefilter. The typefilter
2686 * may be safely deallocated shortly after this function returns.
2687 */
2688static void
316670eb
A
2689kdbg_disable_typefilter(void)
2690{
d9a64523 2691 bool notify_iops = kd_ctrl_page.kdebug_flags & KDBG_TYPEFILTER_CHECK;
316670eb 2692 kd_ctrl_page.kdebug_flags &= ~KDBG_TYPEFILTER_CHECK;
3e170ce0 2693
39037602 2694 if ((kd_ctrl_page.kdebug_flags & (KDBG_PIDCHECK | KDBG_PIDEXCLUDE))) {
cb323159 2695 kdbg_set_flags(SLOW_CHECKS, 0, true);
3e170ce0 2696 } else {
cb323159 2697 kdbg_set_flags(SLOW_CHECKS, 0, false);
3e170ce0 2698 }
39037602 2699 commpage_update_kdebug_state();
d9a64523
A
2700
2701 if (notify_iops) {
2702 /*
2703 * Notify IOPs that the typefilter will now allow everything.
2704 * Otherwise, they won't know a typefilter is no longer in
2705 * effect.
2706 */
2707 typefilter_allow_all(kdbg_typefilter);
2708 kdbg_iop_list_callback(kd_ctrl_page.kdebug_iops,
0a7de745 2709 KD_CALLBACK_TYPEFILTER_CHANGED, kdbg_typefilter);
d9a64523 2710 }
3e170ce0
A
2711}
2712
39037602
A
2713uint32_t
2714kdebug_commpage_state(void)
3e170ce0 2715{
39037602
A
2716 if (kdebug_enable) {
2717 if (kd_ctrl_page.kdebug_flags & KDBG_TYPEFILTER_CHECK) {
2718 return KDEBUG_COMMPAGE_ENABLE_TYPEFILTER | KDEBUG_COMMPAGE_ENABLE_TRACE;
3e170ce0 2719 }
39037602
A
2720
2721 return KDEBUG_COMMPAGE_ENABLE_TRACE;
3e170ce0 2722 }
316670eb 2723
316670eb
A
2724 return 0;
2725}
2726
0c530ab8 2727int
1c79356b
A
2728kdbg_setreg(kd_regtype * kdr)
2729{
0a7de745 2730 int ret = 0;
1c79356b
A
2731 unsigned int val_1, val_2, val;
2732 switch (kdr->type) {
0a7de745 2733 case KDBG_CLASSTYPE:
1c79356b
A
2734 val_1 = (kdr->value1 & 0xff);
2735 val_2 = (kdr->value2 & 0xff);
0a7de745
A
2736 kdlog_beg = (val_1 << 24);
2737 kdlog_end = (val_2 << 24);
6d2010ae
A
2738 kd_ctrl_page.kdebug_flags &= (unsigned int)~KDBG_CKTYPES;
2739 kd_ctrl_page.kdebug_flags &= ~KDBG_VALCHECK; /* Turn off specific value check */
2740 kd_ctrl_page.kdebug_flags |= (KDBG_RANGECHECK | KDBG_CLASSTYPE);
cb323159 2741 kdbg_set_flags(SLOW_CHECKS, 0, true);
1c79356b 2742 break;
0a7de745 2743 case KDBG_SUBCLSTYPE:
1c79356b
A
2744 val_1 = (kdr->value1 & 0xff);
2745 val_2 = (kdr->value2 & 0xff);
2746 val = val_2 + 1;
0a7de745
A
2747 kdlog_beg = ((val_1 << 24) | (val_2 << 16));
2748 kdlog_end = ((val_1 << 24) | (val << 16));
6d2010ae
A
2749 kd_ctrl_page.kdebug_flags &= (unsigned int)~KDBG_CKTYPES;
2750 kd_ctrl_page.kdebug_flags &= ~KDBG_VALCHECK; /* Turn off specific value check */
2751 kd_ctrl_page.kdebug_flags |= (KDBG_RANGECHECK | KDBG_SUBCLSTYPE);
cb323159 2752 kdbg_set_flags(SLOW_CHECKS, 0, true);
1c79356b 2753 break;
0a7de745 2754 case KDBG_RANGETYPE:
1c79356b
A
2755 kdlog_beg = (kdr->value1);
2756 kdlog_end = (kdr->value2);
6d2010ae
A
2757 kd_ctrl_page.kdebug_flags &= (unsigned int)~KDBG_CKTYPES;
2758 kd_ctrl_page.kdebug_flags &= ~KDBG_VALCHECK; /* Turn off specific value check */
2759 kd_ctrl_page.kdebug_flags |= (KDBG_RANGECHECK | KDBG_RANGETYPE);
cb323159 2760 kdbg_set_flags(SLOW_CHECKS, 0, true);
1c79356b
A
2761 break;
2762 case KDBG_VALCHECK:
2763 kdlog_value1 = (kdr->value1);
2764 kdlog_value2 = (kdr->value2);
2765 kdlog_value3 = (kdr->value3);
2766 kdlog_value4 = (kdr->value4);
6d2010ae
A
2767 kd_ctrl_page.kdebug_flags &= (unsigned int)~KDBG_CKTYPES;
2768 kd_ctrl_page.kdebug_flags &= ~KDBG_RANGECHECK; /* Turn off range check */
2769 kd_ctrl_page.kdebug_flags |= KDBG_VALCHECK; /* Turn on specific value check */
cb323159 2770 kdbg_set_flags(SLOW_CHECKS, 0, true);
1c79356b 2771 break;
0a7de745 2772 case KDBG_TYPENONE:
6d2010ae 2773 kd_ctrl_page.kdebug_flags &= (unsigned int)~KDBG_CKTYPES;
91447636 2774
0a7de745
A
2775 if ((kd_ctrl_page.kdebug_flags & (KDBG_RANGECHECK | KDBG_VALCHECK |
2776 KDBG_PIDCHECK | KDBG_PIDEXCLUDE |
2777 KDBG_TYPEFILTER_CHECK))) {
cb323159 2778 kdbg_set_flags(SLOW_CHECKS, 0, true);
0a7de745 2779 } else {
cb323159 2780 kdbg_set_flags(SLOW_CHECKS, 0, false);
0a7de745 2781 }
91447636 2782
1c79356b
A
2783 kdlog_beg = 0;
2784 kdlog_end = 0;
2785 break;
0a7de745 2786 default:
1c79356b
A
2787 ret = EINVAL;
2788 break;
2789 }
0a7de745 2790 return ret;
1c79356b
A
2791}
2792
3e170ce0
A
2793static int
2794kdbg_write_to_vnode(caddr_t buffer, size_t size, vnode_t vp, vfs_context_t ctx, off_t file_offset)
2795{
0a7de745
A
2796 return vn_rdwr(UIO_WRITE, vp, buffer, size, file_offset, UIO_SYSSPACE, IO_NODELOCKED | IO_UNIT,
2797 vfs_context_ucred(ctx), (int *) 0, vfs_context_proc(ctx));
3e170ce0
A
2798}
2799
39236c6e 2800int
3e170ce0 2801kdbg_write_v3_chunk_header(user_addr_t buffer, uint32_t tag, uint32_t sub_tag, uint64_t length, vnode_t vp, vfs_context_t ctx)
39236c6e 2802{
39236c6e 2803 int ret = KERN_SUCCESS;
39037602
A
2804 kd_chunk_header_v3 header = {
2805 .tag = tag,
2806 .sub_tag = sub_tag,
2807 .length = length,
2808 };
3e170ce0
A
2809
2810 // Check that only one of them is valid
2811 assert(!buffer ^ !vp);
2812 assert((vp == NULL) || (ctx != NULL));
2813
2814 // Write the 8-byte future_chunk_timestamp field in the payload
2815 if (buffer || vp) {
2816 if (vp) {
2817 ret = kdbg_write_to_vnode((caddr_t)&header, sizeof(kd_chunk_header_v3), vp, ctx, RAW_file_offset);
2818 if (ret) {
2819 goto write_error;
39236c6e 2820 }
3e170ce0 2821 RAW_file_offset += (sizeof(kd_chunk_header_v3));
0a7de745 2822 } else {
3e170ce0
A
2823 ret = copyout(&header, buffer, sizeof(kd_chunk_header_v3));
2824 if (ret) {
2825 goto write_error;
2826 }
2827 }
2828 }
2829write_error:
2830 return ret;
39236c6e
A
2831}
2832
cb323159 2833static int
3e170ce0
A
2834kdbg_write_v3_chunk_to_fd(uint32_t tag, uint32_t sub_tag, uint64_t length, void *payload, uint64_t payload_size, int fd)
2835{
2836 proc_t p;
2837 struct vfs_context context;
2838 struct fileproc *fp;
2839 vnode_t vp;
2840 p = current_proc();
2841
2842 proc_fdlock(p);
0a7de745 2843 if ((fp_lookup(p, fd, &fp, 1))) {
3e170ce0
A
2844 proc_fdunlock(p);
2845 return EFAULT;
2846 }
2847
2848 context.vc_thread = current_thread();
2849 context.vc_ucred = fp->f_fglob->fg_cred;
2850
2851 if (FILEGLOB_DTYPE(fp->f_fglob) != DTYPE_VNODE) {
2852 fp_drop(p, fd, fp, 1);
2853 proc_fdunlock(p);
2854 return EBADF;
2855 }
2856 vp = (struct vnode *) fp->f_fglob->fg_data;
2857 proc_fdunlock(p);
2858
0a7de745 2859 if ((vnode_getwithref(vp)) == 0) {
3e170ce0
A
2860 RAW_file_offset = fp->f_fglob->fg_offset;
2861
39037602
A
2862 kd_chunk_header_v3 chunk_header = {
2863 .tag = tag,
2864 .sub_tag = sub_tag,
2865 .length = length,
2866 };
3e170ce0
A
2867
2868 int ret = kdbg_write_to_vnode((caddr_t) &chunk_header, sizeof(kd_chunk_header_v3), vp, &context, RAW_file_offset);
2869 if (!ret) {
2870 RAW_file_offset += sizeof(kd_chunk_header_v3);
2871 }
2872
2873 ret = kdbg_write_to_vnode((caddr_t) payload, (size_t) payload_size, vp, &context, RAW_file_offset);
2874 if (!ret) {
2875 RAW_file_offset += payload_size;
2876 }
2877
2878 fp->f_fglob->fg_offset = RAW_file_offset;
2879 vnode_put(vp);
2880 }
2881
2882 fp_drop(p, fd, fp, 0);
2883 return KERN_SUCCESS;
2884}
2885
2886user_addr_t
2887kdbg_write_v3_event_chunk_header(user_addr_t buffer, uint32_t tag, uint64_t length, vnode_t vp, vfs_context_t ctx)
2888{
0a7de745
A
2889 uint64_t future_chunk_timestamp = 0;
2890 length += sizeof(uint64_t);
2891
2892 if (kdbg_write_v3_chunk_header(buffer, tag, V3_EVENT_DATA_VERSION, length, vp, ctx)) {
2893 return 0;
2894 }
2895 if (buffer) {
2896 buffer += sizeof(kd_chunk_header_v3);
2897 }
2898
2899 // Check that only one of them is valid
2900 assert(!buffer ^ !vp);
2901 assert((vp == NULL) || (ctx != NULL));
2902
2903 // Write the 8-byte future_chunk_timestamp field in the payload
2904 if (buffer || vp) {
2905 if (vp) {
2906 int ret = kdbg_write_to_vnode((caddr_t)&future_chunk_timestamp, sizeof(uint64_t), vp, ctx, RAW_file_offset);
2907 if (!ret) {
2908 RAW_file_offset += (sizeof(uint64_t));
2909 }
2910 } else {
2911 if (copyout(&future_chunk_timestamp, buffer, sizeof(uint64_t))) {
2912 return 0;
2913 }
2914 }
2915 }
2916
2917 return buffer + sizeof(uint64_t);
3e170ce0
A
2918}
2919
2920int
2921kdbg_write_v3_header(user_addr_t user_header, size_t *user_header_size, int fd)
2922{
0a7de745
A
2923 int ret = KERN_SUCCESS;
2924
2925 uint8_t* cpumap = 0;
2926 uint32_t cpumap_size = 0;
2927 uint32_t thrmap_size = 0;
2928
2929 size_t bytes_needed = 0;
2930
2931 // Check that only one of them is valid
2932 assert(!user_header ^ !fd);
2933 assert(user_header_size);
2934
2935 if (!(kd_ctrl_page.kdebug_flags & KDBG_BUFINIT)) {
2936 ret = EINVAL;
2937 goto bail;
2938 }
2939
2940 if (!(user_header || fd)) {
2941 ret = EINVAL;
2942 goto bail;
2943 }
2944
2945 // Initialize the cpu map
2946 ret = kdbg_cpumap_init_internal(kd_ctrl_page.kdebug_iops, kd_ctrl_page.kdebug_cpus, &cpumap, &cpumap_size);
2947 if (ret != KERN_SUCCESS) {
2948 goto bail;
2949 }
2950
2951 // Check if a thread map is initialized
2952 if (!kd_mapptr) {
2953 ret = EINVAL;
2954 goto bail;
2955 }
2956 thrmap_size = kd_mapcount * sizeof(kd_threadmap);
2957
2958 mach_timebase_info_data_t timebase = {0, 0};
2959 clock_timebase_info(&timebase);
2960
2961 // Setup the header.
2962 // See v3 header description in sys/kdebug.h for more inforamtion.
2963 kd_header_v3 header = {
2964 .tag = RAW_VERSION3,
2965 .sub_tag = V3_HEADER_VERSION,
2966 .length = (sizeof(kd_header_v3) + cpumap_size - sizeof(kd_cpumap_header)),
2967 .timebase_numer = timebase.numer,
2968 .timebase_denom = timebase.denom,
2969 .timestamp = 0, /* FIXME rdar://problem/22053009 */
2970 .walltime_secs = 0,
2971 .walltime_usecs = 0,
2972 .timezone_minuteswest = 0,
2973 .timezone_dst = 0,
39037602 2974#if defined(__LP64__)
0a7de745 2975 .flags = 1,
3e170ce0 2976#else
0a7de745 2977 .flags = 0,
3e170ce0 2978#endif
0a7de745
A
2979 };
2980
2981 // If its a buffer, check if we have enough space to copy the header and the maps.
2982 if (user_header) {
2983 bytes_needed = header.length + thrmap_size + (2 * sizeof(kd_chunk_header_v3));
2984 if (*user_header_size < bytes_needed) {
2985 ret = EINVAL;
2986 goto bail;
2987 }
2988 }
2989
2990 // Start writing the header
2991 if (fd) {
2992 void *hdr_ptr = (void *)(((uintptr_t) &header) + sizeof(kd_chunk_header_v3));
2993 size_t payload_size = (sizeof(kd_header_v3) - sizeof(kd_chunk_header_v3));
2994
2995 ret = kdbg_write_v3_chunk_to_fd(RAW_VERSION3, V3_HEADER_VERSION, header.length, hdr_ptr, payload_size, fd);
2996 if (ret) {
2997 goto bail;
2998 }
2999 } else {
3000 if (copyout(&header, user_header, sizeof(kd_header_v3))) {
3001 ret = EFAULT;
3002 goto bail;
3003 }
3004 // Update the user pointer
3005 user_header += sizeof(kd_header_v3);
3006 }
3007
3008 // Write a cpu map. This is a sub chunk of the header
3009 cpumap = (uint8_t*)((uintptr_t) cpumap + sizeof(kd_cpumap_header));
3010 size_t payload_size = (size_t)(cpumap_size - sizeof(kd_cpumap_header));
3011 if (fd) {
3012 ret = kdbg_write_v3_chunk_to_fd(V3_CPU_MAP, V3_CPUMAP_VERSION, payload_size, (void *)cpumap, payload_size, fd);
3013 if (ret) {
3014 goto bail;
3015 }
3016 } else {
3017 ret = kdbg_write_v3_chunk_header(user_header, V3_CPU_MAP, V3_CPUMAP_VERSION, payload_size, NULL, NULL);
3018 if (ret) {
3019 goto bail;
3020 }
3021 user_header += sizeof(kd_chunk_header_v3);
3022 if (copyout(cpumap, user_header, payload_size)) {
3023 ret = EFAULT;
3024 goto bail;
3025 }
3026 // Update the user pointer
3027 user_header += payload_size;
3028 }
3029
3030 // Write a thread map
3031 if (fd) {
3032 ret = kdbg_write_v3_chunk_to_fd(V3_THREAD_MAP, V3_THRMAP_VERSION, thrmap_size, (void *)kd_mapptr, thrmap_size, fd);
3033 if (ret) {
3034 goto bail;
3035 }
3036 } else {
3037 ret = kdbg_write_v3_chunk_header(user_header, V3_THREAD_MAP, V3_THRMAP_VERSION, thrmap_size, NULL, NULL);
3038 if (ret) {
3039 goto bail;
3040 }
3041 user_header += sizeof(kd_chunk_header_v3);
3042 if (copyout(kd_mapptr, user_header, thrmap_size)) {
3043 ret = EFAULT;
3044 goto bail;
3045 }
3046 user_header += thrmap_size;
3047 }
3048
3049 if (fd) {
3050 RAW_file_written += bytes_needed;
3051 }
3052
3053 *user_header_size = bytes_needed;
3e170ce0 3054bail:
0a7de745
A
3055 if (cpumap) {
3056 kmem_free(kernel_map, (vm_offset_t)cpumap, cpumap_size);
3057 }
3058 return ret;
3e170ce0
A
3059}
3060
3061int
3062kdbg_readcpumap(user_addr_t user_cpumap, size_t *user_cpumap_size)
3063{
3064 uint8_t* cpumap = NULL;
3065 uint32_t cpumap_size = 0;
3066 int ret = KERN_SUCCESS;
3067
3068 if (kd_ctrl_page.kdebug_flags & KDBG_BUFINIT) {
3069 if (kdbg_cpumap_init_internal(kd_ctrl_page.kdebug_iops, kd_ctrl_page.kdebug_cpus, &cpumap, &cpumap_size) == KERN_SUCCESS) {
3070 if (user_cpumap) {
3071 size_t bytes_to_copy = (*user_cpumap_size >= cpumap_size) ? cpumap_size : *user_cpumap_size;
3072 if (copyout(cpumap, user_cpumap, (size_t)bytes_to_copy)) {
3073 ret = EFAULT;
3074 }
3075 }
3076 *user_cpumap_size = cpumap_size;
3077 kmem_free(kernel_map, (vm_offset_t)cpumap, cpumap_size);
0a7de745 3078 } else {
3e170ce0 3079 ret = EINVAL;
0a7de745
A
3080 }
3081 } else {
39236c6e 3082 ret = EINVAL;
0a7de745 3083 }
39236c6e 3084
0a7de745 3085 return ret;
39236c6e 3086}
1c79356b 3087
91447636 3088int
3e170ce0 3089kdbg_readcurthrmap(user_addr_t buffer, size_t *bufsize)
1c79356b 3090{
3e170ce0 3091 kd_threadmap *mapptr;
39236c6e 3092 unsigned int mapsize;
3e170ce0
A
3093 unsigned int mapcount;
3094 unsigned int count = 0;
3095 int ret = 0;
1c79356b 3096
0a7de745 3097 count = *bufsize / sizeof(kd_threadmap);
3e170ce0 3098 *bufsize = 0;
1c79356b 3099
0a7de745
A
3100 if ((mapptr = kdbg_thrmap_init_internal(count, &mapsize, &mapcount))) {
3101 if (copyout(mapptr, buffer, mapcount * sizeof(kd_threadmap))) {
3e170ce0 3102 ret = EFAULT;
0a7de745 3103 } else {
3e170ce0 3104 *bufsize = (mapcount * sizeof(kd_threadmap));
0a7de745 3105 }
39236c6e 3106
3e170ce0 3107 kmem_free(kernel_map, (vm_offset_t)mapptr, mapsize);
0a7de745 3108 } else {
3e170ce0 3109 ret = EINVAL;
0a7de745 3110 }
39236c6e 3111
0a7de745 3112 return ret;
3e170ce0 3113}
39236c6e 3114
3e170ce0 3115static int
cb323159 3116kdbg_write_v1_header(bool write_thread_map, vnode_t vp, vfs_context_t ctx)
3e170ce0
A
3117{
3118 int ret = 0;
39037602
A
3119 RAW_header header;
3120 clock_sec_t secs;
3121 clock_usec_t usecs;
3122 char *pad_buf;
3e170ce0
A
3123 uint32_t pad_size;
3124 uint32_t extra_thread_count = 0;
3125 uint32_t cpumap_size;
39037602
A
3126 size_t map_size = 0;
3127 size_t map_count = 0;
3128
3129 if (write_thread_map) {
3130 assert(kd_ctrl_page.kdebug_flags & KDBG_MAPINIT);
3131 map_count = kd_mapcount;
3132 map_size = map_count * sizeof(kd_threadmap);
3133 }
3134
3135 /*
3136 * Without the buffers initialized, we cannot construct a CPU map or a
3137 * thread map, and cannot write a header.
3138 */
3139 if (!(kd_ctrl_page.kdebug_flags & KDBG_BUFINIT)) {
3140 return EINVAL;
3141 }
6d2010ae 3142
3e170ce0 3143 /*
39037602
A
3144 * To write a RAW_VERSION1+ file, we must embed a cpumap in the
3145 * "padding" used to page align the events following the threadmap. If
3146 * the threadmap happens to not require enough padding, we artificially
3147 * increase its footprint until it needs enough padding.
3e170ce0 3148 */
6d2010ae 3149
39037602
A
3150 assert(vp);
3151 assert(ctx);
39236c6e 3152
39037602 3153 pad_size = PAGE_16KB - ((sizeof(RAW_header) + map_size) & PAGE_MASK_64);
3e170ce0 3154 cpumap_size = sizeof(kd_cpumap_header) + kd_ctrl_page.kdebug_cpus * sizeof(kd_cpumap);
6d2010ae 3155
3e170ce0
A
3156 if (cpumap_size > pad_size) {
3157 /* If the cpu map doesn't fit in the current available pad_size,
3158 * we increase the pad_size by 16K. We do this so that the event
3159 * data is always available on a page aligned boundary for both
3160 * 4k and 16k systems. We enforce this alignment for the event
39037602
A
3161 * data so that we can take advantage of optimized file/disk writes.
3162 */
3e170ce0
A
3163 pad_size += PAGE_16KB;
3164 }
b0d623f7 3165
3e170ce0
A
3166 /* The way we are silently embedding a cpumap in the "padding" is by artificially
3167 * increasing the number of thread entries. However, we'll also need to ensure that
3168 * the cpumap is embedded in the last 4K page before when the event data is expected.
3169 * This way the tools can read the data starting the next page boundary on both
3170 * 4K and 16K systems preserving compatibility with older versions of the tools
0a7de745 3171 */
3e170ce0
A
3172 if (pad_size > PAGE_4KB) {
3173 pad_size -= PAGE_4KB;
3174 extra_thread_count = (pad_size / sizeof(kd_threadmap)) + 1;
3175 }
39236c6e 3176
39037602 3177 memset(&header, 0, sizeof(header));
3e170ce0 3178 header.version_no = RAW_VERSION1;
39037602 3179 header.thread_count = map_count + extra_thread_count;
3e170ce0
A
3180
3181 clock_get_calendar_microtime(&secs, &usecs);
3182 header.TOD_secs = secs;
3183 header.TOD_usecs = usecs;
3184
3185 ret = vn_rdwr(UIO_WRITE, vp, (caddr_t)&header, sizeof(RAW_header), RAW_file_offset,
0a7de745 3186 UIO_SYSSPACE, IO_NODELOCKED | IO_UNIT, vfs_context_ucred(ctx), (int *) 0, vfs_context_proc(ctx));
39037602 3187 if (ret) {
3e170ce0 3188 goto write_error;
39037602 3189 }
3e170ce0 3190 RAW_file_offset += sizeof(RAW_header);
39037602 3191 RAW_file_written += sizeof(RAW_header);
3e170ce0 3192
39037602
A
3193 if (write_thread_map) {
3194 ret = vn_rdwr(UIO_WRITE, vp, (caddr_t)kd_mapptr, map_size, RAW_file_offset,
0a7de745 3195 UIO_SYSSPACE, IO_NODELOCKED | IO_UNIT, vfs_context_ucred(ctx), (int *) 0, vfs_context_proc(ctx));
39037602
A
3196 if (ret) {
3197 goto write_error;
3198 }
3199
3200 RAW_file_offset += map_size;
3201 RAW_file_written += map_size;
3202 }
3e170ce0
A
3203
3204 if (extra_thread_count) {
3205 pad_size = extra_thread_count * sizeof(kd_threadmap);
39037602 3206 pad_buf = kalloc(pad_size);
3e170ce0
A
3207 if (!pad_buf) {
3208 ret = ENOMEM;
3209 goto write_error;
3210 }
3211 memset(pad_buf, 0, pad_size);
39236c6e 3212
3e170ce0 3213 ret = vn_rdwr(UIO_WRITE, vp, (caddr_t)pad_buf, pad_size, RAW_file_offset,
0a7de745 3214 UIO_SYSSPACE, IO_NODELOCKED | IO_UNIT, vfs_context_ucred(ctx), (int *) 0, vfs_context_proc(ctx));
3e170ce0 3215 kfree(pad_buf, pad_size);
39037602 3216 if (ret) {
3e170ce0 3217 goto write_error;
39037602 3218 }
6d2010ae 3219
39037602
A
3220 RAW_file_offset += pad_size;
3221 RAW_file_written += pad_size;
3e170ce0
A
3222 }
3223
3224 pad_size = PAGE_SIZE - (RAW_file_offset & PAGE_MASK_64);
3225 if (pad_size) {
3226 pad_buf = (char *)kalloc(pad_size);
3227 if (!pad_buf) {
3228 ret = ENOMEM;
3229 goto write_error;
3230 }
3231 memset(pad_buf, 0, pad_size);
3232
3233 /*
3234 * embed a cpumap in the padding bytes.
3235 * older code will skip this.
3236 * newer code will know how to read it.
3237 */
3238 uint32_t temp = pad_size;
3239 if (kdbg_cpumap_init_internal(kd_ctrl_page.kdebug_iops, kd_ctrl_page.kdebug_cpus, (uint8_t**)&pad_buf, &temp) != KERN_SUCCESS) {
3240 memset(pad_buf, 0, pad_size);
3241 }
3242
3243 ret = vn_rdwr(UIO_WRITE, vp, (caddr_t)pad_buf, pad_size, RAW_file_offset,
0a7de745 3244 UIO_SYSSPACE, IO_NODELOCKED | IO_UNIT, vfs_context_ucred(ctx), (int *) 0, vfs_context_proc(ctx));
3e170ce0 3245 kfree(pad_buf, pad_size);
39037602 3246 if (ret) {
3e170ce0 3247 goto write_error;
39037602
A
3248 }
3249
3e170ce0 3250 RAW_file_offset += pad_size;
39037602 3251 RAW_file_written += pad_size;
3e170ce0 3252 }
3e170ce0
A
3253
3254write_error:
3255 return ret;
3256}
3257
39037602
A
3258static void
3259kdbg_clear_thread_map(void)
3e170ce0 3260{
5ba3f43e 3261 ktrace_assert_lock_held();
39037602
A
3262
3263 if (kd_ctrl_page.kdebug_flags & KDBG_MAPINIT) {
3264 assert(kd_mapptr != NULL);
3265 kmem_free(kernel_map, (vm_offset_t)kd_mapptr, kd_mapsize);
3266 kd_mapptr = NULL;
3267 kd_mapsize = 0;
3268 kd_mapcount = 0;
3269 kd_ctrl_page.kdebug_flags &= ~KDBG_MAPINIT;
3270 }
3271}
3e170ce0 3272
39037602
A
3273/*
3274 * Write out a version 1 header and the thread map, if it is initialized, to a
3275 * vnode. Used by KDWRITEMAP and kdbg_dump_trace_to_file.
3276 *
3277 * Returns write errors from vn_rdwr if a write fails. Returns ENODATA if the
3278 * thread map has not been initialized, but the header will still be written.
3279 * Returns ENOMEM if padding could not be allocated. Returns 0 otherwise.
3280 */
3281static int
3282kdbg_write_thread_map(vnode_t vp, vfs_context_t ctx)
3283{
3e170ce0 3284 int ret = 0;
cb323159 3285 bool map_initialized;
3e170ce0 3286
5ba3f43e 3287 ktrace_assert_lock_held();
39037602
A
3288 assert(ctx != NULL);
3289
3290 map_initialized = (kd_ctrl_page.kdebug_flags & KDBG_MAPINIT);
3291
3292 ret = kdbg_write_v1_header(map_initialized, vp, ctx);
3293 if (ret == 0) {
3294 if (map_initialized) {
3295 kdbg_clear_thread_map();
3296 } else {
3297 ret = ENODATA;
3298 }
3e170ce0
A
3299 }
3300
39037602
A
3301 return ret;
3302}
3e170ce0 3303
39037602
A
3304/*
3305 * Copy out the thread map to a user space buffer. Used by KDTHRMAP.
3306 *
3307 * Returns copyout errors if the copyout fails. Returns ENODATA if the thread
3308 * map has not been initialized. Returns EINVAL if the buffer provided is not
3309 * large enough for the entire thread map. Returns 0 otherwise.
3310 */
3311static int
3312kdbg_copyout_thread_map(user_addr_t buffer, size_t *buffer_size)
3313{
cb323159 3314 bool map_initialized;
39037602
A
3315 size_t map_size;
3316 int ret = 0;
3e170ce0 3317
5ba3f43e 3318 ktrace_assert_lock_held();
39037602
A
3319 assert(buffer_size != NULL);
3320
3321 map_initialized = (kd_ctrl_page.kdebug_flags & KDBG_MAPINIT);
3322 if (!map_initialized) {
3323 return ENODATA;
b0d623f7 3324 }
b0d623f7 3325
39037602
A
3326 map_size = kd_mapcount * sizeof(kd_threadmap);
3327 if (*buffer_size < map_size) {
3328 return EINVAL;
3329 }
b0d623f7 3330
39037602
A
3331 ret = copyout(kd_mapptr, buffer, map_size);
3332 if (ret == 0) {
3333 kdbg_clear_thread_map();
1c79356b 3334 }
39037602
A
3335
3336 return ret;
1c79356b
A
3337}
3338
3e170ce0 3339int
39037602 3340kdbg_readthrmap_v3(user_addr_t buffer, size_t buffer_size, int fd)
3e170ce0 3341{
3e170ce0 3342 int ret = 0;
cb323159 3343 bool map_initialized;
39037602
A
3344 size_t map_size;
3345
5ba3f43e 3346 ktrace_assert_lock_held();
3e170ce0
A
3347
3348 if ((!fd && !buffer) || (fd && buffer)) {
3349 return EINVAL;
3350 }
3351
39037602
A
3352 map_initialized = (kd_ctrl_page.kdebug_flags & KDBG_MAPINIT);
3353 map_size = kd_mapcount * sizeof(kd_threadmap);
3e170ce0 3354
0a7de745 3355 if (map_initialized && (buffer_size >= map_size)) {
39037602 3356 ret = kdbg_write_v3_header(buffer, &buffer_size, fd);
3e170ce0 3357
39037602
A
3358 if (ret == 0) {
3359 kdbg_clear_thread_map();
3e170ce0 3360 }
39037602 3361 } else {
3e170ce0
A
3362 ret = EINVAL;
3363 }
3e170ce0 3364
0a7de745 3365 return ret;
39037602 3366}
9bccf70c 3367
39037602 3368static void
0a7de745 3369kdbg_set_nkdbufs(unsigned int req_nkdbufs)
2d21ac55 3370{
39037602 3371 /*
0a7de745 3372 * Only allow allocation up to half the available memory (sane_size).
2d21ac55 3373 */
0a7de745
A
3374 uint64_t max_nkdbufs = (sane_size / 2) / sizeof(kd_buf);
3375 nkdbufs = (req_nkdbufs > max_nkdbufs) ? max_nkdbufs : req_nkdbufs;
2d21ac55
A
3376}
3377
39037602
A
3378/*
3379 * Block until there are `n_storage_threshold` storage units filled with
3380 * events or `timeout_ms` milliseconds have passed. If `locked_wait` is true,
3381 * `ktrace_lock` is held while waiting. This is necessary while waiting to
3382 * write events out of the buffers.
3383 *
3384 * Returns true if the threshold was reached and false otherwise.
3385 *
3386 * Called with `ktrace_lock` locked and interrupts enabled.
3387 */
cb323159
A
3388static bool
3389kdbg_wait(uint64_t timeout_ms, bool locked_wait)
316670eb 3390{
39037602
A
3391 int wait_result = THREAD_AWAKENED;
3392 uint64_t abstime = 0;
39236c6e 3393
5ba3f43e
A
3394 ktrace_assert_lock_held();
3395
39037602
A
3396 if (timeout_ms != 0) {
3397 uint64_t ns = timeout_ms * NSEC_PER_MSEC;
0a7de745 3398 nanoseconds_to_absolutetime(ns, &abstime);
39037602 3399 clock_absolutetime_interval_to_deadline(abstime, &abstime);
316670eb 3400 }
316670eb 3401
cb323159 3402 bool s = ml_set_interrupts_enabled(false);
39037602
A
3403 if (!s) {
3404 panic("kdbg_wait() called with interrupts disabled");
316670eb 3405 }
0a7de745 3406 lck_spin_lock_grp(kdw_spin_lock, kdebug_lck_grp);
316670eb 3407
39037602
A
3408 if (!locked_wait) {
3409 /* drop the mutex to allow others to access trace */
5ba3f43e 3410 ktrace_unlock();
39037602 3411 }
316670eb 3412
39037602 3413 while (wait_result == THREAD_AWAKENED &&
0a7de745 3414 kd_ctrl_page.kds_inuse_count < n_storage_threshold) {
39037602 3415 kds_waiter = 1;
316670eb 3416
39037602
A
3417 if (abstime) {
3418 wait_result = lck_spin_sleep_deadline(kdw_spin_lock, 0, &kds_waiter, THREAD_ABORTSAFE, abstime);
3419 } else {
3420 wait_result = lck_spin_sleep(kdw_spin_lock, 0, &kds_waiter, THREAD_ABORTSAFE);
3421 }
9bccf70c 3422
39037602
A
3423 kds_waiter = 0;
3424 }
3425
3426 /* check the count under the spinlock */
cb323159 3427 bool threshold_exceeded = (kd_ctrl_page.kds_inuse_count >= n_storage_threshold);
39037602
A
3428
3429 lck_spin_unlock(kdw_spin_lock);
3430 ml_set_interrupts_enabled(s);
3431
3432 if (!locked_wait) {
3433 /* pick the mutex back up again */
5ba3f43e 3434 ktrace_lock();
39037602
A
3435 }
3436
3437 /* write out whether we've exceeded the threshold */
3438 return threshold_exceeded;
3439}
3440
3441/*
3442 * Wakeup a thread waiting using `kdbg_wait` if there are at least
3443 * `n_storage_threshold` storage units in use.
3444 */
3445static void
3446kdbg_wakeup(void)
9bccf70c 3447{
cb323159 3448 bool need_kds_wakeup = false;
39037602
A
3449
3450 /*
3451 * Try to take the lock here to synchronize with the waiter entering
3452 * the blocked state. Use the try mode to prevent deadlocks caused by
3453 * re-entering this routine due to various trace points triggered in the
3454 * lck_spin_sleep_xxxx routines used to actually enter one of our 2 wait
3455 * conditions. No problem if we fail, there will be lots of additional
3456 * events coming in that will eventually succeed in grabbing this lock.
3457 */
cb323159 3458 bool s = ml_set_interrupts_enabled(false);
39037602
A
3459
3460 if (lck_spin_try_lock(kdw_spin_lock)) {
3461 if (kds_waiter &&
0a7de745 3462 (kd_ctrl_page.kds_inuse_count >= n_storage_threshold)) {
39037602 3463 kds_waiter = 0;
cb323159 3464 need_kds_wakeup = true;
39037602
A
3465 }
3466 lck_spin_unlock(kdw_spin_lock);
9bccf70c 3467 }
39037602
A
3468
3469 ml_set_interrupts_enabled(s);
3470
cb323159 3471 if (need_kds_wakeup == true) {
39037602 3472 wakeup(&kds_waiter);
9bccf70c
A
3473 }
3474}
1c79356b 3475
0c530ab8 3476int
c910b4d9 3477kdbg_control(int *name, u_int namelen, user_addr_t where, size_t *sizep)
1c79356b 3478{
b0d623f7
A
3479 int ret = 0;
3480 size_t size = *sizep;
c910b4d9 3481 unsigned int value = 0;
91447636
A
3482 kd_regtype kd_Reg;
3483 kbufinfo_t kd_bufinfo;
39037602 3484 proc_t p;
91447636 3485
813fb2f6 3486 if (name[0] == KERN_KDWRITETR ||
0a7de745
A
3487 name[0] == KERN_KDWRITETR_V3 ||
3488 name[0] == KERN_KDWRITEMAP ||
3489 name[0] == KERN_KDWRITEMAP_V3 ||
3490 name[0] == KERN_KDEFLAGS ||
3491 name[0] == KERN_KDDFLAGS ||
3492 name[0] == KERN_KDENABLE ||
3493 name[0] == KERN_KDSETBUF) {
39037602
A
3494 if (namelen < 2) {
3495 return EINVAL;
3496 }
c910b4d9
A
3497 value = name[1];
3498 }
39037602 3499
91447636 3500 kdbg_lock_init();
39037602 3501 assert(kd_ctrl_page.kdebug_flags & KDBG_LOCKINIT);
0c530ab8 3502
5ba3f43e 3503 ktrace_lock();
0c530ab8 3504
39037602
A
3505 /*
3506 * Some requests only require "read" access to kdebug trace. Regardless,
3507 * tell ktrace that a configuration or read is occurring (and see if it's
3508 * allowed).
3509 */
3510 if (name[0] != KERN_KDGETBUF &&
3511 name[0] != KERN_KDGETREG &&
0a7de745 3512 name[0] != KERN_KDREADCURTHRMAP) {
39037602
A
3513 if ((ret = ktrace_configure(KTRACE_KDEBUG))) {
3514 goto out;
3515 }
3516 } else {
3517 if ((ret = ktrace_read_check())) {
3518 goto out;
3519 }
3520 }
91447636 3521
0a7de745
A
3522 switch (name[0]) {
3523 case KERN_KDGETBUF:
3524 if (size < sizeof(kd_bufinfo.nkdbufs)) {
3525 /*
3526 * There is not enough room to return even
3527 * the first element of the info structure.
3528 */
3529 ret = EINVAL;
3530 break;
3531 }
39037602 3532
0a7de745 3533 memset(&kd_bufinfo, 0, sizeof(kd_bufinfo));
39037602 3534
0a7de745
A
3535 kd_bufinfo.nkdbufs = nkdbufs;
3536 kd_bufinfo.nkdthreads = kd_mapcount;
39037602 3537
0a7de745
A
3538 if ((kd_ctrl_page.kdebug_slowcheck & SLOW_NOLOG)) {
3539 kd_bufinfo.nolog = 1;
3540 } else {
3541 kd_bufinfo.nolog = 0;
3542 }
39037602 3543
0a7de745 3544 kd_bufinfo.flags = kd_ctrl_page.kdebug_flags;
39236c6e 3545#if defined(__LP64__)
0a7de745 3546 kd_bufinfo.flags |= KDBG_LP64;
39236c6e 3547#endif
0a7de745
A
3548 {
3549 int pid = ktrace_get_owning_pid();
3550 kd_bufinfo.bufid = (pid == 0 ? -1 : pid);
3551 }
39037602 3552
0a7de745
A
3553 if (size >= sizeof(kd_bufinfo)) {
3554 /*
3555 * Provide all the info we have
3556 */
3557 if (copyout(&kd_bufinfo, where, sizeof(kd_bufinfo))) {
3558 ret = EINVAL;
39236c6e 3559 }
0a7de745
A
3560 } else {
3561 /*
3562 * For backwards compatibility, only provide
3563 * as much info as there is room for.
3564 */
3565 if (copyout(&kd_bufinfo, where, size)) {
3566 ret = EINVAL;
3567 }
3568 }
3569 break;
39037602 3570
0a7de745
A
3571 case KERN_KDREADCURTHRMAP:
3572 ret = kdbg_readcurthrmap(where, sizep);
3573 break;
1c79356b 3574
0a7de745
A
3575 case KERN_KDEFLAGS:
3576 value &= KDBG_USERFLAGS;
3577 kd_ctrl_page.kdebug_flags |= value;
3578 break;
316670eb 3579
0a7de745
A
3580 case KERN_KDDFLAGS:
3581 value &= KDBG_USERFLAGS;
3582 kd_ctrl_page.kdebug_flags &= ~value;
3583 break;
39037602 3584
0a7de745
A
3585 case KERN_KDENABLE:
3586 /*
3587 * Enable tracing mechanism. Two types:
3588 * KDEBUG_TRACE is the standard one,
3589 * and KDEBUG_PPT which is a carefully
3590 * chosen subset to avoid performance impact.
3591 */
3592 if (value) {
b0d623f7 3593 /*
0a7de745 3594 * enable only if buffer is initialized
b0d623f7 3595 */
0a7de745
A
3596 if (!(kd_ctrl_page.kdebug_flags & KDBG_BUFINIT) ||
3597 !(value == KDEBUG_ENABLE_TRACE || value == KDEBUG_ENABLE_PPT)) {
3598 ret = EINVAL;
3599 break;
1c79356b 3600 }
0a7de745 3601 kdbg_thrmap_init();
39037602 3602
cb323159 3603 kdbg_set_tracing_enabled(true, value);
0a7de745
A
3604 } else {
3605 if (!kdebug_enable) {
3606 break;
316670eb 3607 }
316670eb 3608
0a7de745
A
3609 kernel_debug_disable();
3610 }
3611 break;
316670eb 3612
0a7de745
A
3613 case KERN_KDSETBUF:
3614 kdbg_set_nkdbufs(value);
3615 break;
39037602 3616
0a7de745 3617 case KERN_KDSETUP:
cb323159 3618 ret = kdbg_reinit(false);
0a7de745 3619 break;
39037602 3620
0a7de745
A
3621 case KERN_KDREMOVE:
3622 ktrace_reset(KTRACE_KDEBUG);
3623 break;
316670eb 3624
0a7de745
A
3625 case KERN_KDSETREG:
3626 if (size < sizeof(kd_regtype)) {
3627 ret = EINVAL;
1c79356b 3628 break;
0a7de745
A
3629 }
3630 if (copyin(where, &kd_Reg, sizeof(kd_regtype))) {
4bd07ac2 3631 ret = EINVAL;
1c79356b 3632 break;
0a7de745 3633 }
39037602 3634
0a7de745
A
3635 ret = kdbg_setreg(&kd_Reg);
3636 break;
39037602 3637
0a7de745
A
3638 case KERN_KDGETREG:
3639 ret = EINVAL;
3640 break;
6d2010ae 3641
0a7de745
A
3642 case KERN_KDREADTR:
3643 ret = kdbg_read(where, sizep, NULL, NULL, RAW_VERSION1);
3644 break;
6d2010ae 3645
0a7de745
A
3646 case KERN_KDWRITETR:
3647 case KERN_KDWRITETR_V3:
3648 case KERN_KDWRITEMAP:
3649 case KERN_KDWRITEMAP_V3:
3650 {
3651 struct vfs_context context;
3652 struct fileproc *fp;
3653 size_t number;
3654 vnode_t vp;
3655 int fd;
3656
3657 if (name[0] == KERN_KDWRITETR || name[0] == KERN_KDWRITETR_V3) {
cb323159 3658 (void)kdbg_wait(size, true);
0a7de745
A
3659 }
3660 p = current_proc();
3661 fd = value;
6d2010ae 3662
0a7de745
A
3663 proc_fdlock(p);
3664 if ((ret = fp_lookup(p, fd, &fp, 1))) {
3665 proc_fdunlock(p);
3666 break;
3667 }
3668 context.vc_thread = current_thread();
3669 context.vc_ucred = fp->f_fglob->fg_cred;
6d2010ae 3670
0a7de745
A
3671 if (FILEGLOB_DTYPE(fp->f_fglob) != DTYPE_VNODE) {
3672 fp_drop(p, fd, fp, 1);
6d2010ae
A
3673 proc_fdunlock(p);
3674
0a7de745
A
3675 ret = EBADF;
3676 break;
3677 }
3678 vp = (struct vnode *)fp->f_fglob->fg_data;
3679 proc_fdunlock(p);
3680
3681 if ((ret = vnode_getwithref(vp)) == 0) {
3682 RAW_file_offset = fp->f_fglob->fg_offset;
3683 if (name[0] == KERN_KDWRITETR || name[0] == KERN_KDWRITETR_V3) {
3684 number = nkdbufs * sizeof(kd_buf);
6d2010ae 3685
0a7de745
A
3686 KDBG_RELEASE(TRACE_WRITING_EVENTS | DBG_FUNC_START);
3687 if (name[0] == KERN_KDWRITETR_V3) {
3688 ret = kdbg_read(0, &number, vp, &context, RAW_VERSION3);
3689 } else {
3690 ret = kdbg_read(0, &number, vp, &context, RAW_VERSION1);
3691 }
3692 KDBG_RELEASE(TRACE_WRITING_EVENTS | DBG_FUNC_END, number);
6d2010ae 3693
0a7de745
A
3694 *sizep = number;
3695 } else {
3696 number = kd_mapcount * sizeof(kd_threadmap);
3697 if (name[0] == KERN_KDWRITEMAP_V3) {
3698 ret = kdbg_readthrmap_v3(0, number, fd);
6d2010ae 3699 } else {
0a7de745 3700 ret = kdbg_write_thread_map(vp, &context);
6d2010ae 3701 }
6d2010ae 3702 }
0a7de745
A
3703 fp->f_fglob->fg_offset = RAW_file_offset;
3704 vnode_put(vp);
3705 }
3706 fp_drop(p, fd, fp, 0);
6d2010ae 3707
0a7de745
A
3708 break;
3709 }
3710 case KERN_KDBUFWAIT:
cb323159 3711 *sizep = kdbg_wait(size, false);
0a7de745
A
3712 break;
3713
3714 case KERN_KDPIDTR:
3715 if (size < sizeof(kd_regtype)) {
3716 ret = EINVAL;
6d2010ae
A
3717 break;
3718 }
0a7de745
A
3719 if (copyin(where, &kd_Reg, sizeof(kd_regtype))) {
3720 ret = EINVAL;
39236c6e 3721 break;
0a7de745 3722 }
39037602 3723
0a7de745
A
3724 ret = kdbg_setpid(&kd_Reg);
3725 break;
316670eb 3726
0a7de745
A
3727 case KERN_KDPIDEX:
3728 if (size < sizeof(kd_regtype)) {
3729 ret = EINVAL;
1c79356b 3730 break;
0a7de745
A
3731 }
3732 if (copyin(where, &kd_Reg, sizeof(kd_regtype))) {
3733 ret = EINVAL;
1c79356b 3734 break;
0a7de745 3735 }
39037602 3736
0a7de745
A
3737 ret = kdbg_setpidex(&kd_Reg);
3738 break;
39037602 3739
0a7de745
A
3740 case KERN_KDCPUMAP:
3741 ret = kdbg_readcpumap(where, sizep);
3742 break;
316670eb 3743
0a7de745
A
3744 case KERN_KDTHRMAP:
3745 ret = kdbg_copyout_thread_map(where, sizep);
3746 break;
3e170ce0 3747
0a7de745
A
3748 case KERN_KDSET_TYPEFILTER: {
3749 ret = kdbg_copyin_typefilter(where, size);
3750 break;
3751 }
39037602 3752
0a7de745
A
3753 case KERN_KDTEST:
3754 ret = kdbg_test(size);
3755 break;
3756
3757 default:
3758 ret = EINVAL;
3759 break;
1c79356b 3760 }
b0d623f7 3761out:
5ba3f43e 3762 ktrace_unlock();
91447636 3763
5ba3f43e 3764 return ret;
1c79356b
A
3765}
3766
0c530ab8
A
3767
3768/*
b0d623f7
A
3769 * This code can run for the most part concurrently with kernel_debug_internal()...
3770 * 'release_storage_unit' will take the kds_spin_lock which may cause us to briefly
3771 * synchronize with the recording side of this puzzle... otherwise, we are able to
3772 * move through the lists w/o use of any locks
0c530ab8
A
3773 */
3774int
3e170ce0 3775kdbg_read(user_addr_t buffer, size_t *number, vnode_t vp, vfs_context_t ctx, uint32_t file_version)
1c79356b 3776{
0c530ab8 3777 unsigned int count;
6d2010ae 3778 unsigned int cpu, min_cpu;
39037602 3779 uint64_t barrier_min = 0, barrier_max = 0, t, earliest_time;
6d2010ae 3780 int error = 0;
0c530ab8 3781 kd_buf *tempbuf;
6d2010ae
A
3782 uint32_t rcursor;
3783 kd_buf lostevent;
3784 union kds_ptr kdsp;
5ba3f43e 3785 bool traced_retrograde = false;
6d2010ae 3786 struct kd_storage *kdsp_actual;
b0d623f7 3787 struct kd_bufinfo *kdbp;
6d2010ae 3788 struct kd_bufinfo *min_kdbp;
0c530ab8
A
3789 uint32_t tempbuf_count;
3790 uint32_t tempbuf_number;
b0d623f7
A
3791 uint32_t old_kdebug_flags;
3792 uint32_t old_kdebug_slowcheck;
cb323159
A
3793 bool out_of_events = false;
3794 bool wrapped = false;
2d21ac55 3795
39037602 3796 assert(number);
0a7de745 3797 count = *number / sizeof(kd_buf);
0c530ab8
A
3798 *number = 0;
3799
5ba3f43e
A
3800 ktrace_assert_lock_held();
3801
0a7de745 3802 if (count == 0 || !(kd_ctrl_page.kdebug_flags & KDBG_BUFINIT) || kdcopybuf == 0) {
0c530ab8 3803 return EINVAL;
0a7de745 3804 }
1c79356b 3805
39037602
A
3806 thread_set_eager_preempt(current_thread());
3807
6d2010ae 3808 memset(&lostevent, 0, sizeof(lostevent));
04b8595b 3809 lostevent.debugid = TRACE_LOST_EVENTS;
6d2010ae 3810
0c530ab8 3811 /*
39037602
A
3812 * Request each IOP to provide us with up to date entries before merging
3813 * buffers together.
0c530ab8 3814 */
39037602 3815 kdbg_iop_list_callback(kd_ctrl_page.kdebug_iops, KD_CALLBACK_SYNC_FLUSH, NULL);
0c530ab8 3816
cb323159
A
3817 /*
3818 * Capture the current time. Only sort events that have occured
3819 * before now. Since the IOPs are being flushed here, it is possible
3820 * that events occur on the AP while running live tracing.
3821 */
3822 barrier_max = kdbg_timestamp() & KDBG_TIMESTAMP_MASK;
3823
39037602
A
3824 /*
3825 * Disable wrap so storage units cannot be stolen out from underneath us
3826 * while merging events.
3827 *
3828 * Because we hold ktrace_lock, no other control threads can be playing
3829 * with kdebug_flags. The code that emits new events could be running,
3830 * but it grabs kds_spin_lock if it needs to acquire a new storage
3831 * chunk, which is where it examines kdebug_flags. If it is adding to
3832 * the same chunk we're reading from, check for that below.
3833 */
3834 wrapped = disable_wrap(&old_kdebug_slowcheck, &old_kdebug_flags);
4452a7af 3835
0a7de745 3836 if (count > nkdbufs) {
0c530ab8 3837 count = nkdbufs;
0a7de745 3838 }
4452a7af 3839
39037602
A
3840 if ((tempbuf_count = count) > KDCOPYBUF_COUNT) {
3841 tempbuf_count = KDCOPYBUF_COUNT;
3842 }
3843
3844 /*
d9a64523 3845 * If the buffers have wrapped, do not emit additional lost events for the
39037602
A
3846 * oldest storage units.
3847 */
3848 if (wrapped) {
39037602 3849 kd_ctrl_page.kdebug_flags &= ~KDBG_WRAPPED;
39037602
A
3850
3851 for (cpu = 0, kdbp = &kdbip[0]; cpu < kd_ctrl_page.kdebug_cpus; cpu++, kdbp++) {
3852 if ((kdsp = kdbp->kd_list_head).raw == KDS_PTR_NULL) {
3853 continue;
3854 }
3855 kdsp_actual = POINTER_FROM_KDS_PTR(kdsp);
cb323159 3856 kdsp_actual->kds_lostevents = false;
39037602
A
3857 }
3858 }
d9a64523
A
3859 /*
3860 * Capture the earliest time where there are events for all CPUs and don't
3861 * emit events with timestamps prior.
3862 */
3863 barrier_min = kd_ctrl_page.oldest_time;
4452a7af 3864
0c530ab8 3865 while (count) {
39236c6e 3866 tempbuf = kdcopybuf;
0c530ab8
A
3867 tempbuf_number = 0;
3868
39037602 3869 if (wrapped) {
d9a64523
A
3870 /*
3871 * Emit a lost events tracepoint to indicate that previous events
3872 * were lost -- the thread map cannot be trusted. A new one must
3873 * be taken so tools can analyze the trace in a backwards-facing
3874 * fashion.
3875 */
39037602
A
3876 kdbg_set_timestamp_and_cpu(&lostevent, barrier_min, 0);
3877 *tempbuf = lostevent;
cb323159 3878 wrapped = false;
39037602
A
3879 goto nextevent;
3880 }
3881
3882 /* While space left in merged events scratch buffer. */
39236c6e 3883 while (tempbuf_count) {
d9a64523
A
3884 bool lostevents = false;
3885 int lostcpu = 0;
39037602 3886 earliest_time = UINT64_MAX;
6d2010ae
A
3887 min_kdbp = NULL;
3888 min_cpu = 0;
0c530ab8 3889
d9a64523 3890 /* Check each CPU's buffers for the earliest event. */
39236c6e 3891 for (cpu = 0, kdbp = &kdbip[0]; cpu < kd_ctrl_page.kdebug_cpus; cpu++, kdbp++) {
d9a64523 3892 /* Skip CPUs without data in their oldest storage unit. */
39037602
A
3893 if ((kdsp = kdbp->kd_list_head).raw == KDS_PTR_NULL) {
3894next_cpu:
3895 continue;
3896 }
39037602 3897 /* From CPU data to buffer header to buffer. */
6d2010ae
A
3898 kdsp_actual = POINTER_FROM_KDS_PTR(kdsp);
3899
d9a64523
A
3900next_event:
3901 /* The next event to be read from this buffer. */
6d2010ae 3902 rcursor = kdsp_actual->kds_readlast;
b0d623f7 3903
d9a64523 3904 /* Skip this buffer if there are no events left. */
39037602 3905 if (rcursor == kdsp_actual->kds_bufindx) {
b0d623f7 3906 continue;
39037602 3907 }
0c530ab8 3908
d9a64523
A
3909 /*
3910 * Check that this storage unit wasn't stolen and events were
3911 * lost. This must have happened while wrapping was disabled
3912 * in this function.
3913 */
3914 if (kdsp_actual->kds_lostevents) {
3915 lostevents = true;
cb323159 3916 kdsp_actual->kds_lostevents = false;
39037602 3917
d9a64523
A
3918 /*
3919 * The earliest event we can trust is the first one in this
3920 * stolen storage unit.
3921 */
3922 uint64_t lost_time =
0a7de745 3923 kdbg_get_timestamp(&kdsp_actual->kds_records[0]);
d9a64523
A
3924 if (kd_ctrl_page.oldest_time < lost_time) {
3925 /*
3926 * If this is the first time we've seen lost events for
3927 * this gap, record its timestamp as the oldest
3928 * timestamp we're willing to merge for the lost events
3929 * tracepoint.
3930 */
3931 kd_ctrl_page.oldest_time = barrier_min = lost_time;
3932 lostcpu = cpu;
39037602 3933 }
39037602
A
3934 }
3935
d9a64523
A
3936 t = kdbg_get_timestamp(&kdsp_actual->kds_records[rcursor]);
3937
cb323159 3938 if (t > barrier_max) {
d9a64523
A
3939 if (kdbg_debug) {
3940 printf("kdebug: FUTURE EVENT: debugid %#8x: "
0a7de745
A
3941 "time %lld from CPU %u "
3942 "(barrier at time %lld, read %lu events)\n",
3943 kdsp_actual->kds_records[rcursor].debugid,
3944 t, cpu, barrier_max, *number + tempbuf_number);
d9a64523 3945 }
cb323159 3946 goto next_cpu;
39037602 3947 }
6d2010ae
A
3948 if (t < kdsp_actual->kds_timestamp) {
3949 /*
d9a64523
A
3950 * This indicates the event emitter hasn't completed
3951 * filling in the event (becuase we're looking at the
3952 * buffer that the record head is using). The max barrier
3953 * timestamp should have saved us from seeing these kinds
3954 * of things, but other CPUs might be slow on the up-take.
3955 *
3956 * Bail out so we don't get out-of-order events by
3957 * continuing to read events from other CPUs' events.
6d2010ae 3958 */
cb323159 3959 out_of_events = true;
6d2010ae
A
3960 break;
3961 }
d9a64523
A
3962
3963 /*
3964 * Ignore events that have aged out due to wrapping or storage
3965 * unit exhaustion while merging events.
3966 */
3967 if (t < barrier_min) {
3968 kdsp_actual->kds_readlast++;
cb323159
A
3969 if (kdbg_debug) {
3970 printf("kdebug: PAST EVENT: debugid %#8x: "
3971 "time %lld from CPU %u "
3972 "(barrier at time %lld)\n",
3973 kdsp_actual->kds_records[rcursor].debugid,
3974 t, cpu, barrier_min);
3975 }
d9a64523
A
3976
3977 if (kdsp_actual->kds_readlast >= EVENTS_PER_STORAGE_UNIT) {
3978 release_storage_unit(cpu, kdsp.raw);
3979
3980 if ((kdsp = kdbp->kd_list_head).raw == KDS_PTR_NULL) {
3981 goto next_cpu;
3982 }
3983 kdsp_actual = POINTER_FROM_KDS_PTR(kdsp);
3984 }
3985
3986 goto next_event;
3987 }
3988
3989 /*
3990 * Don't worry about merging any events -- just walk through
3991 * the CPUs and find the latest timestamp of lost events.
3992 */
3993 if (lostevents) {
3994 continue;
3995 }
3996
39037602
A
3997 if (t < earliest_time) {
3998 earliest_time = t;
6d2010ae
A
3999 min_kdbp = kdbp;
4000 min_cpu = cpu;
91447636
A
4001 }
4002 }
d9a64523 4003 if (lostevents) {
6d2010ae 4004 /*
d9a64523
A
4005 * If any lost events were hit in the buffers, emit an event
4006 * with the latest timestamp.
91447636 4007 */
d9a64523
A
4008 kdbg_set_timestamp_and_cpu(&lostevent, barrier_min, lostcpu);
4009 *tempbuf = lostevent;
4010 tempbuf->arg1 = 1;
4011 goto nextevent;
4012 }
4013 if (min_kdbp == NULL) {
4014 /* All buffers ran empty. */
cb323159 4015 out_of_events = true;
d9a64523
A
4016 }
4017 if (out_of_events) {
6d2010ae
A
4018 break;
4019 }
316670eb 4020
6d2010ae
A
4021 kdsp = min_kdbp->kd_list_head;
4022 kdsp_actual = POINTER_FROM_KDS_PTR(kdsp);
0c530ab8 4023
39037602 4024 /* Copy earliest event into merged events scratch buffer. */
6d2010ae
A
4025 *tempbuf = kdsp_actual->kds_records[kdsp_actual->kds_readlast++];
4026
0a7de745 4027 if (kdsp_actual->kds_readlast == EVENTS_PER_STORAGE_UNIT) {
6d2010ae 4028 release_storage_unit(min_cpu, kdsp.raw);
0a7de745 4029 }
6d2010ae 4030
b0d623f7 4031 /*
d9a64523 4032 * Watch for out of order timestamps (from IOPs).
39037602
A
4033 */
4034 if (earliest_time < min_kdbp->kd_prev_timebase) {
b0d623f7 4035 /*
5ba3f43e 4036 * If we haven't already, emit a retrograde events event.
d9a64523 4037 * Otherwise, ignore this event.
b0d623f7 4038 */
5ba3f43e
A
4039 if (traced_retrograde) {
4040 continue;
4041 }
4042
6d2010ae 4043 kdbg_set_timestamp_and_cpu(tempbuf, min_kdbp->kd_prev_timebase, kdbg_get_cpu(tempbuf));
5ba3f43e
A
4044 tempbuf->arg1 = tempbuf->debugid;
4045 tempbuf->arg2 = earliest_time;
4046 tempbuf->arg3 = 0;
4047 tempbuf->arg4 = 0;
4048 tempbuf->debugid = TRACE_RETROGRADE_EVENTS;
4049 traced_retrograde = true;
4050 } else {
39037602 4051 min_kdbp->kd_prev_timebase = earliest_time;
5ba3f43e 4052 }
6d2010ae 4053nextevent:
0c530ab8
A
4054 tempbuf_count--;
4055 tempbuf_number++;
b0d623f7 4056 tempbuf++;
6d2010ae 4057
0a7de745 4058 if ((RAW_file_written += sizeof(kd_buf)) >= RAW_FLUSH_SIZE) {
6d2010ae 4059 break;
0a7de745 4060 }
0c530ab8
A
4061 }
4062 if (tempbuf_number) {
d9a64523
A
4063 /*
4064 * Remember the latest timestamp of events that we've merged so we
4065 * don't think we've lost events later.
4066 */
4067 uint64_t latest_time = kdbg_get_timestamp(tempbuf - 1);
4068 if (kd_ctrl_page.oldest_time < latest_time) {
4069 kd_ctrl_page.oldest_time = latest_time;
4070 }
3e170ce0 4071 if (file_version == RAW_VERSION3) {
0a7de745 4072 if (!(kdbg_write_v3_event_chunk_header(buffer, V3_RAW_EVENTS, (tempbuf_number * sizeof(kd_buf)), vp, ctx))) {
3e170ce0
A
4073 error = EFAULT;
4074 goto check_error;
4075 }
0a7de745 4076 if (buffer) {
3e170ce0 4077 buffer += (sizeof(kd_chunk_header_v3) + sizeof(uint64_t));
0a7de745 4078 }
b0d623f7 4079
3e170ce0
A
4080 assert(count >= (sizeof(kd_chunk_header_v3) + sizeof(uint64_t)));
4081 count -= (sizeof(kd_chunk_header_v3) + sizeof(uint64_t));
4082 *number += (sizeof(kd_chunk_header_v3) + sizeof(uint64_t));
4083 }
b0d623f7 4084 if (vp) {
3e170ce0
A
4085 size_t write_size = tempbuf_number * sizeof(kd_buf);
4086 error = kdbg_write_to_vnode((caddr_t)kdcopybuf, write_size, vp, ctx, RAW_file_offset);
0a7de745 4087 if (!error) {
3e170ce0 4088 RAW_file_offset += write_size;
0a7de745 4089 }
d9a64523 4090
6d2010ae 4091 if (RAW_file_written >= RAW_FLUSH_SIZE) {
813fb2f6 4092 error = VNOP_FSYNC(vp, MNT_NOWAIT, ctx);
6d2010ae
A
4093
4094 RAW_file_written = 0;
4095 }
b0d623f7
A
4096 } else {
4097 error = copyout(kdcopybuf, buffer, tempbuf_number * sizeof(kd_buf));
4098 buffer += (tempbuf_number * sizeof(kd_buf));
4099 }
3e170ce0 4100check_error:
b0d623f7
A
4101 if (error) {
4102 *number = 0;
0c530ab8
A
4103 error = EINVAL;
4104 break;
6601e61a 4105 }
0c530ab8
A
4106 count -= tempbuf_number;
4107 *number += tempbuf_number;
0c530ab8 4108 }
cb323159 4109 if (out_of_events == true) {
0a7de745
A
4110 /*
4111 * all trace buffers are empty
4112 */
4113 break;
4114 }
89b3af67 4115
0a7de745
A
4116 if ((tempbuf_count = count) > KDCOPYBUF_COUNT) {
4117 tempbuf_count = KDCOPYBUF_COUNT;
4118 }
0c530ab8 4119 }
0a7de745 4120 if (!(old_kdebug_flags & KDBG_NOWRAP)) {
d9a64523 4121 enable_wrap(old_kdebug_slowcheck);
0c530ab8 4122 }
39037602 4123 thread_clear_eager_preempt(current_thread());
0a7de745 4124 return error;
6601e61a 4125}
4452a7af 4126
cb323159
A
4127#define KDEBUG_TEST_CODE(code) BSDDBG_CODE(DBG_BSD_KDEBUG_TEST, (code))
4128
4129/*
4130 * A test IOP for the SYNC_FLUSH callback.
4131 */
4132
4133static int sync_flush_iop = 0;
4134
4135static void
4136sync_flush_callback(void * __unused context, kd_callback_type reason,
4137 void * __unused arg)
4138{
4139 assert(sync_flush_iop > 0);
4140
4141 if (reason == KD_CALLBACK_SYNC_FLUSH) {
4142 kernel_debug_enter(sync_flush_iop, KDEBUG_TEST_CODE(0xff),
4143 kdbg_timestamp(), 0, 0, 0, 0, 0);
4144 }
4145}
4146
4147static struct kd_callback sync_flush_kdcb = {
4148 .func = sync_flush_callback,
4149 .iop_name = "test_sf",
4150};
4151
39037602 4152static int
5ba3f43e 4153kdbg_test(size_t flavor)
39037602 4154{
39037602 4155 int code = 0;
5ba3f43e 4156 int dummy_iop = 0;
39037602 4157
5ba3f43e
A
4158 switch (flavor) {
4159 case 1:
4160 /* try each macro */
4161 KDBG(KDEBUG_TEST_CODE(code)); code++;
4162 KDBG(KDEBUG_TEST_CODE(code), 1); code++;
4163 KDBG(KDEBUG_TEST_CODE(code), 1, 2); code++;
4164 KDBG(KDEBUG_TEST_CODE(code), 1, 2, 3); code++;
4165 KDBG(KDEBUG_TEST_CODE(code), 1, 2, 3, 4); code++;
4166
4167 KDBG_RELEASE(KDEBUG_TEST_CODE(code)); code++;
4168 KDBG_RELEASE(KDEBUG_TEST_CODE(code), 1); code++;
4169 KDBG_RELEASE(KDEBUG_TEST_CODE(code), 1, 2); code++;
4170 KDBG_RELEASE(KDEBUG_TEST_CODE(code), 1, 2, 3); code++;
4171 KDBG_RELEASE(KDEBUG_TEST_CODE(code), 1, 2, 3, 4); code++;
4172
4173 KDBG_FILTERED(KDEBUG_TEST_CODE(code)); code++;
4174 KDBG_FILTERED(KDEBUG_TEST_CODE(code), 1); code++;
4175 KDBG_FILTERED(KDEBUG_TEST_CODE(code), 1, 2); code++;
4176 KDBG_FILTERED(KDEBUG_TEST_CODE(code), 1, 2, 3); code++;
4177 KDBG_FILTERED(KDEBUG_TEST_CODE(code), 1, 2, 3, 4); code++;
4178
d9a64523
A
4179 KDBG_RELEASE_NOPROCFILT(KDEBUG_TEST_CODE(code)); code++;
4180 KDBG_RELEASE_NOPROCFILT(KDEBUG_TEST_CODE(code), 1); code++;
4181 KDBG_RELEASE_NOPROCFILT(KDEBUG_TEST_CODE(code), 1, 2); code++;
4182 KDBG_RELEASE_NOPROCFILT(KDEBUG_TEST_CODE(code), 1, 2, 3); code++;
4183 KDBG_RELEASE_NOPROCFILT(KDEBUG_TEST_CODE(code), 1, 2, 3, 4); code++;
4184
5ba3f43e
A
4185 KDBG_DEBUG(KDEBUG_TEST_CODE(code)); code++;
4186 KDBG_DEBUG(KDEBUG_TEST_CODE(code), 1); code++;
4187 KDBG_DEBUG(KDEBUG_TEST_CODE(code), 1, 2); code++;
4188 KDBG_DEBUG(KDEBUG_TEST_CODE(code), 1, 2, 3); code++;
4189 KDBG_DEBUG(KDEBUG_TEST_CODE(code), 1, 2, 3, 4); code++;
4190 break;
0c530ab8 4191
5ba3f43e
A
4192 case 2:
4193 if (kd_ctrl_page.kdebug_iops) {
4194 /* avoid the assertion in kernel_debug_enter for a valid IOP */
4195 dummy_iop = kd_ctrl_page.kdebug_iops[0].cpu_id;
4196 }
4197
4198 /* ensure old timestamps are not emitted from kernel_debug_enter */
4199 kernel_debug_enter(dummy_iop, KDEBUG_TEST_CODE(code),
cb323159 4200 100 /* very old timestamp */, 0, 0, 0, 0, 0);
5ba3f43e
A
4201 code++;
4202 kernel_debug_enter(dummy_iop, KDEBUG_TEST_CODE(code),
cb323159 4203 kdbg_timestamp(), 0, 0, 0, 0, 0);
5ba3f43e
A
4204 code++;
4205 break;
d9a64523 4206
cb323159
A
4207 case 3:
4208 if (kd_ctrl_page.kdebug_iops) {
4209 dummy_iop = kd_ctrl_page.kdebug_iops[0].cpu_id;
4210 }
4211 kernel_debug_enter(dummy_iop, KDEBUG_TEST_CODE(code),
4212 kdbg_timestamp() * 2 /* !!! */, 0, 0, 0, 0, 0);
4213 break;
4214
4215 case 4:
4216 if (!sync_flush_iop) {
4217 sync_flush_iop = kernel_debug_register_callback(
4218 sync_flush_kdcb);
4219 assert(sync_flush_iop > 0);
4220 }
4221 break;
4222
5ba3f43e
A
4223 default:
4224 return ENOTSUP;
4225 }
5ba3f43e
A
4226
4227 return 0;
55e303ae 4228}
0c530ab8 4229
cb323159
A
4230#undef KDEBUG_TEST_CODE
4231
39037602 4232void
cb323159 4233kdebug_init(unsigned int n_events, char *filter_desc, bool wrapping)
0c530ab8 4234{
39037602
A
4235 assert(filter_desc != NULL);
4236
5ba3f43e 4237#if defined(__x86_64__)
39037602
A
4238 /* only trace MACH events when outputting kdebug to serial */
4239 if (kdebug_serial) {
4240 n_events = 1;
4241 if (filter_desc[0] == '\0') {
4242 filter_desc[0] = 'C';
4243 filter_desc[1] = '1';
4244 filter_desc[2] = '\0';
4245 }
3e170ce0 4246 }
5ba3f43e 4247#endif /* defined(__x86_64__) */
0c530ab8 4248
39037602
A
4249 if (log_leaks && n_events == 0) {
4250 n_events = 200000;
4251 }
0c530ab8 4252
cb323159 4253 kdebug_trace_start(n_events, filter_desc, wrapping, false);
0c530ab8
A
4254}
4255
39037602
A
4256static void
4257kdbg_set_typefilter_string(const char *filter_desc)
0c530ab8 4258{
39037602 4259 char *end = NULL;
39236c6e 4260
5ba3f43e 4261 ktrace_assert_lock_held();
fe8ab488 4262
39037602 4263 assert(filter_desc != NULL);
0c530ab8 4264
39037602
A
4265 typefilter_reject_all(kdbg_typefilter);
4266 typefilter_allow_class(kdbg_typefilter, DBG_TRACE);
4267
4268 /* if the filter description starts with a number, assume it's a csc */
0a7de745 4269 if (filter_desc[0] >= '0' && filter_desc[0] <= '9') {
39037602
A
4270 unsigned long csc = strtoul(filter_desc, NULL, 0);
4271 if (filter_desc != end && csc <= KDBG_CSC_MAX) {
4272 typefilter_allow_csc(kdbg_typefilter, csc);
4273 }
4274 return;
39236c6e
A
4275 }
4276
39037602
A
4277 while (filter_desc[0] != '\0') {
4278 unsigned long allow_value;
0c530ab8 4279
39037602
A
4280 char filter_type = filter_desc[0];
4281 if (filter_type != 'C' && filter_type != 'S') {
4282 return;
4283 }
4284 filter_desc++;
d41d1dae 4285
39037602
A
4286 allow_value = strtoul(filter_desc, &end, 0);
4287 if (filter_desc == end) {
4288 /* cannot parse as integer */
4289 return;
4290 }
0c530ab8 4291
39037602 4292 switch (filter_type) {
0a7de745
A
4293 case 'C':
4294 if (allow_value <= KDBG_CLASS_MAX) {
4295 typefilter_allow_class(kdbg_typefilter, allow_value);
4296 } else {
4297 /* illegal class */
4298 return;
4299 }
4300 break;
4301 case 'S':
4302 if (allow_value <= KDBG_CSC_MAX) {
4303 typefilter_allow_csc(kdbg_typefilter, allow_value);
4304 } else {
4305 /* illegal class subclass */
39037602 4306 return;
0a7de745
A
4307 }
4308 break;
4309 default:
4310 return;
39037602
A
4311 }
4312
4313 /* advance to next filter entry */
4314 filter_desc = end;
4315 if (filter_desc[0] == ',') {
4316 filter_desc++;
4317 }
4318 }
3e170ce0 4319}
2d21ac55 4320
3e170ce0 4321/*
39037602
A
4322 * This function is meant to be called from the bootstrap thread or coming out
4323 * of acpi_idle_kernel.
3e170ce0 4324 */
39037602
A
4325void
4326kdebug_trace_start(unsigned int n_events, const char *filter_desc,
cb323159 4327 bool wrapping, bool at_wake)
3e170ce0 4328{
39037602 4329 if (!n_events) {
5ba3f43e 4330 kd_early_done = true;
39037602 4331 return;
0c530ab8
A
4332 }
4333
5ba3f43e 4334 ktrace_start_single_threaded();
2d21ac55 4335
2d21ac55 4336 kdbg_lock_init();
39236c6e 4337
39037602 4338 ktrace_kernel_configure(KTRACE_KDEBUG);
fe8ab488 4339
39037602 4340 kdbg_set_nkdbufs(n_events);
39236c6e 4341
39037602 4342 kernel_debug_string_early("start_kern_tracing");
39236c6e 4343
cb323159 4344 if (kdbg_reinit(true)) {
39037602
A
4345 printf("error from kdbg_reinit, kernel tracing not started\n");
4346 goto out;
4347 }
39236c6e 4348
39037602
A
4349 /*
4350 * Wrapping is disabled because boot and wake tracing is interested in
4351 * the earliest events, at the expense of later ones.
4352 */
a39ff7e2
A
4353 if (!wrapping) {
4354 uint32_t old1, old2;
4355 (void)disable_wrap(&old1, &old2);
4356 }
39037602
A
4357
4358 if (filter_desc && filter_desc[0] != '\0') {
4359 if (kdbg_initialize_typefilter(NULL) == KERN_SUCCESS) {
4360 kdbg_set_typefilter_string(filter_desc);
4361 kdbg_enable_typefilter();
39236c6e 4362 }
39037602 4363 }
fe8ab488 4364
39037602
A
4365 /*
4366 * Hold off interrupts between getting a thread map and enabling trace
4367 * and until the early traces are recorded.
4368 */
cb323159 4369 bool s = ml_set_interrupts_enabled(false);
fe8ab488 4370
5ba3f43e 4371 if (at_wake) {
39037602
A
4372 kdbg_thrmap_init();
4373 }
b0d623f7 4374
cb323159 4375 kdbg_set_tracing_enabled(true, KDEBUG_ENABLE_TRACE | (kdebug_serial ?
0a7de745 4376 KDEBUG_ENABLE_SERIAL : 0));
b0d623f7 4377
5ba3f43e
A
4378 if (!at_wake) {
4379 /*
4380 * Transfer all very early events from the static buffer into the real
4381 * buffers.
4382 */
4383 kernel_debug_early_end();
4384 }
b0d623f7 4385
39037602 4386 ml_set_interrupts_enabled(s);
fe8ab488 4387
39037602
A
4388 printf("kernel tracing started with %u events\n", n_events);
4389
4390#if KDEBUG_MOJO_TRACE
4391 if (kdebug_serial) {
4392 printf("serial output enabled with %lu named events\n",
0a7de745 4393 sizeof(kd_events) / sizeof(kd_event_t));
39037602 4394 }
5ba3f43e 4395#endif /* KDEBUG_MOJO_TRACE */
fe8ab488 4396
39037602 4397out:
5ba3f43e 4398 ktrace_end_single_threaded();
fe8ab488
A
4399}
4400
b0d623f7
A
4401void
4402kdbg_dump_trace_to_file(const char *filename)
4403{
39037602
A
4404 vfs_context_t ctx;
4405 vnode_t vp;
4406 size_t write_size;
5ba3f43e 4407 int ret;
b0d623f7 4408
5ba3f43e 4409 ktrace_lock();
b0d623f7 4410
39037602
A
4411 if (!(kdebug_enable & KDEBUG_ENABLE_TRACE)) {
4412 goto out;
4413 }
b0d623f7 4414
39037602
A
4415 if (ktrace_get_owning_pid() != 0) {
4416 /*
4417 * Another process owns ktrace and is still active, disable tracing to
5ba3f43e 4418 * prevent wrapping.
39037602
A
4419 */
4420 kdebug_enable = 0;
4421 kd_ctrl_page.enabled = 0;
4422 commpage_update_kdebug_state();
4423 goto out;
b0d623f7 4424 }
39037602 4425
a39ff7e2 4426 KDBG_RELEASE(TRACE_WRITING_EVENTS | DBG_FUNC_START);
b0d623f7
A
4427
4428 kdebug_enable = 0;
6d2010ae 4429 kd_ctrl_page.enabled = 0;
39037602 4430 commpage_update_kdebug_state();
b0d623f7
A
4431
4432 ctx = vfs_context_kernel();
4433
39037602
A
4434 if (vnode_open(filename, (O_CREAT | FWRITE | O_NOFOLLOW), 0600, 0, &vp, ctx)) {
4435 goto out;
4436 }
b0d623f7 4437
39037602 4438 kdbg_write_thread_map(vp, ctx);
b0d623f7 4439
39037602 4440 write_size = nkdbufs * sizeof(kd_buf);
5ba3f43e
A
4441 ret = kdbg_read(0, &write_size, vp, ctx, RAW_VERSION1);
4442 if (ret) {
4443 goto out_close;
4444 }
b0d623f7 4445
5ba3f43e
A
4446 /*
4447 * Wait to synchronize the file to capture the I/O in the
4448 * TRACE_WRITING_EVENTS interval.
4449 */
4450 ret = VNOP_FSYNC(vp, MNT_WAIT, ctx);
4451
4452 /*
4453 * Balance the starting TRACE_WRITING_EVENTS tracepoint manually.
4454 */
4455 kd_buf end_event = {
4456 .debugid = TRACE_WRITING_EVENTS | DBG_FUNC_END,
4457 .arg1 = write_size,
4458 .arg2 = ret,
4459 .arg5 = thread_tid(current_thread()),
4460 };
4461 kdbg_set_timestamp_and_cpu(&end_event, kdbg_timestamp(),
0a7de745 4462 cpu_number());
5ba3f43e
A
4463
4464 /* this is best effort -- ignore any errors */
4465 (void)kdbg_write_to_vnode((caddr_t)&end_event, sizeof(kd_buf), vp, ctx,
0a7de745 4466 RAW_file_offset);
5ba3f43e
A
4467
4468out_close:
39037602 4469 vnode_close(vp, FWRITE, ctx);
b0d623f7 4470 sync(current_proc(), (void *)NULL, (int *)NULL);
39037602
A
4471
4472out:
5ba3f43e 4473 ktrace_unlock();
b0d623f7 4474}
6d2010ae 4475
5ba3f43e
A
4476static int
4477kdbg_sysctl_continuous SYSCTL_HANDLER_ARGS
4478{
4479#pragma unused(oidp, arg1, arg2)
4480 int value = kdbg_continuous_time;
4481 int ret = sysctl_io_number(req, value, sizeof(value), &value, NULL);
4482
4483 if (ret || !req->newptr) {
4484 return ret;
4485 }
4486
4487 kdbg_continuous_time = value;
4488 return 0;
4489}
4490
4491SYSCTL_NODE(_kern, OID_AUTO, kdbg, CTLFLAG_RD | CTLFLAG_LOCKED, 0,
0a7de745 4492 "kdbg");
5ba3f43e
A
4493
4494SYSCTL_PROC(_kern_kdbg, OID_AUTO, experimental_continuous,
0a7de745
A
4495 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED, 0,
4496 sizeof(int), kdbg_sysctl_continuous, "I",
4497 "Set kdebug to use mach_continuous_time");
5ba3f43e 4498
d9a64523 4499SYSCTL_INT(_kern_kdbg, OID_AUTO, debug,
0a7de745
A
4500 CTLFLAG_RW | CTLFLAG_LOCKED,
4501 &kdbg_debug, 0, "Set kdebug debug mode");
d9a64523 4502
5ba3f43e 4503SYSCTL_QUAD(_kern_kdbg, OID_AUTO, oldest_time,
0a7de745
A
4504 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED,
4505 &kd_ctrl_page.oldest_time,
4506 "Find the oldest timestamp still in trace");
5ba3f43e 4507
04b8595b
A
4508#if KDEBUG_MOJO_TRACE
4509static kd_event_t *
4510binary_search(uint32_t id)
4511{
4512 int low, high, mid;
4513
4514 low = 0;
0a7de745 4515 high = (int)(sizeof(kd_events) / sizeof(kd_event_t)) - 1;
04b8595b 4516
cb323159 4517 while (true) {
04b8595b
A
4518 mid = (low + high) / 2;
4519
0a7de745 4520 if (low > high) {
04b8595b 4521 return NULL; /* failed */
0a7de745 4522 } else if (low + 1 >= high) {
04b8595b 4523 /* We have a match */
0a7de745 4524 if (kd_events[high].id == id) {
04b8595b 4525 return &kd_events[high];
0a7de745 4526 } else if (kd_events[low].id == id) {
04b8595b 4527 return &kd_events[low];
0a7de745 4528 } else {
04b8595b 4529 return NULL; /* search failed */
0a7de745
A
4530 }
4531 } else if (id < kd_events[mid].id) {
04b8595b 4532 high = mid;
0a7de745 4533 } else {
04b8595b 4534 low = mid;
0a7de745
A
4535 }
4536 }
04b8595b
A
4537}
4538
4539/*
4540 * Look up event id to get name string.
4541 * Using a per-cpu cache of a single entry
4542 * before resorting to a binary search of the full table.
4543 */
0a7de745
A
4544#define NCACHE 1
4545static kd_event_t *last_hit[MAX_CPUS];
04b8595b
A
4546static kd_event_t *
4547event_lookup_cache(uint32_t cpu, uint32_t id)
4548{
0a7de745 4549 if (last_hit[cpu] == NULL || last_hit[cpu]->id != id) {
04b8595b 4550 last_hit[cpu] = binary_search(id);
0a7de745 4551 }
04b8595b
A
4552 return last_hit[cpu];
4553}
4554
0a7de745 4555static uint64_t kd_last_timstamp;
04b8595b
A
4556
4557static void
4558kdebug_serial_print(
0a7de745
A
4559 uint32_t cpunum,
4560 uint32_t debugid,
4561 uint64_t timestamp,
4562 uintptr_t arg1,
4563 uintptr_t arg2,
4564 uintptr_t arg3,
4565 uintptr_t arg4,
4566 uintptr_t threadid
04b8595b
A
4567 )
4568{
0a7de745
A
4569 char kprintf_line[192];
4570 char event[40];
4571 uint64_t us = timestamp / NSEC_PER_USEC;
4572 uint64_t us_tenth = (timestamp % NSEC_PER_USEC) / 100;
4573 uint64_t delta = timestamp - kd_last_timstamp;
4574 uint64_t delta_us = delta / NSEC_PER_USEC;
4575 uint64_t delta_us_tenth = (delta % NSEC_PER_USEC) / 100;
4576 uint32_t event_id = debugid & KDBG_EVENTID_MASK;
4577 const char *command;
4578 const char *bra;
4579 const char *ket;
4580 kd_event_t *ep;
04b8595b
A
4581
4582 /* event time and delta from last */
4583 snprintf(kprintf_line, sizeof(kprintf_line),
0a7de745
A
4584 "%11llu.%1llu %8llu.%1llu ",
4585 us, us_tenth, delta_us, delta_us_tenth);
04b8595b
A
4586
4587
4588 /* event (id or name) - start prefixed by "[", end postfixed by "]" */
4589 bra = (debugid & DBG_FUNC_START) ? "[" : " ";
4590 ket = (debugid & DBG_FUNC_END) ? "]" : " ";
4591 ep = event_lookup_cache(cpunum, event_id);
4592 if (ep) {
0a7de745 4593 if (strlen(ep->name) < sizeof(event) - 3) {
04b8595b 4594 snprintf(event, sizeof(event), "%s%s%s",
0a7de745
A
4595 bra, ep->name, ket);
4596 } else {
04b8595b 4597 snprintf(event, sizeof(event), "%s%x(name too long)%s",
0a7de745
A
4598 bra, event_id, ket);
4599 }
04b8595b
A
4600 } else {
4601 snprintf(event, sizeof(event), "%s%x%s",
0a7de745 4602 bra, event_id, ket);
04b8595b
A
4603 }
4604 snprintf(kprintf_line + strlen(kprintf_line),
0a7de745
A
4605 sizeof(kprintf_line) - strlen(kprintf_line),
4606 "%-40s ", event);
04b8595b
A
4607
4608 /* arg1 .. arg4 with special cases for strings */
4609 switch (event_id) {
0a7de745
A
4610 case VFS_LOOKUP:
4611 case VFS_LOOKUP_DONE:
04b8595b
A
4612 if (debugid & DBG_FUNC_START) {
4613 /* arg1 hex then arg2..arg4 chars */
4614 snprintf(kprintf_line + strlen(kprintf_line),
0a7de745
A
4615 sizeof(kprintf_line) - strlen(kprintf_line),
4616 "%-16lx %-8s%-8s%-8s ",
4617 arg1, (char*)&arg2, (char*)&arg3, (char*)&arg4);
04b8595b
A
4618 break;
4619 }
0a7de745
A
4620 /* else fall through for arg1..arg4 chars */
4621 case TRACE_STRING_EXEC:
4622 case TRACE_STRING_NEWTHREAD:
4623 case TRACE_INFO_STRING:
04b8595b 4624 snprintf(kprintf_line + strlen(kprintf_line),
0a7de745
A
4625 sizeof(kprintf_line) - strlen(kprintf_line),
4626 "%-8s%-8s%-8s%-8s ",
4627 (char*)&arg1, (char*)&arg2, (char*)&arg3, (char*)&arg4);
04b8595b 4628 break;
0a7de745 4629 default:
04b8595b 4630 snprintf(kprintf_line + strlen(kprintf_line),
0a7de745
A
4631 sizeof(kprintf_line) - strlen(kprintf_line),
4632 "%-16lx %-16lx %-16lx %-16lx",
4633 arg1, arg2, arg3, arg4);
04b8595b
A
4634 }
4635
4636 /* threadid, cpu and command name */
4637 if (threadid == (uintptr_t)thread_tid(current_thread()) &&
4638 current_proc() &&
0a7de745 4639 current_proc()->p_comm[0]) {
04b8595b 4640 command = current_proc()->p_comm;
0a7de745 4641 } else {
04b8595b 4642 command = "-";
0a7de745 4643 }
04b8595b 4644 snprintf(kprintf_line + strlen(kprintf_line),
0a7de745
A
4645 sizeof(kprintf_line) - strlen(kprintf_line),
4646 " %-16lx %-2d %s\n",
4647 threadid, cpunum, command);
4648
04b8595b
A
4649 kprintf("%s", kprintf_line);
4650 kd_last_timstamp = timestamp;
4651}
39037602 4652
04b8595b 4653#endif