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.
59int 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.
76extern 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.
81extern 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.
85extern 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.
89extern 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.
93extern 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.
159extern 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.
165extern 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
208#define SKYWALKDBG_CODE(SubClass, code) KDBG_CODE(DBG_DLIL, SubClass, code)
209#define PPTDBG_CODE(SubClass, code) KDBG_CODE(DBG_PPT, SubClass, code)
210#define PERFCTRL_CODE(SubClass, code) KDBG_CODE(DBG_PERFCTRL, SubClass, code)
211#define AQMDBG_CODE(SubClass, code) KDBG_CODE(DBG_DLIL, SubClass, code)
212
213#if !defined(DRIVERKIT)
214
215extern unsigned int kdebug_enable;
216
217// Options for `kdebug_enable`.
218
219// Enable tracing.
220#define KDEBUG_ENABLE_TRACE 0x001U
221// Whether timestamps are continuous times or absolute times.
222#define KDEBUG_ENABLE_CONT_TIME 0x020U
223
224#define KDEBUG_TRACE (KDEBUG_ENABLE_TRACE)
225
226// Control which kernel events are compiled in under different build
227// configurations.
228
229// No kdebug events are emitted with the macros.
230#define KDEBUG_LEVEL_NONE 0
231// In-System Tracing exposes a limited set of events for release kernels.
232#define KDEBUG_LEVEL_IST 1
233// The default for development kernels.
234#define KDEBUG_LEVEL_STANDARD 2
235// Truly verbose, debug-level logging, only set manually.
236#define KDEBUG_LEVEL_FULL 3
237
238// Use configuration options to set the kdebug level.
239#if NO_KDEBUG
240#define KDEBUG_LEVEL KDEBUG_LEVEL_NONE
241#elif IST_KDEBUG
242#define KDEBUG_LEVEL KDEBUG_LEVEL_IST
243#elif KDEBUG
244#define KDEBUG_LEVEL KDEBUG_LEVEL_FULL
245#else // !NO_KDEBUG && !IST_KDEBUG && !KDEBUG
246#define KDEBUG_LEVEL KDEBUG_LEVEL_STANDARD
247#endif // !NO_KDEBUG && !IST_KDEBUG && !KDEBUG
248
249#pragma mark - Implementation details
250
251// Ensure that LP32 and LP64 variants of arm64 use the same kd_buf structure.
252#if defined(__arm64__)
253typedef uint64_t kd_buf_argtype;
254#else // defined(__arm64__)
255typedef uintptr_t kd_buf_argtype;
256#endif // !defined(__arm64__)
257
258// The main event ABI as recorded in the kernel.
259
260typedef struct {
261 uint64_t timestamp;
262 kd_buf_argtype arg1;
263 kd_buf_argtype arg2;
264 kd_buf_argtype arg3;
265 kd_buf_argtype arg4;
266 kd_buf_argtype arg5; // Always the thread ID.
267 uint32_t debugid;
268// Ensure that LP32 and LP64 variants of arm64 use the same kd_buf structure.
269#if defined(__LP64__) || defined(__arm64__)
270 uint32_t cpuid;
271 kd_buf_argtype unused;
272#endif // defined(__LP64__) || defined(__arm64__)
273} kd_buf;
274
275#if defined(__LP64__) || defined(__arm64__)
276
277#define KDBG_TIMESTAMP_MASK 0xffffffffffffffffULL
278static inline void
279kdbg_set_cpu(kd_buf *kp, int cpu)
280{
281 kp->cpuid = (unsigned int)cpu;
282}
283static inline int
284kdbg_get_cpu(kd_buf *kp)
285{
286 return (int)kp->cpuid;
287}
288static inline void
289kdbg_set_timestamp(kd_buf *kp, uint64_t thetime)
290{
291 kp->timestamp = thetime;
292}
293static inline uint64_t
294kdbg_get_timestamp(kd_buf *kp)
295{
296 return kp->timestamp;
297}
298static inline void
299kdbg_set_timestamp_and_cpu(kd_buf *kp, uint64_t thetime, int cpu)
300{
301 kdbg_set_timestamp(kp, thetime);
302 kdbg_set_cpu(kp, cpu);
303}
304#else // defined(__LP64__) || defined(__arm64__)
305#define KDBG_TIMESTAMP_MASK 0x00ffffffffffffffULL
306#define KDBG_CPU_MASK 0xff00000000000000ULL
307#define KDBG_CPU_SHIFT 56
308static inline void
309kdbg_set_cpu(kd_buf *kp, int cpu)
310{
311 kp->timestamp = (kp->timestamp & KDBG_TIMESTAMP_MASK) |
312 (((uint64_t) cpu) << KDBG_CPU_SHIFT);
313}
314static inline int
315kdbg_get_cpu(kd_buf *kp)
316{
317 return (int) (((kp)->timestamp & KDBG_CPU_MASK) >> KDBG_CPU_SHIFT);
318}
319static inline void
320kdbg_set_timestamp(kd_buf *kp, uint64_t thetime)
321{
322 kp->timestamp = thetime & KDBG_TIMESTAMP_MASK;
323}
324static inline uint64_t
325kdbg_get_timestamp(kd_buf *kp)
326{
327 return kp->timestamp & KDBG_TIMESTAMP_MASK;
328}
329static inline void
330kdbg_set_timestamp_and_cpu(kd_buf *kp, uint64_t thetime, int cpu)
331{
332 kp->timestamp = (thetime & KDBG_TIMESTAMP_MASK) |
333 (((uint64_t) cpu) << KDBG_CPU_SHIFT);
334}
335#endif // !defined(__LP64__) && !defined(__arm64__)
336
337// 8KB, one bit for each possible class/subclass combination.
338#define KDBG_TYPEFILTER_BITMAP_SIZE ((256 * 256) / 8)
339
340// Settings that may need to be changed while tracing, protected by the storage
341// lock or the ktrace lock if tracing is disabled.
342//
343// These flags must not overlap with `kdebug_flags_t`.
344__options_decl(kdebug_live_flags_t, uint32_t, {
345 // Disable tracing when events wrap. Set while reading events.
346 KDBG_NOWRAP = 0x0002,
347 // Events have wrapped.
348 KDBG_WRAPPED = 0x0008,
349});
350
351// Mostly configuration options, protected by the ktrace lock.
352__options_decl(kdebug_flags_t, uint32_t, {
353 // Only trace processes with the kdebug bit set.
354 KDBG_PIDCHECK = 0x0010,
355 // Thread map pointer is valid.
356 KDBG_MAPINIT = 0x0020,
357 // Exclude events from processes with the kdebug bit set.
358 KDBG_PIDEXCLUDE = 0x0040,
359 // Events are 64-bit, only for `kbufinfo_t`.
360 KDBG_LP64 = 0x0100,
361 // Timestamps are continuous time, instead of absolute time.
362 KDBG_CONTINUOUS_TIME = 0x0200,
363 // Exclude events from coprocessors (IOPs).
364 KDBG_DISABLE_COPROCS = 0x0400,
365 // Disable tracing on event match.
366 KDBG_MATCH_DISABLE = 0x0800,
367 // Check the typefilter.
368 KDBG_TYPEFILTER_CHECK = 0x00400000,
369 // 64-bit debug ID present in arg4 (triage-only).
370 KDBG_DEBUGID_64 = 0x00800000,
371 // Event storage buffers are initialized.
372 KDBG_BUFINIT = 0x80000000U,
373});
374
375// Obsolete flags.
376#define KDBG_INIT 0x01
377#define KDBG_FREERUN 0x04
378
379// Flags in `kdebug_live_flags_t` and `kdebug_flags_t` that can be modified by
380// user space.
381#define KDBG_USERFLAGS (KDBG_NOWRAP | KDBG_CONTINUOUS_TIME | \
382 KDBG_DISABLE_COPROCS | KDBG_MATCH_DISABLE)
383
384// Information about kdebug for user space consumption.
385typedef struct {
386 // Size of buffers in number of events (kd_bufs).
387 int nkdbufs;
388 // True is tracing is disabled, false otherwise.
389 int nolog;
390 // Combined `kdebug_live_flags_t` and `kdebug_state_t`.
391 unsigned int flags;
392 // Number of threads in the thread map.
393 int nkdthreads;
394 // Owning process PID.
395 int bufid;
396} kbufinfo_t;
397
398// Header for CPU mapping list.
399typedef struct {
400 uint32_t version_no;
401 uint32_t cpu_count;
402} kd_cpumap_header;
403
404// CPU map entry flags.
405#define KDBG_CPUMAP_IS_IOP 0x1
406
407// CPU map entries to map `cpuid` from events to names.
408typedef struct {
409 uint32_t cpu_id;
410 uint32_t flags;
411 char name[32];
412} kd_cpumap_ext;
413
414// Match structured data from events.
415typedef struct {
416 uint32_t kem_debugid;
417 uint32_t kem_padding;
418 uint64_t kem_args[4];
419} kd_event_matcher;
420
421// Options for `kdebug_enable` in the comm-page.
422#define KDEBUG_COMMPAGE_ENABLE_TRACE 0x1
423#define KDEBUG_COMMPAGE_ENABLE_TYPEFILTER 0x2
424#define KDEBUG_COMMPAGE_CONTINUOUS 0x4
425
426#pragma mark - Tests
427
428// Test scenarios.
429__enum_decl(kdebug_test_t, uint32_t, {
430 KDTEST_KERNEL_MACROS = 1,
431 KDTEST_OLD_TIMESTAMP,
432 KDTEST_FUTURE_TIMESTAMP,
433 KDTEST_SETUP_IOP,
434 KDTEST_SETUP_COPROCESSOR,
435 KDTEST_CONTINUOUS_TIMESTAMP,
436 KDTEST_ABSOLUTE_TIMESTAMP,
437 KDTEST_PAST_EVENT,
438});
439
440#pragma mark - Obsolete interfaces
441
442// Some Apple-internal clients try to use the kernel macros in user space.
443#ifndef KERNEL_DEBUG
444#define KERNEL_DEBUG(...) do { } while (0)
445#endif // !defined(KERNEL_DEBUG)
446
447// Obsolete options for `kdebug_enable`.
448#define KDEBUG_ENABLE_ENTROPY 0x002U
449#define KDEBUG_ENABLE_CHUD 0x004U
450#define KDEBUG_ENABLE_PPT 0x008U
451#define KDEBUG_ENABLE_SERIAL 0x010U
452#define KDEBUG_PPT (KDEBUG_ENABLE_PPT)
453#define KDEBUG_COMMON (KDEBUG_ENABLE_TRACE | KDEBUG_ENABLE_PPT)
454
455// Obsolete flags.
456#define KDBG_LOCKINIT 0x0080
457#define KDBG_RANGECHECK 0x00100000U
458#define KDBG_VALCHECK 0x00200000U
459
460// Type values for `kd_regtype`.
461#define KDBG_CLASSTYPE 0x10000
462#define KDBG_SUBCLSTYPE 0x20000
463#define KDBG_RANGETYPE 0x40000
464#define KDBG_TYPENONE 0x80000
465#define KDBG_CKTYPES 0xF0000
466
467typedef struct {
468 unsigned int type;
469 unsigned int value1;
470 unsigned int value2;
471 unsigned int value3;
472 unsigned int value4;
473} kd_regtype;
474
475// Entry for the legacy thread map system (replaced by stackshot).
476typedef struct {
477 // A thread's unique ID.
478#if defined(__arm64__)
479 uint64_t thread;
480#else
481 uintptr_t thread __kernel_data_semantics;
482#endif
483 // The process ID (or 1 for `kernproc`).
484 int valid;
485 // The name of the process owning this thread.
486 char command[20];
487} kd_threadmap;
488
489// Legacy CPU map entry.
490typedef struct {
491 uint32_t cpu_id;
492 uint32_t flags;
493 char name[8];
494} kd_cpumap;
495
496// File header for legacy trace files.
497typedef struct {
498 int version_no;
499 int thread_count;
500 uint64_t TOD_secs;
501 uint32_t TOD_usecs;
502} RAW_header;
503
504// Obsolete `version_no` for legacy trace files.
505#define RAW_VERSION0 0x55aa0000
506#define RAW_VERSION1 0x55aa0101
507#define RAW_VERSION2 0x55aa0200
508
509// Obsolete EnergyTracing definitions.
510
511#define kEnTrCompKernel 2
512#define kEnTrActKernSocket 1
513#define kEnTrActKernSockRead 2
514#define kEnTrActKernSockWrite 3
515#define kEnTrActKernPoll 10
516#define kEnTrActKernSelect 11
517#define kEnTrActKernKQWait 12
518#define kEnTrEvUnblocked 256
519#define kEnTrFlagNonBlocking 0x1
520#define kEnTrFlagNoWork 0x2
521
522#if (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST)
523#define ENTR_SHOULDTRACE kdebug_enable
524#define ENTR_KDTRACE(component, opcode, lifespan, id, quality, value) \
525do { \
526 uint32_t kdcode__; \
527 uintptr_t highval__, lowval__, mask__ = 0xffffffff; \
528 kdcode__ = KDBG_CODE(DBG_ENERGYTRACE,component,opcode)|(lifespan); \
529 highval__ = ((value) >> 32) & mask__; \
530 lowval__ = (value) & mask__; \
531 ENTR_KDTRACEFUNC(kdcode__, id, quality, highval__, lowval__); \
532} while(0)
533
534#define kEnTrModAssociate (1 << 28)
535#define ENTR_KDASSOCIATE(par_comp, par_opcode, par_act_id, \
536 sub_comp, sub_opcode, sub_act_id) \
537do { \
538 unsigned sub_compcode = ((unsigned)sub_comp << 16) | sub_opcode; \
539 ENTR_KDTRACEFUNC(KDBG_CODE(DBG_ENERGYTRACE,par_comp,par_opcode), \
540 par_act_id, kEnTrModAssociate, sub_compcode, \
541 sub_act_id); \
542} while(0)
543
544#else // (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST)
545
546#define ENTR_SHOULDTRACE 0
547#define ENTR_KDTRACE(component, opcode, lifespan, id, quality, value) do {} while (0)
548#define ENTR_KDASSOCIATE(par_comp, par_opcode, par_act_id, sub_comp, sub_opcode, sub_act_id) do {} while (0)
549
550#endif // (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST)
551
552#endif // !defined(DRIVERKIT)
553
554__END_DECLS
555
556#endif // !defined(BSD_KDEBUG_PRIVATE_H)
557