1 /*
2 * Copyright (c) 2000-2021 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29 #ifndef BSD_KDEBUG_PRIVATE_H
30 #define BSD_KDEBUG_PRIVATE_H
31
32 #include <os/base.h>
33 #include <stdint.h>
34 #include <stdbool.h>
35 #include <sys/cdefs.h>
36 #include <sys/kdebug.h>
37
38 #if !KERNEL
39
40 #include <Availability.h>
41
42 __BEGIN_DECLS
43
44 #pragma mark - User space SPI
45
46 // Internal software can trace events into kdebug, but the os_signpost(3)
47 // interfaces in `<os/signpost.h>` are recommended.
48 //
49 // kdebug_trace(KDBG_EVENTID(DBG_XPC, 15, 1), 1, 2, 3, 4);
50 //
51 // The performance impact when kernel tracing is not enabled is minimal.
52 // However, when tracing is enabled, each event requires a syscall.
53 //
54 // Classes can be reserved by filing a Radar in xnu | ktrace.
55 //
56 // 64-bit arguments may be truncated if the system is using a 32-bit kernel.
57 //
58 // On error, -1 will be returned and errno will indicate the error.
59 int kdebug_trace(uint32_t debugid, uint64_t arg1, uint64_t arg2, uint64_t arg3,
60 uint64_t arg4)
61 __API_AVAILABLE(macos(10.0), ios(8), tvos(8), watchos(1));
62
63 // Although the performance impact of kdebug_trace() when tracing is disabled is
64 // minimal, it may require the caller to perform an expensive calculation or
65 // summarization. This cost can be skipped by checking the kdebug_is_enabled()
66 // predicate:
67 //
68 // if (kdebug_is_enabled(KDBG_CODE(DBG_XPC, 15, 1))) {
69 // uint64_t arg1 = ...;
70 // uint64_t arg2 = ...;
71 // kdebug_trace(KDBG_EVENTID(DBG_XPC, 15, 1), arg1, arg2, 0, 0);
72 // }
73 //
74 // true is returned iff tracing is enabled for the debug ID at the time of the
75 // check.
76 extern bool kdebug_is_enabled(uint32_t debugid)
77 __API_AVAILABLE(macos(10.12), ios(10), watchos(3), tvos(10));
78
79 // Returns true if kdebug is using continuous time for its events, and false
80 // otherwise.
81 extern bool kdebug_using_continuous_time(void)
82 __API_AVAILABLE(macos(10.15), ios(13), tvos(13), watchos(6));
83
84 // Convert an absolute time to a kdebug timestamp.
85 extern uint64_t kdebug_timestamp_from_absolute(uint64_t abstime)
86 __API_AVAILABLE(macos(12), ios(15), tvos(15), watchos(8));
87
88 // Convert a continuous time to a kdebug timestamp.
89 extern uint64_t kdebug_timestamp_from_continuous(uint64_t conttime)
90 __API_AVAILABLE(macos(12), ios(15), tvos(15), watchos(8));
91
92 // Capture a kdebug timestamp for the current time.
93 extern uint64_t kdebug_timestamp(void)
94 __API_AVAILABLE(macos(12), ios(15), tvos(15), watchos(8));
95
96 /// @function kdebug_trace_string
97 ///
98 /// @discussion
99 /// This function emits strings to kdebug trace along with an ID and allows
100 /// for previously-traced strings to be overwritten and invalidated.
101 ///
102 /// To start tracing a string and generate an ID to use to refer to it:
103 ///
104 /// string_id = kdebug_trace_string(debugid, 0, "string");
105 ///
106 /// To replace a string previously traced:
107 ///
108 /// string_id = kdebug_trace_string(debugid, string_id, "new string");
109 ///
110 /// To invalidate a string ID:
111 ///
112 /// string_id = kdebug_trace_string(debugid, string_id, NULL);
113 ///
114 /// To check for errors:
115 ///
116 /// if ((int64_t)string_id == -1) { perror("string error") }
117 ///
118 /// @param debugid
119 /// The `debugid` to check if its enabled before tracing and include as
120 /// an argument in the event containing the string.
121 ///
122 /// Some classes or subclasses are reserved for specific uses and are not
123 /// allowed to be used with this function. No function qualifiers are
124 /// allowed on `debugid`.
125 ///
126 /// @param str_id
127 /// When 0, a new ID will be generated and returned if tracing is
128 /// enabled.
129 ///
130 /// Otherwise `str_id` must contain an ID that was previously generated
131 /// with this function. Clents should pass NULL in `str` if `str_id`
132 /// is no longer in use. Otherwise, the string previously mapped to
133 /// `str_id` will be overwritten with the contents of `str`.
134 ///
135 /// @param str
136 /// A NUL-terminated 'C' string containing the characters that should be
137 /// traced alongside `str_id`.
138 ///
139 /// If necessary, the string will be truncated at an
140 /// implementation-defined length of at least PATH_MAX characters. The string
141 /// must not be the empty string, but can be NULL if a valid `str_id` is
142 /// provided.
143 ///
144 /// @return
145 /// 0 if tracing is disabled or `debugid` is being filtered out of trace.
146 /// It can also return (int64_t)-1 if an error occured. Otherwise,
147 /// it returns the ID to use to refer to the string in future
148 /// kdebug_trace(2) calls.
149 ///
150 /// The errors that can occur are:
151 ///
152 /// EINVAL
153 /// There are function qualifiers on `debugid`, `str` is empty, or
154 /// `str_id` was not generated by this function.
155 /// EPERM
156 /// The `debugid`'s class or subclass is reserved for internal use.
157 /// EFAULT
158 /// `str` is an invalid address or NULL when `str_id` is 0.
159 extern uint64_t kdebug_trace_string(uint32_t debugid, uint64_t str_id,
160 const char *str)
161 __API_AVAILABLE(macos(10.11), ios(9), watchos(2), tvos(9));
162
163 // Returns a pointer to the userspace typefilter, if one is available.
164 // May return NULL.
165 extern void *kdebug_typefilter(void)
166 __API_AVAILABLE(macos(10.12), ios(10), watchos(3), tvos(10));
167
168 #else
169 __BEGIN_DECLS
170 #endif /* !KERNEL */
171
172 #pragma mark - Private debug IDs
173
174 #define DBG_PPT 36
175 #define DBG_PERFCTRL 39
176 #define DBG_CLPC 50
177 #define DBG_MUSE 52
178
179 #define DBG_ANS 128
180 #define DBG_SIO 129
181 #define DBG_SEP 130
182 #define DBG_ISP 131
183 #define DBG_OSCAR 132
184 #define DBG_EMBEDDEDGFX 133
185 #define DBG_PMP 134
186 #define DBG_RTKIT 135
187 #define DBG_DCP 136
188 #define DBG_KMP 137
189
190 // DBG_SKYWALK is the same as DBG_DLIL, so don't reuse subclasses
191 #define DBG_SKYWALK_ALWAYSON 0x10
192 #define DBG_SKYWALK_FLOWSWITCH 0x11
193 #define DBG_SKYWALK_NETIF 0x12
194 #define DBG_SKYWALK_CHANNEL 0x13
195 #define DBG_SKYWALK_PACKET 0x14
196
197 // DBG_AQM is the same as DBG_DLIL and DBG_SKYWALK, so don't reuse subclasses
198 #define DBG_AQM_ALWAYSON 0x30
199 #define DBG_AQM_STATS 0x31
200
201 #define PPT_TEST 0x01
202 #define PPT_JETSAM_HIWAT 0x02
203 #define PPT_JETSAM_TOPPROC 0x03
204
205 // DBG_SECURITY private subclasses
206 #define DBG_SEC_SSMA 0x02
207 #define DBG_SEC_ERM 0x03
208
209 #define SKYWALKDBG_CODE(SubClass, code) KDBG_CODE(DBG_DLIL, SubClass, code)
210 #define PPTDBG_CODE(SubClass, code) KDBG_CODE(DBG_PPT, SubClass, code)
211 #define PERFCTRL_CODE(SubClass, code) KDBG_CODE(DBG_PERFCTRL, SubClass, code)
212 #define AQMDBG_CODE(SubClass, code) KDBG_CODE(DBG_DLIL, SubClass, code)
213
214 #if !defined(DRIVERKIT)
215
216 extern unsigned int kdebug_enable;
217
218 // Options for `kdebug_enable`.
219
220 // Enable tracing.
221 #define KDEBUG_ENABLE_TRACE 0x001U
222 // Whether timestamps are continuous times or absolute times.
223 #define KDEBUG_ENABLE_CONT_TIME 0x020U
224
225 #define KDEBUG_TRACE (KDEBUG_ENABLE_TRACE)
226
227 // Control which kernel events are compiled in under different build
228 // configurations.
229
230 // No kdebug events are emitted with the macros.
231 #define KDEBUG_LEVEL_NONE 0
232 // In-System Tracing exposes a limited set of events for release kernels.
233 #define KDEBUG_LEVEL_IST 1
234 // The default for development kernels.
235 #define KDEBUG_LEVEL_STANDARD 2
236 // Truly verbose, debug-level logging, only set manually.
237 #define KDEBUG_LEVEL_FULL 3
238
239 // Use configuration options to set the kdebug level.
240 #if NO_KDEBUG
241 #define KDEBUG_LEVEL KDEBUG_LEVEL_NONE
242 #elif IST_KDEBUG
243 #define KDEBUG_LEVEL KDEBUG_LEVEL_IST
244 #elif KDEBUG
245 #define KDEBUG_LEVEL KDEBUG_LEVEL_FULL
246 #else // !NO_KDEBUG && !IST_KDEBUG && !KDEBUG
247 #define KDEBUG_LEVEL KDEBUG_LEVEL_STANDARD
248 #endif // !NO_KDEBUG && !IST_KDEBUG && !KDEBUG
249
250 #pragma mark - Implementation details
251
252 // Ensure that LP32 and LP64 variants of arm64 use the same kd_buf structure.
253 #if defined(__arm64__)
254 typedef uint64_t kd_buf_argtype;
255 #else // defined(__arm64__)
256 typedef uintptr_t kd_buf_argtype;
257 #endif // !defined(__arm64__)
258
259 // The main event ABI as recorded in the kernel.
260
261 typedef struct {
262 uint64_t timestamp;
263 kd_buf_argtype arg1;
264 kd_buf_argtype arg2;
265 kd_buf_argtype arg3;
266 kd_buf_argtype arg4;
267 kd_buf_argtype arg5; // Always the thread ID.
268 uint32_t debugid;
269 // Ensure that LP32 and LP64 variants of arm64 use the same kd_buf structure.
270 #if defined(__LP64__) || defined(__arm64__)
271 uint32_t cpuid;
272 kd_buf_argtype unused;
273 #endif // defined(__LP64__) || defined(__arm64__)
274 } kd_buf;
275
276 #if defined(__LP64__) || defined(__arm64__)
277
278 #define KDBG_TIMESTAMP_MASK 0xffffffffffffffffULL
279 static inline void
kdbg_set_cpu(kd_buf * kp,int cpu)280 kdbg_set_cpu(kd_buf *kp, int cpu)
281 {
282 kp->cpuid = (unsigned int)cpu;
283 }
284 static inline int
kdbg_get_cpu(kd_buf * kp)285 kdbg_get_cpu(kd_buf *kp)
286 {
287 return (int)kp->cpuid;
288 }
289 static inline void
kdbg_set_timestamp(kd_buf * kp,uint64_t thetime)290 kdbg_set_timestamp(kd_buf *kp, uint64_t thetime)
291 {
292 kp->timestamp = thetime;
293 }
294 static inline uint64_t
kdbg_get_timestamp(kd_buf * kp)295 kdbg_get_timestamp(kd_buf *kp)
296 {
297 return kp->timestamp;
298 }
299 static inline void
kdbg_set_timestamp_and_cpu(kd_buf * kp,uint64_t thetime,int cpu)300 kdbg_set_timestamp_and_cpu(kd_buf *kp, uint64_t thetime, int cpu)
301 {
302 kdbg_set_timestamp(kp, thetime);
303 kdbg_set_cpu(kp, cpu);
304 }
305 #else // defined(__LP64__) || defined(__arm64__)
306 #define KDBG_TIMESTAMP_MASK 0x00ffffffffffffffULL
307 #define KDBG_CPU_MASK 0xff00000000000000ULL
308 #define KDBG_CPU_SHIFT 56
309 static inline void
kdbg_set_cpu(kd_buf * kp,int cpu)310 kdbg_set_cpu(kd_buf *kp, int cpu)
311 {
312 kp->timestamp = (kp->timestamp & KDBG_TIMESTAMP_MASK) |
313 (((uint64_t) cpu) << KDBG_CPU_SHIFT);
314 }
315 static inline int
kdbg_get_cpu(kd_buf * kp)316 kdbg_get_cpu(kd_buf *kp)
317 {
318 return (int) (((kp)->timestamp & KDBG_CPU_MASK) >> KDBG_CPU_SHIFT);
319 }
320 static inline void
kdbg_set_timestamp(kd_buf * kp,uint64_t thetime)321 kdbg_set_timestamp(kd_buf *kp, uint64_t thetime)
322 {
323 kp->timestamp = thetime & KDBG_TIMESTAMP_MASK;
324 }
325 static inline uint64_t
kdbg_get_timestamp(kd_buf * kp)326 kdbg_get_timestamp(kd_buf *kp)
327 {
328 return kp->timestamp & KDBG_TIMESTAMP_MASK;
329 }
330 static inline void
kdbg_set_timestamp_and_cpu(kd_buf * kp,uint64_t thetime,int cpu)331 kdbg_set_timestamp_and_cpu(kd_buf *kp, uint64_t thetime, int cpu)
332 {
333 kp->timestamp = (thetime & KDBG_TIMESTAMP_MASK) |
334 (((uint64_t) cpu) << KDBG_CPU_SHIFT);
335 }
336 #endif // !defined(__LP64__) && !defined(__arm64__)
337
338 // 8KB, one bit for each possible class/subclass combination.
339 #define KDBG_TYPEFILTER_BITMAP_SIZE ((256 * 256) / 8)
340
341 // Settings that may need to be changed while tracing, protected by the storage
342 // lock or the ktrace lock if tracing is disabled.
343 //
344 // These flags must not overlap with `kdebug_flags_t`.
345 __options_decl(kdebug_live_flags_t, uint32_t, {
346 // Disable tracing when events wrap. Set while reading events.
347 KDBG_NOWRAP = 0x0002,
348 // Events have wrapped.
349 KDBG_WRAPPED = 0x0008,
350 });
351
352 // Mostly configuration options, protected by the ktrace lock.
353 __options_decl(kdebug_flags_t, uint32_t, {
354 // Only trace processes with the kdebug bit set.
355 KDBG_PIDCHECK = 0x0010,
356 // Thread map pointer is valid.
357 KDBG_MAPINIT = 0x0020,
358 // Exclude events from processes with the kdebug bit set.
359 KDBG_PIDEXCLUDE = 0x0040,
360 // Events are 64-bit, only for `kbufinfo_t`.
361 KDBG_LP64 = 0x0100,
362 // Timestamps are continuous time, instead of absolute time.
363 KDBG_CONTINUOUS_TIME = 0x0200,
364 // Exclude events from coprocessors (IOPs).
365 KDBG_DISABLE_COPROCS = 0x0400,
366 // Disable tracing on event match.
367 KDBG_MATCH_DISABLE = 0x0800,
368 // Check the typefilter.
369 KDBG_TYPEFILTER_CHECK = 0x00400000,
370 // 64-bit debug ID present in arg4 (triage-only).
371 KDBG_DEBUGID_64 = 0x00800000,
372 // Event storage buffers are initialized.
373 KDBG_BUFINIT = 0x80000000U,
374 });
375
376 // Obsolete flags.
377 #define KDBG_INIT 0x01
378 #define KDBG_FREERUN 0x04
379
380 // Flags in `kdebug_live_flags_t` and `kdebug_flags_t` that can be modified by
381 // user space.
382 #define KDBG_USERFLAGS (KDBG_NOWRAP | KDBG_CONTINUOUS_TIME | \
383 KDBG_DISABLE_COPROCS | KDBG_MATCH_DISABLE)
384
385 // Information about kdebug for user space consumption.
386 typedef struct {
387 // Size of buffers in number of events (kd_bufs).
388 int nkdbufs;
389 // True is tracing is disabled, false otherwise.
390 int nolog;
391 // Combined `kdebug_live_flags_t` and `kdebug_state_t`.
392 unsigned int flags;
393 // Number of threads in the thread map.
394 int nkdthreads;
395 // Owning process PID.
396 int bufid;
397 } kbufinfo_t;
398
399 // Header for CPU mapping list.
400 typedef struct {
401 uint32_t version_no;
402 uint32_t cpu_count;
403 } kd_cpumap_header;
404
405 // CPU map entry flags.
406 #define KDBG_CPUMAP_IS_IOP 0x1
407
408 // CPU map entries to map `cpuid` from events to names.
409 typedef struct {
410 uint32_t cpu_id;
411 uint32_t flags;
412 char name[32];
413 } kd_cpumap_ext;
414
415 // Match structured data from events.
416 typedef struct {
417 uint32_t kem_debugid;
418 uint32_t kem_padding;
419 uint64_t kem_args[4];
420 } kd_event_matcher;
421
422 // Options for `kdebug_enable` in the comm-page.
423 #define KDEBUG_COMMPAGE_ENABLE_TRACE 0x1
424 #define KDEBUG_COMMPAGE_ENABLE_TYPEFILTER 0x2
425 #define KDEBUG_COMMPAGE_CONTINUOUS 0x4
426
427 #pragma mark - Tests
428
429 // Test scenarios.
430 __enum_decl(kdebug_test_t, uint32_t, {
431 KDTEST_KERNEL_MACROS = 1,
432 KDTEST_OLD_TIMESTAMP,
433 KDTEST_FUTURE_TIMESTAMP,
434 KDTEST_SETUP_IOP,
435 KDTEST_SETUP_COPROCESSOR,
436 KDTEST_CONTINUOUS_TIMESTAMP,
437 KDTEST_ABSOLUTE_TIMESTAMP,
438 KDTEST_PAST_EVENT,
439 });
440
441 #pragma mark - Obsolete interfaces
442
443 // Some Apple-internal clients try to use the kernel macros in user space.
444 #ifndef KERNEL_DEBUG
445 #define KERNEL_DEBUG(...) do { } while (0)
446 #endif // !defined(KERNEL_DEBUG)
447
448 // Obsolete options for `kdebug_enable`.
449 #define KDEBUG_ENABLE_ENTROPY 0x002U
450 #define KDEBUG_ENABLE_CHUD 0x004U
451 #define KDEBUG_ENABLE_PPT 0x008U
452 #define KDEBUG_ENABLE_SERIAL 0x010U
453 #define KDEBUG_PPT (KDEBUG_ENABLE_PPT)
454 #define KDEBUG_COMMON (KDEBUG_ENABLE_TRACE | KDEBUG_ENABLE_PPT)
455
456 // Obsolete flags.
457 #define KDBG_LOCKINIT 0x0080
458 #define KDBG_RANGECHECK 0x00100000U
459 #define KDBG_VALCHECK 0x00200000U
460
461 // Type values for `kd_regtype`.
462 #define KDBG_CLASSTYPE 0x10000
463 #define KDBG_SUBCLSTYPE 0x20000
464 #define KDBG_RANGETYPE 0x40000
465 #define KDBG_TYPENONE 0x80000
466 #define KDBG_CKTYPES 0xF0000
467
468 typedef struct {
469 unsigned int type;
470 unsigned int value1;
471 unsigned int value2;
472 unsigned int value3;
473 unsigned int value4;
474 } kd_regtype;
475
476 // Entry for the legacy thread map system (replaced by stackshot).
477 typedef struct {
478 // A thread's unique ID.
479 #if defined(__arm64__)
480 uint64_t thread;
481 #else
482 uintptr_t thread __kernel_data_semantics;
483 #endif
484 // The process ID (or 1 for `kernproc`).
485 int valid;
486 // The name of the process owning this thread.
487 char command[20];
488 } kd_threadmap;
489
490 // Legacy CPU map entry.
491 typedef struct {
492 uint32_t cpu_id;
493 uint32_t flags;
494 char name[8];
495 } kd_cpumap;
496
497 // File header for legacy trace files.
498 typedef struct {
499 int version_no;
500 int thread_count;
501 uint64_t TOD_secs;
502 uint32_t TOD_usecs;
503 } RAW_header;
504
505 // Obsolete `version_no` for legacy trace files.
506 #define RAW_VERSION0 0x55aa0000
507 #define RAW_VERSION1 0x55aa0101
508 #define RAW_VERSION2 0x55aa0200
509
510 // Obsolete EnergyTracing definitions.
511
512 #define kEnTrCompKernel 2
513 #define kEnTrActKernSocket 1
514 #define kEnTrActKernSockRead 2
515 #define kEnTrActKernSockWrite 3
516 #define kEnTrActKernPoll 10
517 #define kEnTrActKernSelect 11
518 #define kEnTrActKernKQWait 12
519 #define kEnTrEvUnblocked 256
520 #define kEnTrFlagNonBlocking 0x1
521 #define kEnTrFlagNoWork 0x2
522
523 #if (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST)
524 #define ENTR_SHOULDTRACE kdebug_enable
525 #define ENTR_KDTRACE(component, opcode, lifespan, id, quality, value) \
526 do { \
527 uint32_t kdcode__; \
528 uintptr_t highval__, lowval__, mask__ = 0xffffffff; \
529 kdcode__ = KDBG_CODE(DBG_ENERGYTRACE,component,opcode)|(lifespan); \
530 highval__ = ((value) >> 32) & mask__; \
531 lowval__ = (value) & mask__; \
532 ENTR_KDTRACEFUNC(kdcode__, id, quality, highval__, lowval__); \
533 } while(0)
534
535 #define kEnTrModAssociate (1 << 28)
536 #define ENTR_KDASSOCIATE(par_comp, par_opcode, par_act_id, \
537 sub_comp, sub_opcode, sub_act_id) \
538 do { \
539 unsigned sub_compcode = ((unsigned)sub_comp << 16) | sub_opcode; \
540 ENTR_KDTRACEFUNC(KDBG_CODE(DBG_ENERGYTRACE,par_comp,par_opcode), \
541 par_act_id, kEnTrModAssociate, sub_compcode, \
542 sub_act_id); \
543 } while(0)
544
545 #else // (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST)
546
547 #define ENTR_SHOULDTRACE 0
548 #define ENTR_KDTRACE(component, opcode, lifespan, id, quality, value) do {} while (0)
549 #define ENTR_KDASSOCIATE(par_comp, par_opcode, par_act_id, sub_comp, sub_opcode, sub_act_id) do {} while (0)
550
551 #endif // (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST)
552
553 #endif // !defined(DRIVERKIT)
554
555 __END_DECLS
556
557 #endif // !defined(BSD_KDEBUG_PRIVATE_H)
558