1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Portions Copyright (c) 2013, 2016, Joyent, Inc. All rights reserved.
24 * Portions Copyright (c) 2013 by Delphix. All rights reserved.
25 */
26
27 /*
28 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
29 * Use is subject to license terms.
30 */
31
32 /*
33 * DTrace - Dynamic Tracing for Solaris
34 *
35 * This is the implementation of the Solaris Dynamic Tracing framework
36 * (DTrace). The user-visible interface to DTrace is described at length in
37 * the "Solaris Dynamic Tracing Guide". The interfaces between the libdtrace
38 * library, the in-kernel DTrace framework, and the DTrace providers are
39 * described in the block comments in the <sys/dtrace.h> header file. The
40 * internal architecture of DTrace is described in the block comments in the
41 * <sys/dtrace_impl.h> header file. The comments contained within the DTrace
42 * implementation very much assume mastery of all of these sources; if one has
43 * an unanswered question about the implementation, one should consult them
44 * first.
45 *
46 * The functions here are ordered roughly as follows:
47 *
48 * - Probe context functions
49 * - Probe hashing functions
50 * - Non-probe context utility functions
51 * - Matching functions
52 * - Provider-to-Framework API functions
53 * - Probe management functions
54 * - DIF object functions
55 * - Format functions
56 * - Predicate functions
57 * - ECB functions
58 * - Buffer functions
59 * - Enabling functions
60 * - DOF functions
61 * - Anonymous enabling functions
62 * - Process functions
63 * - Consumer state functions
64 * - Helper functions
65 * - Hook functions
66 * - Driver cookbook functions
67 *
68 * Each group of functions begins with a block comment labelled the "DTrace
69 * [Group] Functions", allowing one to find each block by searching forward
70 * on capital-f functions.
71 */
72 #include <sys/errno.h>
73 #include <sys/types.h>
74 #include <sys/stat.h>
75 #include <sys/conf.h>
76 #include <sys/random.h>
77 #include <sys/systm.h>
78 #include <sys/dtrace_impl.h>
79 #include <sys/param.h>
80 #include <sys/proc_internal.h>
81 #include <sys/ioctl.h>
82 #include <sys/fcntl.h>
83 #include <miscfs/devfs/devfs.h>
84 #include <sys/malloc.h>
85 #include <sys/kernel_types.h>
86 #include <sys/proc_internal.h>
87 #include <sys/uio_internal.h>
88 #include <sys/kauth.h>
89 #include <vm/pmap.h>
90 #include <sys/user.h>
91 #include <mach/exception_types.h>
92 #include <sys/signalvar.h>
93 #include <mach/task.h>
94 #include <kern/zalloc.h>
95 #include <kern/ast.h>
96 #include <kern/sched_prim.h>
97 #include <kern/task.h>
98 #include <kern/hvg_hypercall.h>
99 #include <netinet/in.h>
100 #include <libkern/sysctl.h>
101 #include <sys/kdebug.h>
102 #include <sys/sdt_impl.h>
103
104 #if MONOTONIC
105 #include <kern/monotonic.h>
106 #include <machine/monotonic.h>
107 #endif /* MONOTONIC */
108
109 #include "dtrace_xoroshiro128_plus.h"
110
111 #include <IOKit/IOPlatformExpert.h>
112
113 #include <kern/cpu_data.h>
114
115 extern addr64_t kvtophys(vm_offset_t va);
116
117 extern uint32_t pmap_find_phys(void *, uint64_t);
118 extern boolean_t pmap_valid_page(uint32_t);
119 extern void OSKextRegisterKextsWithDTrace(void);
120 extern kmod_info_t g_kernel_kmod_info;
121 extern void commpage_update_dof(boolean_t enabled);
122
123 /* Solaris proc_t is the struct. Darwin's proc_t is a pointer to it. */
124 #define proc_t struct proc /* Steer clear of the Darwin typedef for proc_t */
125
126 #define t_predcache t_dtrace_predcache /* Cosmetic. Helps readability of thread.h */
127
128 extern void dtrace_suspend(void);
129 extern void dtrace_resume(void);
130 extern void dtrace_early_init(void);
131 extern int dtrace_keep_kernel_symbols(void);
132 extern void dtrace_init(void);
133 extern void helper_init(void);
134 extern void fasttrap_init(void);
135
136 static int dtrace_lazy_dofs_duplicate(proc_t *, proc_t *);
137 extern void dtrace_lazy_dofs_destroy(proc_t *);
138 extern void dtrace_postinit(void);
139
140 extern void dtrace_proc_fork(proc_t*, proc_t*, int);
141 extern void dtrace_proc_exec(proc_t*);
142 extern void dtrace_proc_exit(proc_t*);
143
144 /*
145 * DTrace Tunable Variables
146 *
147 * The following variables may be dynamically tuned by using sysctl(8), the
148 * variables being stored in the kern.dtrace namespace. For example:
149 * sysctl kern.dtrace.dof_maxsize = 1048575 # 1M
150 *
151 * In general, the only variables that one should be tuning this way are those
152 * that affect system-wide DTrace behavior, and for which the default behavior
153 * is undesirable. Most of these variables are tunable on a per-consumer
154 * basis using DTrace options, and need not be tuned on a system-wide basis.
155 * When tuning these variables, avoid pathological values; while some attempt
156 * is made to verify the integrity of these variables, they are not considered
157 * part of the supported interface to DTrace, and they are therefore not
158 * checked comprehensively.
159 */
160 uint64_t dtrace_buffer_memory_maxsize = 0; /* initialized in dtrace_init */
161 uint64_t dtrace_buffer_memory_inuse = 0;
162 int dtrace_destructive_disallow = 1;
163 dtrace_optval_t dtrace_nonroot_maxsize = (16 * 1024 * 1024);
164 size_t dtrace_difo_maxsize = (256 * 1024);
165 dtrace_optval_t dtrace_dof_maxsize = (512 * 1024);
166 dtrace_optval_t dtrace_statvar_maxsize = (16 * 1024);
167 dtrace_optval_t dtrace_statvar_maxsize_max = (16 * 10 * 1024);
168 size_t dtrace_actions_max = (16 * 1024);
169 size_t dtrace_retain_max = 1024;
170 dtrace_optval_t dtrace_helper_actions_max = 32;
171 dtrace_optval_t dtrace_helper_providers_max = 64;
172 dtrace_optval_t dtrace_dstate_defsize = (1 * 1024 * 1024);
173 size_t dtrace_strsize_default = 256;
174 dtrace_optval_t dtrace_strsize_min = 8;
175 dtrace_optval_t dtrace_strsize_max = 65536;
176 dtrace_optval_t dtrace_cleanrate_default = 990099000; /* 1.1 hz */
177 dtrace_optval_t dtrace_cleanrate_min = 20000000; /* 50 hz */
178 dtrace_optval_t dtrace_cleanrate_max = (uint64_t)60 * NANOSEC; /* 1/minute */
179 dtrace_optval_t dtrace_aggrate_default = NANOSEC; /* 1 hz */
180 dtrace_optval_t dtrace_statusrate_default = NANOSEC; /* 1 hz */
181 dtrace_optval_t dtrace_statusrate_max = (hrtime_t)10 * NANOSEC; /* 6/minute */
182 dtrace_optval_t dtrace_switchrate_default = NANOSEC; /* 1 hz */
183 dtrace_optval_t dtrace_nspec_default = 1;
184 dtrace_optval_t dtrace_specsize_default = 32 * 1024;
185 dtrace_optval_t dtrace_stackframes_default = 20;
186 dtrace_optval_t dtrace_ustackframes_default = 20;
187 dtrace_optval_t dtrace_jstackframes_default = 50;
188 dtrace_optval_t dtrace_jstackstrsize_default = 512;
189 dtrace_optval_t dtrace_buflimit_default = 75;
190 dtrace_optval_t dtrace_buflimit_min = 1;
191 dtrace_optval_t dtrace_buflimit_max = 99;
192 size_t dtrace_nprobes_default = 4;
193 int dtrace_msgdsize_max = 128;
194 hrtime_t dtrace_chill_max = 500 * (NANOSEC / MILLISEC); /* 500 ms */
195 hrtime_t dtrace_chill_interval = NANOSEC; /* 1000 ms */
196 int dtrace_devdepth_max = 32;
197 int dtrace_err_verbose;
198 hrtime_t dtrace_deadman_interval = NANOSEC;
199 hrtime_t dtrace_deadman_timeout = (hrtime_t)10 * NANOSEC;
200 hrtime_t dtrace_deadman_user = (hrtime_t)30 * NANOSEC;
201
202 /*
203 * DTrace External Variables
204 *
205 * As dtrace(7D) is a kernel module, any DTrace variables are obviously
206 * available to DTrace consumers via the backtick (`) syntax. One of these,
207 * dtrace_zero, is made deliberately so: it is provided as a source of
208 * well-known, zero-filled memory. While this variable is not documented,
209 * it is used by some translators as an implementation detail.
210 */
211 const char dtrace_zero[256] = { 0 }; /* zero-filled memory */
212 unsigned int dtrace_max_cpus = 0; /* number of enabled cpus */
213 /*
214 * DTrace Internal Variables
215 */
216 static dev_info_t *dtrace_devi; /* device info */
217 static vmem_t *dtrace_arena; /* probe ID arena */
218 static dtrace_probe_t **dtrace_probes; /* array of all probes */
219 static int dtrace_nprobes; /* number of probes */
220 static dtrace_provider_t *dtrace_provider; /* provider list */
221 static dtrace_meta_t *dtrace_meta_pid; /* user-land meta provider */
222 static int dtrace_opens; /* number of opens */
223 static int dtrace_helpers; /* number of helpers */
224 static dtrace_hash_t *dtrace_strings;
225 static dtrace_hash_t *dtrace_byprov; /* probes hashed by provider */
226 static dtrace_hash_t *dtrace_bymod; /* probes hashed by module */
227 static dtrace_hash_t *dtrace_byfunc; /* probes hashed by function */
228 static dtrace_hash_t *dtrace_byname; /* probes hashed by name */
229 static dtrace_toxrange_t *dtrace_toxrange; /* toxic range array */
230 static int dtrace_toxranges; /* number of toxic ranges */
231 static int dtrace_toxranges_max; /* size of toxic range array */
232 static dtrace_anon_t dtrace_anon; /* anonymous enabling */
233 static kmem_cache_t *dtrace_state_cache; /* cache for dynamic state */
234 static uint64_t dtrace_vtime_references; /* number of vtimestamp refs */
235 static kthread_t *dtrace_panicked; /* panicking thread */
236 static dtrace_ecb_t *dtrace_ecb_create_cache; /* cached created ECB */
237 static dtrace_genid_t dtrace_probegen; /* current probe generation */
238 static dtrace_helpers_t *dtrace_deferred_pid; /* deferred helper list */
239 static dtrace_enabling_t *dtrace_retained; /* list of retained enablings */
240 static dtrace_genid_t dtrace_retained_gen; /* current retained enab gen */
241 static dtrace_dynvar_t dtrace_dynhash_sink; /* end of dynamic hash chains */
242
243 static int dtrace_dof_mode; /* See dtrace_impl.h for a description of Darwin's dof modes. */
244
245 /*
246 * This does't quite fit as an internal variable, as it must be accessed in
247 * fbt_provide and sdt_provide. Its clearly not a dtrace tunable variable either...
248 */
249 int dtrace_kernel_symbol_mode; /* See dtrace_impl.h for a description of Darwin's kernel symbol modes. */
250 static uint32_t dtrace_wake_clients;
251 static uint8_t dtrace_kerneluuid[16]; /* the 128-bit uuid */
252
253 /*
254 * To save memory, some common memory allocations are given a
255 * unique zone. For example, dtrace_probe_t is 72 bytes in size,
256 * which means it would fall into the kalloc.128 bucket. With
257 * 20k elements allocated, the space saved is substantial.
258 */
259
260 static ZONE_DECLARE(dtrace_probe_t_zone, "dtrace.dtrace_probe_t",
261 sizeof(dtrace_probe_t), ZC_NONE);
262
263 static int dtrace_module_unloaded(struct kmod_info *kmod);
264
265 /*
266 * DTrace Locking
267 * DTrace is protected by three (relatively coarse-grained) locks:
268 *
269 * (1) dtrace_lock is required to manipulate essentially any DTrace state,
270 * including enabling state, probes, ECBs, consumer state, helper state,
271 * etc. Importantly, dtrace_lock is _not_ required when in probe context;
272 * probe context is lock-free -- synchronization is handled via the
273 * dtrace_sync() cross call mechanism.
274 *
275 * (2) dtrace_provider_lock is required when manipulating provider state, or
276 * when provider state must be held constant.
277 *
278 * (3) dtrace_meta_lock is required when manipulating meta provider state, or
279 * when meta provider state must be held constant.
280 *
281 * The lock ordering between these three locks is dtrace_meta_lock before
282 * dtrace_provider_lock before dtrace_lock. (In particular, there are
283 * several places where dtrace_provider_lock is held by the framework as it
284 * calls into the providers -- which then call back into the framework,
285 * grabbing dtrace_lock.)
286 *
287 * There are two other locks in the mix: mod_lock and cpu_lock. With respect
288 * to dtrace_provider_lock and dtrace_lock, cpu_lock continues its historical
289 * role as a coarse-grained lock; it is acquired before both of these locks.
290 * With respect to dtrace_meta_lock, its behavior is stranger: cpu_lock must
291 * be acquired _between_ dtrace_meta_lock and any other DTrace locks.
292 * mod_lock is similar with respect to dtrace_provider_lock in that it must be
293 * acquired _between_ dtrace_provider_lock and dtrace_lock.
294 */
295
296
297 /*
298 * APPLE NOTE:
299 *
300 * For porting purposes, all kmutex_t vars have been changed
301 * to lck_mtx_t, which require explicit initialization.
302 *
303 * kmutex_t becomes lck_mtx_t
304 * mutex_enter() becomes lck_mtx_lock()
305 * mutex_exit() becomes lck_mtx_unlock()
306 *
307 * Lock asserts are changed like this:
308 *
309 * ASSERT(MUTEX_HELD(&cpu_lock));
310 * becomes:
311 * LCK_MTX_ASSERT(&cpu_lock, LCK_MTX_ASSERT_OWNED);
312 *
313 */
314 static LCK_MTX_DECLARE_ATTR(dtrace_lock,
315 &dtrace_lck_grp, &dtrace_lck_attr); /* probe state lock */
316 static LCK_MTX_DECLARE_ATTR(dtrace_provider_lock,
317 &dtrace_lck_grp, &dtrace_lck_attr); /* provider state lock */
318 static LCK_MTX_DECLARE_ATTR(dtrace_meta_lock,
319 &dtrace_lck_grp, &dtrace_lck_attr); /* meta-provider state lock */
320 static LCK_RW_DECLARE_ATTR(dtrace_dof_mode_lock,
321 &dtrace_lck_grp, &dtrace_lck_attr); /* dof mode lock */
322
323 /*
324 * DTrace Provider Variables
325 *
326 * These are the variables relating to DTrace as a provider (that is, the
327 * provider of the BEGIN, END, and ERROR probes).
328 */
329 static dtrace_pattr_t dtrace_provider_attr = {
330 { DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
331 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
332 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
333 { DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
334 { DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
335 };
336
337 static void
dtrace_provide_nullop(void * arg,const dtrace_probedesc_t * desc)338 dtrace_provide_nullop(void *arg, const dtrace_probedesc_t *desc)
339 {
340 #pragma unused(arg, desc)
341 }
342
343 static void
dtrace_provide_module_nullop(void * arg,struct modctl * ctl)344 dtrace_provide_module_nullop(void *arg, struct modctl *ctl)
345 {
346 #pragma unused(arg, ctl)
347 }
348
349 static int
dtrace_enable_nullop(void * arg,dtrace_id_t id,void * parg)350 dtrace_enable_nullop(void *arg, dtrace_id_t id, void *parg)
351 {
352 #pragma unused(arg, id, parg)
353 return (0);
354 }
355
356 static void
dtrace_disable_nullop(void * arg,dtrace_id_t id,void * parg)357 dtrace_disable_nullop(void *arg, dtrace_id_t id, void *parg)
358 {
359 #pragma unused(arg, id, parg)
360 }
361
362 static void
dtrace_suspend_nullop(void * arg,dtrace_id_t id,void * parg)363 dtrace_suspend_nullop(void *arg, dtrace_id_t id, void *parg)
364 {
365 #pragma unused(arg, id, parg)
366 }
367
368 static void
dtrace_resume_nullop(void * arg,dtrace_id_t id,void * parg)369 dtrace_resume_nullop(void *arg, dtrace_id_t id, void *parg)
370 {
371 #pragma unused(arg, id, parg)
372 }
373
374 static void
dtrace_destroy_nullop(void * arg,dtrace_id_t id,void * parg)375 dtrace_destroy_nullop(void *arg, dtrace_id_t id, void *parg)
376 {
377 #pragma unused(arg, id, parg)
378 }
379
380
381 static dtrace_pops_t dtrace_provider_ops = {
382 .dtps_provide = dtrace_provide_nullop,
383 .dtps_provide_module = dtrace_provide_module_nullop,
384 .dtps_enable = dtrace_enable_nullop,
385 .dtps_disable = dtrace_disable_nullop,
386 .dtps_suspend = dtrace_suspend_nullop,
387 .dtps_resume = dtrace_resume_nullop,
388 .dtps_getargdesc = NULL,
389 .dtps_getargval = NULL,
390 .dtps_usermode = NULL,
391 .dtps_destroy = dtrace_destroy_nullop,
392 };
393
394 static dtrace_id_t dtrace_probeid_begin; /* special BEGIN probe */
395 static dtrace_id_t dtrace_probeid_end; /* special END probe */
396 dtrace_id_t dtrace_probeid_error; /* special ERROR probe */
397
398 /*
399 * DTrace Helper Tracing Variables
400 */
401 uint32_t dtrace_helptrace_next = 0;
402 uint32_t dtrace_helptrace_nlocals;
403 char *dtrace_helptrace_buffer;
404 size_t dtrace_helptrace_bufsize = 512 * 1024;
405
406 #if DEBUG
407 int dtrace_helptrace_enabled = 1;
408 #else
409 int dtrace_helptrace_enabled = 0;
410 #endif
411
412 #if defined (__arm64__)
413 /*
414 * The ioctl for adding helper DOF is based on the
415 * size of a user_addr_t. We need to recognize both
416 * U32 and U64 as the same action.
417 */
418 #define DTRACEHIOC_ADDDOF_U32 _IOW('h', 4, user32_addr_t)
419 #define DTRACEHIOC_ADDDOF_U64 _IOW('h', 4, user64_addr_t)
420 #endif /* __arm64__ */
421
422 /*
423 * DTrace Error Hashing
424 *
425 * On DEBUG kernels, DTrace will track the errors that has seen in a hash
426 * table. This is very useful for checking coverage of tests that are
427 * expected to induce DIF or DOF processing errors, and may be useful for
428 * debugging problems in the DIF code generator or in DOF generation . The
429 * error hash may be examined with the ::dtrace_errhash MDB dcmd.
430 */
431 #if DEBUG
432 static dtrace_errhash_t dtrace_errhash[DTRACE_ERRHASHSZ];
433 static const char *dtrace_errlast;
434 static kthread_t *dtrace_errthread;
435 static LCK_MTX_DECLARE_ATTR(dtrace_errlock, &dtrace_lck_grp, &dtrace_lck_attr);
436 #endif
437
438 /*
439 * DTrace Macros and Constants
440 *
441 * These are various macros that are useful in various spots in the
442 * implementation, along with a few random constants that have no meaning
443 * outside of the implementation. There is no real structure to this cpp
444 * mishmash -- but is there ever?
445 */
446
447 #define DTRACE_GETSTR(hash, elm) \
448 (hash->dth_getstr(elm, hash->dth_stroffs))
449
450 #define DTRACE_HASHSTR(hash, elm) \
451 dtrace_hash_str(DTRACE_GETSTR(hash, elm))
452
453 #define DTRACE_HASHNEXT(hash, elm) \
454 (void**)((uintptr_t)(elm) + (hash)->dth_nextoffs)
455
456 #define DTRACE_HASHPREV(hash, elm) \
457 (void**)((uintptr_t)(elm) + (hash)->dth_prevoffs)
458
459 #define DTRACE_HASHEQ(hash, lhs, rhs) \
460 (strcmp(DTRACE_GETSTR(hash, lhs), \
461 DTRACE_GETSTR(hash, rhs)) == 0)
462
463 #define DTRACE_AGGHASHSIZE_SLEW 17
464
465 #define DTRACE_V4MAPPED_OFFSET (sizeof (uint32_t) * 3)
466
467 /*
468 * The key for a thread-local variable consists of the lower 61 bits of the
469 * current_thread(), plus the 3 bits of the highest active interrupt above LOCK_LEVEL.
470 * We add DIF_VARIABLE_MAX to t_did to assure that the thread key is never
471 * equal to a variable identifier. This is necessary (but not sufficient) to
472 * assure that global associative arrays never collide with thread-local
473 * variables. To guarantee that they cannot collide, we must also define the
474 * order for keying dynamic variables. That order is:
475 *
476 * [ key0 ] ... [ keyn ] [ variable-key ] [ tls-key ]
477 *
478 * Because the variable-key and the tls-key are in orthogonal spaces, there is
479 * no way for a global variable key signature to match a thread-local key
480 * signature.
481 */
482 #if defined (__x86_64__)
483 /* FIXME: two function calls!! */
484 #define DTRACE_TLS_THRKEY(where) { \
485 uint_t intr = ml_at_interrupt_context(); /* Note: just one measly bit */ \
486 uint64_t thr = (uintptr_t)current_thread(); \
487 ASSERT(intr < (1 << 3)); \
488 (where) = ((thr + DIF_VARIABLE_MAX) & \
489 (((uint64_t)1 << 61) - 1)) | ((uint64_t)intr << 61); \
490 }
491 #elif defined(__arm__)
492 /* FIXME: three function calls!!! */
493 #define DTRACE_TLS_THRKEY(where) { \
494 uint_t intr = ml_at_interrupt_context(); /* Note: just one measly bit */ \
495 uint64_t thr = (uintptr_t)current_thread(); \
496 uint_t pid = (uint_t)dtrace_proc_selfpid(); \
497 ASSERT(intr < (1 << 3)); \
498 (where) = (((thr << 32 | pid) + DIF_VARIABLE_MAX) & \
499 (((uint64_t)1 << 61) - 1)) | ((uint64_t)intr << 61); \
500 }
501 #elif defined (__arm64__)
502 /* FIXME: two function calls!! */
503 #define DTRACE_TLS_THRKEY(where) { \
504 uint_t intr = ml_at_interrupt_context(); /* Note: just one measly bit */ \
505 uint64_t thr = (uintptr_t)current_thread(); \
506 ASSERT(intr < (1 << 3)); \
507 (where) = ((thr + DIF_VARIABLE_MAX) & \
508 (((uint64_t)1 << 61) - 1)) | ((uint64_t)intr << 61); \
509 }
510 #else
511 #error Unknown architecture
512 #endif
513
514 #define DT_BSWAP_8(x) ((x) & 0xff)
515 #define DT_BSWAP_16(x) ((DT_BSWAP_8(x) << 8) | DT_BSWAP_8((x) >> 8))
516 #define DT_BSWAP_32(x) ((DT_BSWAP_16(x) << 16) | DT_BSWAP_16((x) >> 16))
517 #define DT_BSWAP_64(x) ((DT_BSWAP_32(x) << 32) | DT_BSWAP_32((x) >> 32))
518
519 #define DT_MASK_LO 0x00000000FFFFFFFFULL
520
521 #define DTRACE_STORE(type, tomax, offset, what) \
522 *((type *)((uintptr_t)(tomax) + (uintptr_t)offset)) = (type)(what);
523
524
525 #define DTRACE_ALIGNCHECK(addr, size, flags) \
526 if (addr & (MIN(size,4) - 1)) { \
527 *flags |= CPU_DTRACE_BADALIGN; \
528 cpu_core[CPU->cpu_id].cpuc_dtrace_illval = addr; \
529 return (0); \
530 }
531
532 #define DTRACE_RANGE_REMAIN(remp, addr, baseaddr, basesz) \
533 do { \
534 if ((remp) != NULL) { \
535 *(remp) = (uintptr_t)(baseaddr) + (basesz) - (addr); \
536 } \
537 } while (0)
538
539
540 /*
541 * Test whether a range of memory starting at testaddr of size testsz falls
542 * within the range of memory described by addr, sz. We take care to avoid
543 * problems with overflow and underflow of the unsigned quantities, and
544 * disallow all negative sizes. Ranges of size 0 are allowed.
545 */
546 #define DTRACE_INRANGE(testaddr, testsz, baseaddr, basesz) \
547 ((testaddr) - (baseaddr) < (basesz) && \
548 (testaddr) + (testsz) - (baseaddr) <= (basesz) && \
549 (testaddr) + (testsz) >= (testaddr))
550
551 /*
552 * Test whether alloc_sz bytes will fit in the scratch region. We isolate
553 * alloc_sz on the righthand side of the comparison in order to avoid overflow
554 * or underflow in the comparison with it. This is simpler than the INRANGE
555 * check above, because we know that the dtms_scratch_ptr is valid in the
556 * range. Allocations of size zero are allowed.
557 */
558 #define DTRACE_INSCRATCH(mstate, alloc_sz) \
559 ((mstate)->dtms_scratch_base + (mstate)->dtms_scratch_size - \
560 (mstate)->dtms_scratch_ptr >= (alloc_sz))
561
562 #define RECOVER_LABEL(bits) dtraceLoadRecover##bits:
563
564 #if defined (__x86_64__) || (defined (__arm__) || defined (__arm64__))
565 #define DTRACE_LOADFUNC(bits) \
566 /*CSTYLED*/ \
567 uint##bits##_t dtrace_load##bits(uintptr_t addr); \
568 \
569 uint##bits##_t \
570 dtrace_load##bits(uintptr_t addr) \
571 { \
572 size_t size = bits / NBBY; \
573 /*CSTYLED*/ \
574 uint##bits##_t rval = 0; \
575 int i; \
576 volatile uint16_t *flags = (volatile uint16_t *) \
577 &cpu_core[CPU->cpu_id].cpuc_dtrace_flags; \
578 \
579 DTRACE_ALIGNCHECK(addr, size, flags); \
580 \
581 for (i = 0; i < dtrace_toxranges; i++) { \
582 if (addr >= dtrace_toxrange[i].dtt_limit) \
583 continue; \
584 \
585 if (addr + size <= dtrace_toxrange[i].dtt_base) \
586 continue; \
587 \
588 /* \
589 * This address falls within a toxic region; return 0. \
590 */ \
591 *flags |= CPU_DTRACE_BADADDR; \
592 cpu_core[CPU->cpu_id].cpuc_dtrace_illval = addr; \
593 return (0); \
594 } \
595 \
596 { \
597 volatile vm_offset_t recover = (vm_offset_t)&&dtraceLoadRecover##bits; \
598 *flags |= CPU_DTRACE_NOFAULT; \
599 recover = dtrace_sign_and_set_thread_recover(current_thread(), recover); \
600 /*CSTYLED*/ \
601 /* \
602 * PR6394061 - avoid device memory that is unpredictably \
603 * mapped and unmapped \
604 */ \
605 if (pmap_valid_page(pmap_find_phys(kernel_pmap, addr))) \
606 rval = *((volatile uint##bits##_t *)addr); \
607 else { \
608 *flags |= CPU_DTRACE_BADADDR; \
609 cpu_core[CPU->cpu_id].cpuc_dtrace_illval = addr; \
610 return (0); \
611 } \
612 \
613 RECOVER_LABEL(bits); \
614 (void)dtrace_set_thread_recover(current_thread(), recover); \
615 *flags &= ~CPU_DTRACE_NOFAULT; \
616 } \
617 \
618 return (rval); \
619 }
620 #else /* all other architectures */
621 #error Unknown Architecture
622 #endif
623
624 #ifdef __LP64__
625 #define dtrace_loadptr dtrace_load64
626 #else
627 #define dtrace_loadptr dtrace_load32
628 #endif
629
630 #define DTRACE_DYNHASH_FREE 0
631 #define DTRACE_DYNHASH_SINK 1
632 #define DTRACE_DYNHASH_VALID 2
633
634 #define DTRACE_MATCH_FAIL -1
635 #define DTRACE_MATCH_NEXT 0
636 #define DTRACE_MATCH_DONE 1
637 #define DTRACE_ANCHORED(probe) ((probe)->dtpr_func[0] != '\0')
638 #define DTRACE_STATE_ALIGN 64
639
640 #define DTRACE_FLAGS2FLT(flags) \
641 (((flags) & CPU_DTRACE_BADADDR) ? DTRACEFLT_BADADDR : \
642 ((flags) & CPU_DTRACE_ILLOP) ? DTRACEFLT_ILLOP : \
643 ((flags) & CPU_DTRACE_DIVZERO) ? DTRACEFLT_DIVZERO : \
644 ((flags) & CPU_DTRACE_KPRIV) ? DTRACEFLT_KPRIV : \
645 ((flags) & CPU_DTRACE_UPRIV) ? DTRACEFLT_UPRIV : \
646 ((flags) & CPU_DTRACE_TUPOFLOW) ? DTRACEFLT_TUPOFLOW : \
647 ((flags) & CPU_DTRACE_BADALIGN) ? DTRACEFLT_BADALIGN : \
648 ((flags) & CPU_DTRACE_NOSCRATCH) ? DTRACEFLT_NOSCRATCH : \
649 ((flags) & CPU_DTRACE_BADSTACK) ? DTRACEFLT_BADSTACK : \
650 DTRACEFLT_UNKNOWN)
651
652 #define DTRACEACT_ISSTRING(act) \
653 ((act)->dta_kind == DTRACEACT_DIFEXPR && \
654 (act)->dta_difo->dtdo_rtype.dtdt_kind == DIF_TYPE_STRING)
655
656
657 static size_t dtrace_strlen(const char *, size_t);
658 static dtrace_probe_t *dtrace_probe_lookup_id(dtrace_id_t id);
659 static void dtrace_enabling_provide(dtrace_provider_t *);
660 static int dtrace_enabling_match(dtrace_enabling_t *, int *, dtrace_match_cond_t *cond);
661 static void dtrace_enabling_matchall_with_cond(dtrace_match_cond_t *cond);
662 static void dtrace_enabling_matchall(void);
663 static dtrace_state_t *dtrace_anon_grab(void);
664 static uint64_t dtrace_helper(int, dtrace_mstate_t *,
665 dtrace_state_t *, uint64_t, uint64_t);
666 static dtrace_helpers_t *dtrace_helpers_create(proc_t *);
667 static void dtrace_buffer_drop(dtrace_buffer_t *);
668 static intptr_t dtrace_buffer_reserve(dtrace_buffer_t *, size_t, size_t,
669 dtrace_state_t *, dtrace_mstate_t *);
670 static int dtrace_state_option(dtrace_state_t *, dtrace_optid_t,
671 dtrace_optval_t);
672 static int dtrace_ecb_create_enable(dtrace_probe_t *, void *, void *);
673 static void dtrace_helper_provider_destroy(dtrace_helper_provider_t *);
674 static int dtrace_canload_remains(uint64_t, size_t, size_t *,
675 dtrace_mstate_t *, dtrace_vstate_t *);
676 static int dtrace_canstore_remains(uint64_t, size_t, size_t *,
677 dtrace_mstate_t *, dtrace_vstate_t *);
678
679
680 /*
681 * DTrace sysctl handlers
682 *
683 * These declarations and functions are used for a deeper DTrace configuration.
684 * Most of them are not per-consumer basis and may impact the other DTrace
685 * consumers. Correctness may not be supported for all the variables, so you
686 * should be careful about what values you are using.
687 */
688
689 SYSCTL_DECL(_kern_dtrace);
690 SYSCTL_NODE(_kern, OID_AUTO, dtrace, CTLFLAG_RW | CTLFLAG_LOCKED, 0, "dtrace");
691
692 static int
693 sysctl_dtrace_err_verbose SYSCTL_HANDLER_ARGS
694 {
695 #pragma unused(oidp, arg2)
696 int changed, error;
697 int value = *(int *) arg1;
698
699 error = sysctl_io_number(req, value, sizeof(value), &value, &changed);
700 if (error || !changed)
701 return (error);
702
703 if (value != 0 && value != 1)
704 return (ERANGE);
705
706 lck_mtx_lock(&dtrace_lock);
707 dtrace_err_verbose = value;
708 lck_mtx_unlock(&dtrace_lock);
709
710 return (0);
711 }
712
713 /*
714 * kern.dtrace.err_verbose
715 *
716 * Set DTrace verbosity when an error occured (0 = disabled, 1 = enabld).
717 * Errors are reported when a DIFO or a DOF has been rejected by the kernel.
718 */
719 SYSCTL_PROC(_kern_dtrace, OID_AUTO, err_verbose,
720 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
721 &dtrace_err_verbose, 0,
722 sysctl_dtrace_err_verbose, "I", "dtrace error verbose");
723
724 static int
725 sysctl_dtrace_buffer_memory_maxsize SYSCTL_HANDLER_ARGS
726 {
727 #pragma unused(oidp, arg2, req)
728 int changed, error;
729 uint64_t value = *(uint64_t *) arg1;
730
731 error = sysctl_io_number(req, value, sizeof(value), &value, &changed);
732 if (error || !changed)
733 return (error);
734
735 if (value <= dtrace_buffer_memory_inuse)
736 return (ERANGE);
737
738 lck_mtx_lock(&dtrace_lock);
739 dtrace_buffer_memory_maxsize = value;
740 lck_mtx_unlock(&dtrace_lock);
741
742 return (0);
743 }
744
745 /*
746 * kern.dtrace.buffer_memory_maxsize
747 *
748 * Set DTrace maximal size in bytes used by all the consumers' state buffers. By default
749 * the limit is PHYS_MEM / 3 for *all* consumers. Attempting to set a null, a negative value
750 * or a value <= to dtrace_buffer_memory_inuse will result in a failure.
751 */
752 SYSCTL_PROC(_kern_dtrace, OID_AUTO, buffer_memory_maxsize,
753 CTLTYPE_QUAD | CTLFLAG_RW | CTLFLAG_LOCKED,
754 &dtrace_buffer_memory_maxsize, 0,
755 sysctl_dtrace_buffer_memory_maxsize, "Q", "dtrace state buffer memory maxsize");
756
757 /*
758 * kern.dtrace.buffer_memory_inuse
759 *
760 * Current state buffer memory used, in bytes, by all the DTrace consumers.
761 * This value is read-only.
762 */
763 SYSCTL_QUAD(_kern_dtrace, OID_AUTO, buffer_memory_inuse, CTLFLAG_RD | CTLFLAG_LOCKED,
764 &dtrace_buffer_memory_inuse, "dtrace state buffer memory in-use");
765
766 static int
767 sysctl_dtrace_difo_maxsize SYSCTL_HANDLER_ARGS
768 {
769 #pragma unused(oidp, arg2, req)
770 int changed, error;
771 size_t value = *(size_t*) arg1;
772
773 error = sysctl_io_number(req, value, sizeof(value), &value, &changed);
774 if (error || !changed)
775 return (error);
776
777 if (value <= 0)
778 return (ERANGE);
779
780 lck_mtx_lock(&dtrace_lock);
781 dtrace_difo_maxsize = value;
782 lck_mtx_unlock(&dtrace_lock);
783
784 return (0);
785 }
786
787 /*
788 * kern.dtrace.difo_maxsize
789 *
790 * Set the DIFO max size in bytes, check the definition of dtrace_difo_maxsize
791 * to get the default value. Attempting to set a null or negative size will
792 * result in a failure.
793 */
794 SYSCTL_PROC(_kern_dtrace, OID_AUTO, difo_maxsize,
795 CTLTYPE_QUAD | CTLFLAG_RW | CTLFLAG_LOCKED,
796 &dtrace_difo_maxsize, 0,
797 sysctl_dtrace_difo_maxsize, "Q", "dtrace difo maxsize");
798
799 static int
800 sysctl_dtrace_dof_maxsize SYSCTL_HANDLER_ARGS
801 {
802 #pragma unused(oidp, arg2, req)
803 int changed, error;
804 dtrace_optval_t value = *(dtrace_optval_t *) arg1;
805
806 error = sysctl_io_number(req, value, sizeof(value), &value, &changed);
807 if (error || !changed)
808 return (error);
809
810 if (value <= 0)
811 return (ERANGE);
812
813 if (value >= dtrace_copy_maxsize())
814 return (ERANGE);
815
816 lck_mtx_lock(&dtrace_lock);
817 dtrace_dof_maxsize = value;
818 lck_mtx_unlock(&dtrace_lock);
819
820 return (0);
821 }
822
823 /*
824 * kern.dtrace.dof_maxsize
825 *
826 * Set the DOF max size in bytes, check the definition of dtrace_dof_maxsize to
827 * get the default value. Attempting to set a null or negative size will result
828 * in a failure.
829 */
830 SYSCTL_PROC(_kern_dtrace, OID_AUTO, dof_maxsize,
831 CTLTYPE_QUAD | CTLFLAG_RW | CTLFLAG_LOCKED,
832 &dtrace_dof_maxsize, 0,
833 sysctl_dtrace_dof_maxsize, "Q", "dtrace dof maxsize");
834
835 static int
836 sysctl_dtrace_statvar_maxsize SYSCTL_HANDLER_ARGS
837 {
838 #pragma unused(oidp, arg2, req)
839 int changed, error;
840 dtrace_optval_t value = *(dtrace_optval_t*) arg1;
841
842 error = sysctl_io_number(req, value, sizeof(value), &value, &changed);
843 if (error || !changed)
844 return (error);
845
846 if (value <= 0)
847 return (ERANGE);
848 if (value > dtrace_statvar_maxsize_max)
849 return (ERANGE);
850
851 lck_mtx_lock(&dtrace_lock);
852 dtrace_statvar_maxsize = value;
853 lck_mtx_unlock(&dtrace_lock);
854
855 return (0);
856 }
857
858 /*
859 * kern.dtrace.global_maxsize
860 *
861 * Set the variable max size in bytes, check the definition of
862 * dtrace_statvar_maxsize to get the default value. Attempting to set a null,
863 * too high or negative size will result in a failure.
864 */
865 SYSCTL_PROC(_kern_dtrace, OID_AUTO, global_maxsize,
866 CTLTYPE_QUAD | CTLFLAG_RW | CTLFLAG_LOCKED,
867 &dtrace_statvar_maxsize, 0,
868 sysctl_dtrace_statvar_maxsize, "Q", "dtrace statvar maxsize");
869
870
871 /*
872 * kern.dtrace.provide_private_probes
873 *
874 * Set whether the providers must provide the private probes. This is
875 * kept as compatibility as they are always provided.
876 */
877 SYSCTL_INT(_kern_dtrace, OID_AUTO, provide_private_probes,
878 CTLFLAG_RD | CTLFLAG_LOCKED,
879 (int *)NULL, 1, "provider must provide the private probes");
880
881 /*
882 * kern.dtrace.dof_mode
883 *
884 * Returns the current DOF mode.
885 * This value is read-only.
886 */
887 SYSCTL_INT(_kern_dtrace, OID_AUTO, dof_mode, CTLFLAG_RD | CTLFLAG_LOCKED,
888 &dtrace_dof_mode, 0, "dtrace dof mode");
889
890 /*
891 * DTrace Probe Context Functions
892 *
893 * These functions are called from probe context. Because probe context is
894 * any context in which C may be called, arbitrarily locks may be held,
895 * interrupts may be disabled, we may be in arbitrary dispatched state, etc.
896 * As a result, functions called from probe context may only call other DTrace
897 * support functions -- they may not interact at all with the system at large.
898 * (Note that the ASSERT macro is made probe-context safe by redefining it in
899 * terms of dtrace_assfail(), a probe-context safe function.) If arbitrary
900 * loads are to be performed from probe context, they _must_ be in terms of
901 * the safe dtrace_load*() variants.
902 *
903 * Some functions in this block are not actually called from probe context;
904 * for these functions, there will be a comment above the function reading
905 * "Note: not called from probe context."
906 */
907
908 int
dtrace_assfail(const char * a,const char * f,int l)909 dtrace_assfail(const char *a, const char *f, int l)
910 {
911 panic("dtrace: assertion failed: %s, file: %s, line: %d", a, f, l);
912
913 /*
914 * We just need something here that even the most clever compiler
915 * cannot optimize away.
916 */
917 return (a[(uintptr_t)f]);
918 }
919
920 /*
921 * Atomically increment a specified error counter from probe context.
922 */
923 static void
dtrace_error(uint32_t * counter)924 dtrace_error(uint32_t *counter)
925 {
926 /*
927 * Most counters stored to in probe context are per-CPU counters.
928 * However, there are some error conditions that are sufficiently
929 * arcane that they don't merit per-CPU storage. If these counters
930 * are incremented concurrently on different CPUs, scalability will be
931 * adversely affected -- but we don't expect them to be white-hot in a
932 * correctly constructed enabling...
933 */
934 uint32_t oval, nval;
935
936 do {
937 oval = *counter;
938
939 if ((nval = oval + 1) == 0) {
940 /*
941 * If the counter would wrap, set it to 1 -- assuring
942 * that the counter is never zero when we have seen
943 * errors. (The counter must be 32-bits because we
944 * aren't guaranteed a 64-bit compare&swap operation.)
945 * To save this code both the infamy of being fingered
946 * by a priggish news story and the indignity of being
947 * the target of a neo-puritan witch trial, we're
948 * carefully avoiding any colorful description of the
949 * likelihood of this condition -- but suffice it to
950 * say that it is only slightly more likely than the
951 * overflow of predicate cache IDs, as discussed in
952 * dtrace_predicate_create().
953 */
954 nval = 1;
955 }
956 } while (dtrace_cas32(counter, oval, nval) != oval);
957 }
958
959 /*
960 * Use the DTRACE_LOADFUNC macro to define functions for each of loading a
961 * uint8_t, a uint16_t, a uint32_t and a uint64_t.
962 */
963 DTRACE_LOADFUNC(8)
964 DTRACE_LOADFUNC(16)
965 DTRACE_LOADFUNC(32)
966 DTRACE_LOADFUNC(64)
967
968 static int
dtrace_inscratch(uintptr_t dest,size_t size,dtrace_mstate_t * mstate)969 dtrace_inscratch(uintptr_t dest, size_t size, dtrace_mstate_t *mstate)
970 {
971 if (dest < mstate->dtms_scratch_base)
972 return (0);
973
974 if (dest + size < dest)
975 return (0);
976
977 if (dest + size > mstate->dtms_scratch_ptr)
978 return (0);
979
980 return (1);
981 }
982
983 static int
dtrace_canstore_statvar(uint64_t addr,size_t sz,size_t * remain,dtrace_statvar_t ** svars,int nsvars)984 dtrace_canstore_statvar(uint64_t addr, size_t sz, size_t *remain,
985 dtrace_statvar_t **svars, int nsvars)
986 {
987 int i;
988
989 size_t maxglobalsize, maxlocalsize;
990
991 maxglobalsize = dtrace_statvar_maxsize + sizeof (uint64_t);
992 maxlocalsize = (maxglobalsize) * NCPU;
993
994 if (nsvars == 0)
995 return (0);
996
997 for (i = 0; i < nsvars; i++) {
998 dtrace_statvar_t *svar = svars[i];
999 uint8_t scope;
1000 size_t size;
1001
1002 if (svar == NULL || (size = svar->dtsv_size) == 0)
1003 continue;
1004
1005 scope = svar->dtsv_var.dtdv_scope;
1006
1007 /**
1008 * We verify that our size is valid in the spirit of providing
1009 * defense in depth: we want to prevent attackers from using
1010 * DTrace to escalate an orthogonal kernel heap corruption bug
1011 * into the ability to store to arbitrary locations in memory.
1012 */
1013 VERIFY((scope == DIFV_SCOPE_GLOBAL && size <= maxglobalsize) ||
1014 (scope == DIFV_SCOPE_LOCAL && size <= maxlocalsize));
1015
1016 if (DTRACE_INRANGE(addr, sz, svar->dtsv_data, svar->dtsv_size)) {
1017 DTRACE_RANGE_REMAIN(remain, addr, svar->dtsv_data,
1018 svar->dtsv_size);
1019 return (1);
1020 }
1021 }
1022
1023 return (0);
1024 }
1025
1026 /*
1027 * Check to see if the address is within a memory region to which a store may
1028 * be issued. This includes the DTrace scratch areas, and any DTrace variable
1029 * region. The caller of dtrace_canstore() is responsible for performing any
1030 * alignment checks that are needed before stores are actually executed.
1031 */
1032 static int
dtrace_canstore(uint64_t addr,size_t sz,dtrace_mstate_t * mstate,dtrace_vstate_t * vstate)1033 dtrace_canstore(uint64_t addr, size_t sz, dtrace_mstate_t *mstate,
1034 dtrace_vstate_t *vstate)
1035 {
1036 return (dtrace_canstore_remains(addr, sz, NULL, mstate, vstate));
1037 }
1038 /*
1039 * Implementation of dtrace_canstore which communicates the upper bound of the
1040 * allowed memory region.
1041 */
1042 static int
dtrace_canstore_remains(uint64_t addr,size_t sz,size_t * remain,dtrace_mstate_t * mstate,dtrace_vstate_t * vstate)1043 dtrace_canstore_remains(uint64_t addr, size_t sz, size_t *remain,
1044 dtrace_mstate_t *mstate, dtrace_vstate_t *vstate)
1045 {
1046 /*
1047 * First, check to see if the address is in scratch space...
1048 */
1049 if (DTRACE_INRANGE(addr, sz, mstate->dtms_scratch_base,
1050 mstate->dtms_scratch_size)) {
1051 DTRACE_RANGE_REMAIN(remain, addr, mstate->dtms_scratch_base,
1052 mstate->dtms_scratch_size);
1053 return (1);
1054 }
1055 /*
1056 * Now check to see if it's a dynamic variable. This check will pick
1057 * up both thread-local variables and any global dynamically-allocated
1058 * variables.
1059 */
1060 if (DTRACE_INRANGE(addr, sz, (uintptr_t)vstate->dtvs_dynvars.dtds_base,
1061 vstate->dtvs_dynvars.dtds_size)) {
1062 dtrace_dstate_t *dstate = &vstate->dtvs_dynvars;
1063 uintptr_t base = (uintptr_t)dstate->dtds_base +
1064 (dstate->dtds_hashsize * sizeof (dtrace_dynhash_t));
1065 uintptr_t chunkoffs;
1066 dtrace_dynvar_t *dvar;
1067
1068 /*
1069 * Before we assume that we can store here, we need to make
1070 * sure that it isn't in our metadata -- storing to our
1071 * dynamic variable metadata would corrupt our state. For
1072 * the range to not include any dynamic variable metadata,
1073 * it must:
1074 *
1075 * (1) Start above the hash table that is at the base of
1076 * the dynamic variable space
1077 *
1078 * (2) Have a starting chunk offset that is beyond the
1079 * dtrace_dynvar_t that is at the base of every chunk
1080 *
1081 * (3) Not span a chunk boundary
1082 *
1083 * (4) Not be in the tuple space of a dynamic variable
1084 *
1085 */
1086 if (addr < base)
1087 return (0);
1088
1089 chunkoffs = (addr - base) % dstate->dtds_chunksize;
1090
1091 if (chunkoffs < sizeof (dtrace_dynvar_t))
1092 return (0);
1093
1094 if (chunkoffs + sz > dstate->dtds_chunksize)
1095 return (0);
1096
1097 dvar = (dtrace_dynvar_t *)((uintptr_t)addr - chunkoffs);
1098
1099 if (dvar->dtdv_hashval == DTRACE_DYNHASH_FREE)
1100 return (0);
1101
1102 if (chunkoffs < sizeof (dtrace_dynvar_t) +
1103 ((dvar->dtdv_tuple.dtt_nkeys - 1) * sizeof (dtrace_key_t)))
1104 return (0);
1105
1106 return (1);
1107 }
1108
1109 /*
1110 * Finally, check the static local and global variables. These checks
1111 * take the longest, so we perform them last.
1112 */
1113 if (dtrace_canstore_statvar(addr, sz, remain,
1114 vstate->dtvs_locals, vstate->dtvs_nlocals))
1115 return (1);
1116
1117 if (dtrace_canstore_statvar(addr, sz, remain,
1118 vstate->dtvs_globals, vstate->dtvs_nglobals))
1119 return (1);
1120
1121 return (0);
1122 }
1123
1124
1125 /*
1126 * Convenience routine to check to see if the address is within a memory
1127 * region in which a load may be issued given the user's privilege level;
1128 * if not, it sets the appropriate error flags and loads 'addr' into the
1129 * illegal value slot.
1130 *
1131 * DTrace subroutines (DIF_SUBR_*) should use this helper to implement
1132 * appropriate memory access protection.
1133 */
1134 int
dtrace_canload(uint64_t addr,size_t sz,dtrace_mstate_t * mstate,dtrace_vstate_t * vstate)1135 dtrace_canload(uint64_t addr, size_t sz, dtrace_mstate_t *mstate,
1136 dtrace_vstate_t *vstate)
1137 {
1138 return (dtrace_canload_remains(addr, sz, NULL, mstate, vstate));
1139 }
1140
1141 /*
1142 * Implementation of dtrace_canload which communicates the upper bound of the
1143 * allowed memory region.
1144 */
1145 static int
dtrace_canload_remains(uint64_t addr,size_t sz,size_t * remain,dtrace_mstate_t * mstate,dtrace_vstate_t * vstate)1146 dtrace_canload_remains(uint64_t addr, size_t sz, size_t *remain,
1147 dtrace_mstate_t *mstate, dtrace_vstate_t *vstate)
1148 {
1149 volatile uint64_t *illval = &cpu_core[CPU->cpu_id].cpuc_dtrace_illval;
1150
1151 /*
1152 * If we hold the privilege to read from kernel memory, then
1153 * everything is readable.
1154 */
1155 if ((mstate->dtms_access & DTRACE_ACCESS_KERNEL) != 0) {
1156 DTRACE_RANGE_REMAIN(remain, addr, addr, sz);
1157 return (1);
1158 }
1159
1160 /*
1161 * You can obviously read that which you can store.
1162 */
1163 if (dtrace_canstore_remains(addr, sz, remain, mstate, vstate))
1164 return (1);
1165
1166 /*
1167 * We're allowed to read from our own string table.
1168 */
1169 if (DTRACE_INRANGE(addr, sz, (uintptr_t)mstate->dtms_difo->dtdo_strtab,
1170 mstate->dtms_difo->dtdo_strlen)) {
1171 DTRACE_RANGE_REMAIN(remain, addr,
1172 mstate->dtms_difo->dtdo_strtab,
1173 mstate->dtms_difo->dtdo_strlen);
1174 return (1);
1175 }
1176
1177 DTRACE_CPUFLAG_SET(CPU_DTRACE_KPRIV);
1178 *illval = addr;
1179 return (0);
1180 }
1181
1182 /*
1183 * Convenience routine to check to see if a given string is within a memory
1184 * region in which a load may be issued given the user's privilege level;
1185 * this exists so that we don't need to issue unnecessary dtrace_strlen()
1186 * calls in the event that the user has all privileges.
1187 */
1188 static int
dtrace_strcanload(uint64_t addr,size_t sz,size_t * remain,dtrace_mstate_t * mstate,dtrace_vstate_t * vstate)1189 dtrace_strcanload(uint64_t addr, size_t sz, size_t *remain,
1190 dtrace_mstate_t *mstate, dtrace_vstate_t *vstate)
1191 {
1192 size_t rsize = 0;
1193
1194 /*
1195 * If we hold the privilege to read from kernel memory, then
1196 * everything is readable.
1197 */
1198 if ((mstate->dtms_access & DTRACE_ACCESS_KERNEL) != 0) {
1199 DTRACE_RANGE_REMAIN(remain, addr, addr, sz);
1200 return (1);
1201 }
1202
1203 /*
1204 * Even if the caller is uninterested in querying the remaining valid
1205 * range, it is required to ensure that the access is allowed.
1206 */
1207 if (remain == NULL) {
1208 remain = &rsize;
1209 }
1210 if (dtrace_canload_remains(addr, 0, remain, mstate, vstate)) {
1211 size_t strsz;
1212 /*
1213 * Perform the strlen after determining the length of the
1214 * memory region which is accessible. This prevents timing
1215 * information from being used to find NULs in memory which is
1216 * not accessible to the caller.
1217 */
1218 strsz = 1 + dtrace_strlen((char *)(uintptr_t)addr,
1219 MIN(sz, *remain));
1220 if (strsz <= *remain) {
1221 return (1);
1222 }
1223 }
1224
1225 return (0);
1226 }
1227
1228 /*
1229 * Convenience routine to check to see if a given variable is within a memory
1230 * region in which a load may be issued given the user's privilege level.
1231 */
1232 static int
dtrace_vcanload(void * src,dtrace_diftype_t * type,size_t * remain,dtrace_mstate_t * mstate,dtrace_vstate_t * vstate)1233 dtrace_vcanload(void *src, dtrace_diftype_t *type, size_t *remain,
1234 dtrace_mstate_t *mstate, dtrace_vstate_t *vstate)
1235 {
1236 size_t sz;
1237 ASSERT(type->dtdt_flags & DIF_TF_BYREF);
1238
1239 /*
1240 * Calculate the max size before performing any checks since even
1241 * DTRACE_ACCESS_KERNEL-credentialed callers expect that this function
1242 * return the max length via 'remain'.
1243 */
1244 if (type->dtdt_kind == DIF_TYPE_STRING) {
1245 dtrace_state_t *state = vstate->dtvs_state;
1246
1247 if (state != NULL) {
1248 sz = state->dts_options[DTRACEOPT_STRSIZE];
1249 } else {
1250 /*
1251 * In helper context, we have a NULL state; fall back
1252 * to using the system-wide default for the string size
1253 * in this case.
1254 */
1255 sz = dtrace_strsize_default;
1256 }
1257 } else {
1258 sz = type->dtdt_size;
1259 }
1260
1261 /*
1262 * If we hold the privilege to read from kernel memory, then
1263 * everything is readable.
1264 */
1265 if ((mstate->dtms_access & DTRACE_ACCESS_KERNEL) != 0) {
1266 DTRACE_RANGE_REMAIN(remain, (uintptr_t)src, src, sz);
1267 return (1);
1268 }
1269
1270 if (type->dtdt_kind == DIF_TYPE_STRING) {
1271 return (dtrace_strcanload((uintptr_t)src, sz, remain, mstate,
1272 vstate));
1273 }
1274 return (dtrace_canload_remains((uintptr_t)src, sz, remain, mstate,
1275 vstate));
1276 }
1277
1278 #define isdigit(ch) ((ch) >= '0' && (ch) <= '9')
1279 #define islower(ch) ((ch) >= 'a' && (ch) <= 'z')
1280 #define isspace(ch) (((ch) == ' ') || ((ch) == '\r') || ((ch) == '\n') || \
1281 ((ch) == '\t') || ((ch) == '\f'))
1282 #define isxdigit(ch) (isdigit(ch) || ((ch) >= 'a' && (ch) <= 'f') || \
1283 ((ch) >= 'A' && (ch) <= 'F'))
1284 #define lisalnum(x) \
1285 (isdigit(x) || ((x) >= 'a' && (x) <= 'z') || ((x) >= 'A' && (x) <= 'Z'))
1286
1287 #define DIGIT(x) \
1288 (isdigit(x) ? (x) - '0' : islower(x) ? (x) + 10 - 'a' : (x) + 10 - 'A')
1289
1290 /*
1291 * Convert a string to a signed integer using safe loads.
1292 */
1293 static int64_t
dtrace_strtoll(char * input,int base,size_t limit)1294 dtrace_strtoll(char *input, int base, size_t limit)
1295 {
1296 uintptr_t pos = (uintptr_t)input;
1297 int64_t val = 0;
1298 int x;
1299 boolean_t neg = B_FALSE;
1300 char c, cc, ccc;
1301 uintptr_t end = pos + limit;
1302
1303 /*
1304 * Consume any whitespace preceding digits.
1305 */
1306 while ((c = dtrace_load8(pos)) == ' ' || c == '\t')
1307 pos++;
1308
1309 /*
1310 * Handle an explicit sign if one is present.
1311 */
1312 if (c == '-' || c == '+') {
1313 if (c == '-')
1314 neg = B_TRUE;
1315 c = dtrace_load8(++pos);
1316 }
1317
1318 /*
1319 * Check for an explicit hexadecimal prefix ("0x" or "0X") and skip it
1320 * if present.
1321 */
1322 if (base == 16 && c == '0' && ((cc = dtrace_load8(pos + 1)) == 'x' ||
1323 cc == 'X') && isxdigit(ccc = dtrace_load8(pos + 2))) {
1324 pos += 2;
1325 c = ccc;
1326 }
1327
1328 /*
1329 * Read in contiguous digits until the first non-digit character.
1330 */
1331 for (; pos < end && c != '\0' && lisalnum(c) && (x = DIGIT(c)) < base;
1332 c = dtrace_load8(++pos))
1333 val = val * base + x;
1334
1335 return (neg ? -val : val);
1336 }
1337
1338
1339 /*
1340 * Compare two strings using safe loads.
1341 */
1342 static int
dtrace_strncmp(const char * s1,const char * s2,size_t limit)1343 dtrace_strncmp(const char *s1, const char *s2, size_t limit)
1344 {
1345 uint8_t c1, c2;
1346 volatile uint16_t *flags;
1347
1348 if (s1 == s2 || limit == 0)
1349 return (0);
1350
1351 flags = (volatile uint16_t *)&cpu_core[CPU->cpu_id].cpuc_dtrace_flags;
1352
1353 do {
1354 if (s1 == NULL) {
1355 c1 = '\0';
1356 } else {
1357 c1 = dtrace_load8((uintptr_t)s1++);
1358 }
1359
1360 if (s2 == NULL) {
1361 c2 = '\0';
1362 } else {
1363 c2 = dtrace_load8((uintptr_t)s2++);
1364 }
1365
1366 if (c1 != c2)
1367 return (c1 - c2);
1368 } while (--limit && c1 != '\0' && !(*flags & CPU_DTRACE_FAULT));
1369
1370 return (0);
1371 }
1372
1373 /*
1374 * Compute strlen(s) for a string using safe memory accesses. The additional
1375 * len parameter is used to specify a maximum length to ensure completion.
1376 */
1377 static size_t
dtrace_strlen(const char * s,size_t lim)1378 dtrace_strlen(const char *s, size_t lim)
1379 {
1380 uint_t len;
1381
1382 for (len = 0; len != lim; len++) {
1383 if (dtrace_load8((uintptr_t)s++) == '\0')
1384 break;
1385 }
1386
1387 return (len);
1388 }
1389
1390 /*
1391 * Check if an address falls within a toxic region.
1392 */
1393 static int
dtrace_istoxic(uintptr_t kaddr,size_t size)1394 dtrace_istoxic(uintptr_t kaddr, size_t size)
1395 {
1396 uintptr_t taddr, tsize;
1397 int i;
1398
1399 for (i = 0; i < dtrace_toxranges; i++) {
1400 taddr = dtrace_toxrange[i].dtt_base;
1401 tsize = dtrace_toxrange[i].dtt_limit - taddr;
1402
1403 if (kaddr - taddr < tsize) {
1404 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
1405 cpu_core[CPU->cpu_id].cpuc_dtrace_illval = kaddr;
1406 return (1);
1407 }
1408
1409 if (taddr - kaddr < size) {
1410 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
1411 cpu_core[CPU->cpu_id].cpuc_dtrace_illval = taddr;
1412 return (1);
1413 }
1414 }
1415
1416 return (0);
1417 }
1418
1419 /*
1420 * Copy src to dst using safe memory accesses. The src is assumed to be unsafe
1421 * memory specified by the DIF program. The dst is assumed to be safe memory
1422 * that we can store to directly because it is managed by DTrace. As with
1423 * standard bcopy, overlapping copies are handled properly.
1424 */
1425 static void
dtrace_bcopy(const void * src,void * dst,size_t len)1426 dtrace_bcopy(const void *src, void *dst, size_t len)
1427 {
1428 if (len != 0) {
1429 uint8_t *s1 = dst;
1430 const uint8_t *s2 = src;
1431
1432 if (s1 <= s2) {
1433 do {
1434 *s1++ = dtrace_load8((uintptr_t)s2++);
1435 } while (--len != 0);
1436 } else {
1437 s2 += len;
1438 s1 += len;
1439
1440 do {
1441 *--s1 = dtrace_load8((uintptr_t)--s2);
1442 } while (--len != 0);
1443 }
1444 }
1445 }
1446
1447 /*
1448 * Copy src to dst using safe memory accesses, up to either the specified
1449 * length, or the point that a nul byte is encountered. The src is assumed to
1450 * be unsafe memory specified by the DIF program. The dst is assumed to be
1451 * safe memory that we can store to directly because it is managed by DTrace.
1452 * Unlike dtrace_bcopy(), overlapping regions are not handled.
1453 */
1454 static void
dtrace_strcpy(const void * src,void * dst,size_t len)1455 dtrace_strcpy(const void *src, void *dst, size_t len)
1456 {
1457 if (len != 0) {
1458 uint8_t *s1 = dst, c;
1459 const uint8_t *s2 = src;
1460
1461 do {
1462 *s1++ = c = dtrace_load8((uintptr_t)s2++);
1463 } while (--len != 0 && c != '\0');
1464 }
1465 }
1466
1467 /*
1468 * Copy src to dst, deriving the size and type from the specified (BYREF)
1469 * variable type. The src is assumed to be unsafe memory specified by the DIF
1470 * program. The dst is assumed to be DTrace variable memory that is of the
1471 * specified type; we assume that we can store to directly.
1472 */
1473 static void
dtrace_vcopy(void * src,void * dst,dtrace_diftype_t * type,size_t limit)1474 dtrace_vcopy(void *src, void *dst, dtrace_diftype_t *type, size_t limit)
1475 {
1476 ASSERT(type->dtdt_flags & DIF_TF_BYREF);
1477
1478 if (type->dtdt_kind == DIF_TYPE_STRING) {
1479 dtrace_strcpy(src, dst, MIN(type->dtdt_size, limit));
1480 } else {
1481 dtrace_bcopy(src, dst, MIN(type->dtdt_size, limit));
1482 }
1483 }
1484
1485 /*
1486 * Compare s1 to s2 using safe memory accesses. The s1 data is assumed to be
1487 * unsafe memory specified by the DIF program. The s2 data is assumed to be
1488 * safe memory that we can access directly because it is managed by DTrace.
1489 */
1490 static int
dtrace_bcmp(const void * s1,const void * s2,size_t len)1491 dtrace_bcmp(const void *s1, const void *s2, size_t len)
1492 {
1493 volatile uint16_t *flags;
1494
1495 flags = (volatile uint16_t *)&cpu_core[CPU->cpu_id].cpuc_dtrace_flags;
1496
1497 if (s1 == s2)
1498 return (0);
1499
1500 if (s1 == NULL || s2 == NULL)
1501 return (1);
1502
1503 if (s1 != s2 && len != 0) {
1504 const uint8_t *ps1 = s1;
1505 const uint8_t *ps2 = s2;
1506
1507 do {
1508 if (dtrace_load8((uintptr_t)ps1++) != *ps2++)
1509 return (1);
1510 } while (--len != 0 && !(*flags & CPU_DTRACE_FAULT));
1511 }
1512 return (0);
1513 }
1514
1515 /*
1516 * Zero the specified region using a simple byte-by-byte loop. Note that this
1517 * is for safe DTrace-managed memory only.
1518 */
1519 static void
dtrace_bzero(void * dst,size_t len)1520 dtrace_bzero(void *dst, size_t len)
1521 {
1522 uchar_t *cp;
1523
1524 for (cp = dst; len != 0; len--)
1525 *cp++ = 0;
1526 }
1527
1528 static void
dtrace_add_128(uint64_t * addend1,uint64_t * addend2,uint64_t * sum)1529 dtrace_add_128(uint64_t *addend1, uint64_t *addend2, uint64_t *sum)
1530 {
1531 uint64_t result[2];
1532
1533 result[0] = addend1[0] + addend2[0];
1534 result[1] = addend1[1] + addend2[1] +
1535 (result[0] < addend1[0] || result[0] < addend2[0] ? 1 : 0);
1536
1537 sum[0] = result[0];
1538 sum[1] = result[1];
1539 }
1540
1541 /*
1542 * Shift the 128-bit value in a by b. If b is positive, shift left.
1543 * If b is negative, shift right.
1544 */
1545 static void
dtrace_shift_128(uint64_t * a,int b)1546 dtrace_shift_128(uint64_t *a, int b)
1547 {
1548 uint64_t mask;
1549
1550 if (b == 0)
1551 return;
1552
1553 if (b < 0) {
1554 b = -b;
1555 if (b >= 64) {
1556 a[0] = a[1] >> (b - 64);
1557 a[1] = 0;
1558 } else {
1559 a[0] >>= b;
1560 mask = 1LL << (64 - b);
1561 mask -= 1;
1562 a[0] |= ((a[1] & mask) << (64 - b));
1563 a[1] >>= b;
1564 }
1565 } else {
1566 if (b >= 64) {
1567 a[1] = a[0] << (b - 64);
1568 a[0] = 0;
1569 } else {
1570 a[1] <<= b;
1571 mask = a[0] >> (64 - b);
1572 a[1] |= mask;
1573 a[0] <<= b;
1574 }
1575 }
1576 }
1577
1578 /*
1579 * The basic idea is to break the 2 64-bit values into 4 32-bit values,
1580 * use native multiplication on those, and then re-combine into the
1581 * resulting 128-bit value.
1582 *
1583 * (hi1 << 32 + lo1) * (hi2 << 32 + lo2) =
1584 * hi1 * hi2 << 64 +
1585 * hi1 * lo2 << 32 +
1586 * hi2 * lo1 << 32 +
1587 * lo1 * lo2
1588 */
1589 static void
dtrace_multiply_128(uint64_t factor1,uint64_t factor2,uint64_t * product)1590 dtrace_multiply_128(uint64_t factor1, uint64_t factor2, uint64_t *product)
1591 {
1592 uint64_t hi1, hi2, lo1, lo2;
1593 uint64_t tmp[2];
1594
1595 hi1 = factor1 >> 32;
1596 hi2 = factor2 >> 32;
1597
1598 lo1 = factor1 & DT_MASK_LO;
1599 lo2 = factor2 & DT_MASK_LO;
1600
1601 product[0] = lo1 * lo2;
1602 product[1] = hi1 * hi2;
1603
1604 tmp[0] = hi1 * lo2;
1605 tmp[1] = 0;
1606 dtrace_shift_128(tmp, 32);
1607 dtrace_add_128(product, tmp, product);
1608
1609 tmp[0] = hi2 * lo1;
1610 tmp[1] = 0;
1611 dtrace_shift_128(tmp, 32);
1612 dtrace_add_128(product, tmp, product);
1613 }
1614
1615 /*
1616 * This privilege check should be used by actions and subroutines to
1617 * verify that the user credentials of the process that enabled the
1618 * invoking ECB match the target credentials
1619 */
1620 static int
dtrace_priv_proc_common_user(dtrace_state_t * state)1621 dtrace_priv_proc_common_user(dtrace_state_t *state)
1622 {
1623 cred_t *cr, *s_cr = state->dts_cred.dcr_cred;
1624
1625 /*
1626 * We should always have a non-NULL state cred here, since if cred
1627 * is null (anonymous tracing), we fast-path bypass this routine.
1628 */
1629 ASSERT(s_cr != NULL);
1630
1631 if ((cr = dtrace_CRED()) != NULL &&
1632 posix_cred_get(s_cr)->cr_uid == posix_cred_get(cr)->cr_uid &&
1633 posix_cred_get(s_cr)->cr_uid == posix_cred_get(cr)->cr_ruid &&
1634 posix_cred_get(s_cr)->cr_uid == posix_cred_get(cr)->cr_suid &&
1635 posix_cred_get(s_cr)->cr_gid == posix_cred_get(cr)->cr_gid &&
1636 posix_cred_get(s_cr)->cr_gid == posix_cred_get(cr)->cr_rgid &&
1637 posix_cred_get(s_cr)->cr_gid == posix_cred_get(cr)->cr_sgid)
1638 return (1);
1639
1640 return (0);
1641 }
1642
1643 /*
1644 * This privilege check should be used by actions and subroutines to
1645 * verify that the zone of the process that enabled the invoking ECB
1646 * matches the target credentials
1647 */
1648 static int
dtrace_priv_proc_common_zone(dtrace_state_t * state)1649 dtrace_priv_proc_common_zone(dtrace_state_t *state)
1650 {
1651 cred_t *cr, *s_cr = state->dts_cred.dcr_cred;
1652 #pragma unused(cr, s_cr, state) /* __APPLE__ */
1653
1654 /*
1655 * We should always have a non-NULL state cred here, since if cred
1656 * is null (anonymous tracing), we fast-path bypass this routine.
1657 */
1658 ASSERT(s_cr != NULL);
1659
1660 return 1; /* APPLE NOTE: Darwin doesn't do zones. */
1661 }
1662
1663 /*
1664 * This privilege check should be used by actions and subroutines to
1665 * verify that the process has not setuid or changed credentials.
1666 */
1667 static int
dtrace_priv_proc_common_nocd(void)1668 dtrace_priv_proc_common_nocd(void)
1669 {
1670 return 1; /* Darwin omits "No Core Dump" flag. */
1671 }
1672
1673 static int
dtrace_priv_proc_destructive(dtrace_state_t * state)1674 dtrace_priv_proc_destructive(dtrace_state_t *state)
1675 {
1676 int action = state->dts_cred.dcr_action;
1677
1678 if (ISSET(current_proc()->p_lflag, P_LNOATTACH))
1679 goto bad;
1680
1681 if (dtrace_is_restricted() && !dtrace_can_attach_to_proc(current_proc()))
1682 goto bad;
1683
1684 if (((action & DTRACE_CRA_PROC_DESTRUCTIVE_ALLZONE) == 0) &&
1685 dtrace_priv_proc_common_zone(state) == 0)
1686 goto bad;
1687
1688 if (((action & DTRACE_CRA_PROC_DESTRUCTIVE_ALLUSER) == 0) &&
1689 dtrace_priv_proc_common_user(state) == 0)
1690 goto bad;
1691
1692 if (((action & DTRACE_CRA_PROC_DESTRUCTIVE_CREDCHG) == 0) &&
1693 dtrace_priv_proc_common_nocd() == 0)
1694 goto bad;
1695
1696 return (1);
1697
1698 bad:
1699 cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= CPU_DTRACE_UPRIV;
1700
1701 return (0);
1702 }
1703
1704 static int
dtrace_priv_proc_control(dtrace_state_t * state)1705 dtrace_priv_proc_control(dtrace_state_t *state)
1706 {
1707 if (ISSET(current_proc()->p_lflag, P_LNOATTACH))
1708 goto bad;
1709
1710 if (dtrace_is_restricted() && !dtrace_can_attach_to_proc(current_proc()))
1711 goto bad;
1712
1713 if (state->dts_cred.dcr_action & DTRACE_CRA_PROC_CONTROL)
1714 return (1);
1715
1716 if (dtrace_priv_proc_common_zone(state) &&
1717 dtrace_priv_proc_common_user(state) &&
1718 dtrace_priv_proc_common_nocd())
1719 return (1);
1720
1721 bad:
1722 cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= CPU_DTRACE_UPRIV;
1723
1724 return (0);
1725 }
1726
1727 static int
dtrace_priv_proc(dtrace_state_t * state)1728 dtrace_priv_proc(dtrace_state_t *state)
1729 {
1730 if (ISSET(current_proc()->p_lflag, P_LNOATTACH))
1731 goto bad;
1732
1733 if (dtrace_is_restricted() && !dtrace_are_restrictions_relaxed() && !dtrace_can_attach_to_proc(current_proc()))
1734 goto bad;
1735
1736 if (state->dts_cred.dcr_action & DTRACE_CRA_PROC)
1737 return (1);
1738
1739 bad:
1740 cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= CPU_DTRACE_UPRIV;
1741
1742 return (0);
1743 }
1744
1745 /*
1746 * The P_LNOATTACH check is an Apple specific check.
1747 * We need a version of dtrace_priv_proc() that omits
1748 * that check for PID and EXECNAME accesses
1749 */
1750 static int
dtrace_priv_proc_relaxed(dtrace_state_t * state)1751 dtrace_priv_proc_relaxed(dtrace_state_t *state)
1752 {
1753
1754 if (state->dts_cred.dcr_action & DTRACE_CRA_PROC)
1755 return (1);
1756
1757 cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= CPU_DTRACE_UPRIV;
1758
1759 return (0);
1760 }
1761
1762 static int
dtrace_priv_kernel(dtrace_state_t * state)1763 dtrace_priv_kernel(dtrace_state_t *state)
1764 {
1765 if (dtrace_is_restricted() && !dtrace_are_restrictions_relaxed())
1766 goto bad;
1767
1768 if (state->dts_cred.dcr_action & DTRACE_CRA_KERNEL)
1769 return (1);
1770
1771 bad:
1772 cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= CPU_DTRACE_KPRIV;
1773
1774 return (0);
1775 }
1776
1777 static int
dtrace_priv_kernel_destructive(dtrace_state_t * state)1778 dtrace_priv_kernel_destructive(dtrace_state_t *state)
1779 {
1780 if (dtrace_is_restricted())
1781 goto bad;
1782
1783 if (state->dts_cred.dcr_action & DTRACE_CRA_KERNEL_DESTRUCTIVE)
1784 return (1);
1785
1786 bad:
1787 cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= CPU_DTRACE_KPRIV;
1788
1789 return (0);
1790 }
1791
1792 /*
1793 * Note: not called from probe context. This function is called
1794 * asynchronously (and at a regular interval) from outside of probe context to
1795 * clean the dirty dynamic variable lists on all CPUs. Dynamic variable
1796 * cleaning is explained in detail in <sys/dtrace_impl.h>.
1797 */
1798 static void
dtrace_dynvar_clean(dtrace_dstate_t * dstate)1799 dtrace_dynvar_clean(dtrace_dstate_t *dstate)
1800 {
1801 dtrace_dynvar_t *dirty;
1802 dtrace_dstate_percpu_t *dcpu;
1803 int i, work = 0;
1804
1805 for (i = 0; i < (int)NCPU; i++) {
1806 dcpu = &dstate->dtds_percpu[i];
1807
1808 ASSERT(dcpu->dtdsc_rinsing == NULL);
1809
1810 /*
1811 * If the dirty list is NULL, there is no dirty work to do.
1812 */
1813 if (dcpu->dtdsc_dirty == NULL)
1814 continue;
1815
1816 /*
1817 * If the clean list is non-NULL, then we're not going to do
1818 * any work for this CPU -- it means that there has not been
1819 * a dtrace_dynvar() allocation on this CPU (or from this CPU)
1820 * since the last time we cleaned house.
1821 */
1822 if (dcpu->dtdsc_clean != NULL)
1823 continue;
1824
1825 work = 1;
1826
1827 /*
1828 * Atomically move the dirty list aside.
1829 */
1830 do {
1831 dirty = dcpu->dtdsc_dirty;
1832
1833 /*
1834 * Before we zap the dirty list, set the rinsing list.
1835 * (This allows for a potential assertion in
1836 * dtrace_dynvar(): if a free dynamic variable appears
1837 * on a hash chain, either the dirty list or the
1838 * rinsing list for some CPU must be non-NULL.)
1839 */
1840 dcpu->dtdsc_rinsing = dirty;
1841 dtrace_membar_producer();
1842 } while (dtrace_casptr(&dcpu->dtdsc_dirty,
1843 dirty, NULL) != dirty);
1844 }
1845
1846 if (!work) {
1847 /*
1848 * We have no work to do; we can simply return.
1849 */
1850 return;
1851 }
1852
1853 dtrace_sync();
1854
1855 for (i = 0; i < (int)NCPU; i++) {
1856 dcpu = &dstate->dtds_percpu[i];
1857
1858 if (dcpu->dtdsc_rinsing == NULL)
1859 continue;
1860
1861 /*
1862 * We are now guaranteed that no hash chain contains a pointer
1863 * into this dirty list; we can make it clean.
1864 */
1865 ASSERT(dcpu->dtdsc_clean == NULL);
1866 dcpu->dtdsc_clean = dcpu->dtdsc_rinsing;
1867 dcpu->dtdsc_rinsing = NULL;
1868 }
1869
1870 /*
1871 * Before we actually set the state to be DTRACE_DSTATE_CLEAN, make
1872 * sure that all CPUs have seen all of the dtdsc_clean pointers.
1873 * This prevents a race whereby a CPU incorrectly decides that
1874 * the state should be something other than DTRACE_DSTATE_CLEAN
1875 * after dtrace_dynvar_clean() has completed.
1876 */
1877 dtrace_sync();
1878
1879 dstate->dtds_state = DTRACE_DSTATE_CLEAN;
1880 }
1881
1882 /*
1883 * Depending on the value of the op parameter, this function looks-up,
1884 * allocates or deallocates an arbitrarily-keyed dynamic variable. If an
1885 * allocation is requested, this function will return a pointer to a
1886 * dtrace_dynvar_t corresponding to the allocated variable -- or NULL if no
1887 * variable can be allocated. If NULL is returned, the appropriate counter
1888 * will be incremented.
1889 */
1890 static dtrace_dynvar_t *
dtrace_dynvar(dtrace_dstate_t * dstate,uint_t nkeys,dtrace_key_t * key,size_t dsize,dtrace_dynvar_op_t op,dtrace_mstate_t * mstate,dtrace_vstate_t * vstate)1891 dtrace_dynvar(dtrace_dstate_t *dstate, uint_t nkeys,
1892 dtrace_key_t *key, size_t dsize, dtrace_dynvar_op_t op,
1893 dtrace_mstate_t *mstate, dtrace_vstate_t *vstate)
1894 {
1895 uint64_t hashval = DTRACE_DYNHASH_VALID;
1896 dtrace_dynhash_t *hash = dstate->dtds_hash;
1897 dtrace_dynvar_t *free, *new_free, *next, *dvar, *start, *prev = NULL;
1898 processorid_t me = CPU->cpu_id, cpu = me;
1899 dtrace_dstate_percpu_t *dcpu = &dstate->dtds_percpu[me];
1900 size_t bucket, ksize;
1901 size_t chunksize = dstate->dtds_chunksize;
1902 uintptr_t kdata, lock, nstate;
1903 uint_t i;
1904
1905 ASSERT(nkeys != 0);
1906
1907 /*
1908 * Hash the key. As with aggregations, we use Jenkins' "One-at-a-time"
1909 * algorithm. For the by-value portions, we perform the algorithm in
1910 * 16-bit chunks (as opposed to 8-bit chunks). This speeds things up a
1911 * bit, and seems to have only a minute effect on distribution. For
1912 * the by-reference data, we perform "One-at-a-time" iterating (safely)
1913 * over each referenced byte. It's painful to do this, but it's much
1914 * better than pathological hash distribution. The efficacy of the
1915 * hashing algorithm (and a comparison with other algorithms) may be
1916 * found by running the ::dtrace_dynstat MDB dcmd.
1917 */
1918 for (i = 0; i < nkeys; i++) {
1919 if (key[i].dttk_size == 0) {
1920 uint64_t val = key[i].dttk_value;
1921
1922 hashval += (val >> 48) & 0xffff;
1923 hashval += (hashval << 10);
1924 hashval ^= (hashval >> 6);
1925
1926 hashval += (val >> 32) & 0xffff;
1927 hashval += (hashval << 10);
1928 hashval ^= (hashval >> 6);
1929
1930 hashval += (val >> 16) & 0xffff;
1931 hashval += (hashval << 10);
1932 hashval ^= (hashval >> 6);
1933
1934 hashval += val & 0xffff;
1935 hashval += (hashval << 10);
1936 hashval ^= (hashval >> 6);
1937 } else {
1938 /*
1939 * This is incredibly painful, but it beats the hell
1940 * out of the alternative.
1941 */
1942 uint64_t j, size = key[i].dttk_size;
1943 uintptr_t base = (uintptr_t)key[i].dttk_value;
1944
1945 if (!dtrace_canload(base, size, mstate, vstate))
1946 break;
1947
1948 for (j = 0; j < size; j++) {
1949 hashval += dtrace_load8(base + j);
1950 hashval += (hashval << 10);
1951 hashval ^= (hashval >> 6);
1952 }
1953 }
1954 }
1955
1956 if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_FAULT))
1957 return (NULL);
1958
1959 hashval += (hashval << 3);
1960 hashval ^= (hashval >> 11);
1961 hashval += (hashval << 15);
1962
1963 /*
1964 * There is a remote chance (ideally, 1 in 2^31) that our hashval
1965 * comes out to be one of our two sentinel hash values. If this
1966 * actually happens, we set the hashval to be a value known to be a
1967 * non-sentinel value.
1968 */
1969 if (hashval == DTRACE_DYNHASH_FREE || hashval == DTRACE_DYNHASH_SINK)
1970 hashval = DTRACE_DYNHASH_VALID;
1971
1972 /*
1973 * Yes, it's painful to do a divide here. If the cycle count becomes
1974 * important here, tricks can be pulled to reduce it. (However, it's
1975 * critical that hash collisions be kept to an absolute minimum;
1976 * they're much more painful than a divide.) It's better to have a
1977 * solution that generates few collisions and still keeps things
1978 * relatively simple.
1979 */
1980 bucket = hashval % dstate->dtds_hashsize;
1981
1982 if (op == DTRACE_DYNVAR_DEALLOC) {
1983 volatile uintptr_t *lockp = &hash[bucket].dtdh_lock;
1984
1985 for (;;) {
1986 while ((lock = *lockp) & 1)
1987 continue;
1988
1989 if (dtrace_casptr((void *)(uintptr_t)lockp,
1990 (void *)lock, (void *)(lock + 1)) == (void *)lock)
1991 break;
1992 }
1993
1994 dtrace_membar_producer();
1995 }
1996
1997 top:
1998 prev = NULL;
1999 lock = hash[bucket].dtdh_lock;
2000
2001 dtrace_membar_consumer();
2002
2003 start = hash[bucket].dtdh_chain;
2004 ASSERT(start != NULL && (start->dtdv_hashval == DTRACE_DYNHASH_SINK ||
2005 start->dtdv_hashval != DTRACE_DYNHASH_FREE ||
2006 op != DTRACE_DYNVAR_DEALLOC));
2007
2008 for (dvar = start; dvar != NULL; dvar = dvar->dtdv_next) {
2009 dtrace_tuple_t *dtuple = &dvar->dtdv_tuple;
2010 dtrace_key_t *dkey = &dtuple->dtt_key[0];
2011
2012 if (dvar->dtdv_hashval != hashval) {
2013 if (dvar->dtdv_hashval == DTRACE_DYNHASH_SINK) {
2014 /*
2015 * We've reached the sink, and therefore the
2016 * end of the hash chain; we can kick out of
2017 * the loop knowing that we have seen a valid
2018 * snapshot of state.
2019 */
2020 ASSERT(dvar->dtdv_next == NULL);
2021 ASSERT(dvar == &dtrace_dynhash_sink);
2022 break;
2023 }
2024
2025 if (dvar->dtdv_hashval == DTRACE_DYNHASH_FREE) {
2026 /*
2027 * We've gone off the rails: somewhere along
2028 * the line, one of the members of this hash
2029 * chain was deleted. Note that we could also
2030 * detect this by simply letting this loop run
2031 * to completion, as we would eventually hit
2032 * the end of the dirty list. However, we
2033 * want to avoid running the length of the
2034 * dirty list unnecessarily (it might be quite
2035 * long), so we catch this as early as
2036 * possible by detecting the hash marker. In
2037 * this case, we simply set dvar to NULL and
2038 * break; the conditional after the loop will
2039 * send us back to top.
2040 */
2041 dvar = NULL;
2042 break;
2043 }
2044
2045 goto next;
2046 }
2047
2048 if (dtuple->dtt_nkeys != nkeys)
2049 goto next;
2050
2051 for (i = 0; i < nkeys; i++, dkey++) {
2052 if (dkey->dttk_size != key[i].dttk_size)
2053 goto next; /* size or type mismatch */
2054
2055 if (dkey->dttk_size != 0) {
2056 if (dtrace_bcmp(
2057 (void *)(uintptr_t)key[i].dttk_value,
2058 (void *)(uintptr_t)dkey->dttk_value,
2059 dkey->dttk_size))
2060 goto next;
2061 } else {
2062 if (dkey->dttk_value != key[i].dttk_value)
2063 goto next;
2064 }
2065 }
2066
2067 if (op != DTRACE_DYNVAR_DEALLOC)
2068 return (dvar);
2069
2070 ASSERT(dvar->dtdv_next == NULL ||
2071 dvar->dtdv_next->dtdv_hashval != DTRACE_DYNHASH_FREE);
2072
2073 if (prev != NULL) {
2074 ASSERT(hash[bucket].dtdh_chain != dvar);
2075 ASSERT(start != dvar);
2076 ASSERT(prev->dtdv_next == dvar);
2077 prev->dtdv_next = dvar->dtdv_next;
2078 } else {
2079 if (dtrace_casptr(&hash[bucket].dtdh_chain,
2080 start, dvar->dtdv_next) != start) {
2081 /*
2082 * We have failed to atomically swing the
2083 * hash table head pointer, presumably because
2084 * of a conflicting allocation on another CPU.
2085 * We need to reread the hash chain and try
2086 * again.
2087 */
2088 goto top;
2089 }
2090 }
2091
2092 dtrace_membar_producer();
2093
2094 /*
2095 * Now set the hash value to indicate that it's free.
2096 */
2097 ASSERT(hash[bucket].dtdh_chain != dvar);
2098 dvar->dtdv_hashval = DTRACE_DYNHASH_FREE;
2099
2100 dtrace_membar_producer();
2101
2102 /*
2103 * Set the next pointer to point at the dirty list, and
2104 * atomically swing the dirty pointer to the newly freed dvar.
2105 */
2106 do {
2107 next = dcpu->dtdsc_dirty;
2108 dvar->dtdv_next = next;
2109 } while (dtrace_casptr(&dcpu->dtdsc_dirty, next, dvar) != next);
2110
2111 /*
2112 * Finally, unlock this hash bucket.
2113 */
2114 ASSERT(hash[bucket].dtdh_lock == lock);
2115 ASSERT(lock & 1);
2116 hash[bucket].dtdh_lock++;
2117
2118 return (NULL);
2119 next:
2120 prev = dvar;
2121 continue;
2122 }
2123
2124 if (dvar == NULL) {
2125 /*
2126 * If dvar is NULL, it is because we went off the rails:
2127 * one of the elements that we traversed in the hash chain
2128 * was deleted while we were traversing it. In this case,
2129 * we assert that we aren't doing a dealloc (deallocs lock
2130 * the hash bucket to prevent themselves from racing with
2131 * one another), and retry the hash chain traversal.
2132 */
2133 ASSERT(op != DTRACE_DYNVAR_DEALLOC);
2134 goto top;
2135 }
2136
2137 if (op != DTRACE_DYNVAR_ALLOC) {
2138 /*
2139 * If we are not to allocate a new variable, we want to
2140 * return NULL now. Before we return, check that the value
2141 * of the lock word hasn't changed. If it has, we may have
2142 * seen an inconsistent snapshot.
2143 */
2144 if (op == DTRACE_DYNVAR_NOALLOC) {
2145 if (hash[bucket].dtdh_lock != lock)
2146 goto top;
2147 } else {
2148 ASSERT(op == DTRACE_DYNVAR_DEALLOC);
2149 ASSERT(hash[bucket].dtdh_lock == lock);
2150 ASSERT(lock & 1);
2151 hash[bucket].dtdh_lock++;
2152 }
2153
2154 return (NULL);
2155 }
2156
2157 /*
2158 * We need to allocate a new dynamic variable. The size we need is the
2159 * size of dtrace_dynvar plus the size of nkeys dtrace_key_t's plus the
2160 * size of any auxiliary key data (rounded up to 8-byte alignment) plus
2161 * the size of any referred-to data (dsize). We then round the final
2162 * size up to the chunksize for allocation.
2163 */
2164 for (ksize = 0, i = 0; i < nkeys; i++)
2165 ksize += P2ROUNDUP(key[i].dttk_size, sizeof (uint64_t));
2166
2167 /*
2168 * This should be pretty much impossible, but could happen if, say,
2169 * strange DIF specified the tuple. Ideally, this should be an
2170 * assertion and not an error condition -- but that requires that the
2171 * chunksize calculation in dtrace_difo_chunksize() be absolutely
2172 * bullet-proof. (That is, it must not be able to be fooled by
2173 * malicious DIF.) Given the lack of backwards branches in DIF,
2174 * solving this would presumably not amount to solving the Halting
2175 * Problem -- but it still seems awfully hard.
2176 */
2177 if (sizeof (dtrace_dynvar_t) + sizeof (dtrace_key_t) * (nkeys - 1) +
2178 ksize + dsize > chunksize) {
2179 dcpu->dtdsc_drops++;
2180 return (NULL);
2181 }
2182
2183 nstate = DTRACE_DSTATE_EMPTY;
2184
2185 do {
2186 retry:
2187 free = dcpu->dtdsc_free;
2188
2189 if (free == NULL) {
2190 dtrace_dynvar_t *clean = dcpu->dtdsc_clean;
2191 void *rval;
2192
2193 if (clean == NULL) {
2194 /*
2195 * We're out of dynamic variable space on
2196 * this CPU. Unless we have tried all CPUs,
2197 * we'll try to allocate from a different
2198 * CPU.
2199 */
2200 switch (dstate->dtds_state) {
2201 case DTRACE_DSTATE_CLEAN: {
2202 void *sp = &dstate->dtds_state;
2203
2204 if (++cpu >= (int)NCPU)
2205 cpu = 0;
2206
2207 if (dcpu->dtdsc_dirty != NULL &&
2208 nstate == DTRACE_DSTATE_EMPTY)
2209 nstate = DTRACE_DSTATE_DIRTY;
2210
2211 if (dcpu->dtdsc_rinsing != NULL)
2212 nstate = DTRACE_DSTATE_RINSING;
2213
2214 dcpu = &dstate->dtds_percpu[cpu];
2215
2216 if (cpu != me)
2217 goto retry;
2218
2219 (void) dtrace_cas32(sp,
2220 DTRACE_DSTATE_CLEAN, nstate);
2221
2222 /*
2223 * To increment the correct bean
2224 * counter, take another lap.
2225 */
2226 goto retry;
2227 }
2228
2229 case DTRACE_DSTATE_DIRTY:
2230 dcpu->dtdsc_dirty_drops++;
2231 break;
2232
2233 case DTRACE_DSTATE_RINSING:
2234 dcpu->dtdsc_rinsing_drops++;
2235 break;
2236
2237 case DTRACE_DSTATE_EMPTY:
2238 dcpu->dtdsc_drops++;
2239 break;
2240 }
2241
2242 DTRACE_CPUFLAG_SET(CPU_DTRACE_DROP);
2243 return (NULL);
2244 }
2245
2246 /*
2247 * The clean list appears to be non-empty. We want to
2248 * move the clean list to the free list; we start by
2249 * moving the clean pointer aside.
2250 */
2251 if (dtrace_casptr(&dcpu->dtdsc_clean,
2252 clean, NULL) != clean) {
2253 /*
2254 * We are in one of two situations:
2255 *
2256 * (a) The clean list was switched to the
2257 * free list by another CPU.
2258 *
2259 * (b) The clean list was added to by the
2260 * cleansing cyclic.
2261 *
2262 * In either of these situations, we can
2263 * just reattempt the free list allocation.
2264 */
2265 goto retry;
2266 }
2267
2268 ASSERT(clean->dtdv_hashval == DTRACE_DYNHASH_FREE);
2269
2270 /*
2271 * Now we'll move the clean list to the free list.
2272 * It's impossible for this to fail: the only way
2273 * the free list can be updated is through this
2274 * code path, and only one CPU can own the clean list.
2275 * Thus, it would only be possible for this to fail if
2276 * this code were racing with dtrace_dynvar_clean().
2277 * (That is, if dtrace_dynvar_clean() updated the clean
2278 * list, and we ended up racing to update the free
2279 * list.) This race is prevented by the dtrace_sync()
2280 * in dtrace_dynvar_clean() -- which flushes the
2281 * owners of the clean lists out before resetting
2282 * the clean lists.
2283 */
2284 rval = dtrace_casptr(&dcpu->dtdsc_free, NULL, clean);
2285 ASSERT(rval == NULL);
2286 goto retry;
2287 }
2288
2289 dvar = free;
2290 new_free = dvar->dtdv_next;
2291 } while (dtrace_casptr(&dcpu->dtdsc_free, free, new_free) != free);
2292
2293 /*
2294 * We have now allocated a new chunk. We copy the tuple keys into the
2295 * tuple array and copy any referenced key data into the data space
2296 * following the tuple array. As we do this, we relocate dttk_value
2297 * in the final tuple to point to the key data address in the chunk.
2298 */
2299 kdata = (uintptr_t)&dvar->dtdv_tuple.dtt_key[nkeys];
2300 dvar->dtdv_data = (void *)(kdata + ksize);
2301 dvar->dtdv_tuple.dtt_nkeys = nkeys;
2302
2303 for (i = 0; i < nkeys; i++) {
2304 dtrace_key_t *dkey = &dvar->dtdv_tuple.dtt_key[i];
2305 size_t kesize = key[i].dttk_size;
2306
2307 if (kesize != 0) {
2308 dtrace_bcopy(
2309 (const void *)(uintptr_t)key[i].dttk_value,
2310 (void *)kdata, kesize);
2311 dkey->dttk_value = kdata;
2312 kdata += P2ROUNDUP(kesize, sizeof (uint64_t));
2313 } else {
2314 dkey->dttk_value = key[i].dttk_value;
2315 }
2316
2317 dkey->dttk_size = kesize;
2318 }
2319
2320 ASSERT(dvar->dtdv_hashval == DTRACE_DYNHASH_FREE);
2321 dvar->dtdv_hashval = hashval;
2322 dvar->dtdv_next = start;
2323
2324 if (dtrace_casptr(&hash[bucket].dtdh_chain, start, dvar) == start)
2325 return (dvar);
2326
2327 /*
2328 * The cas has failed. Either another CPU is adding an element to
2329 * this hash chain, or another CPU is deleting an element from this
2330 * hash chain. The simplest way to deal with both of these cases
2331 * (though not necessarily the most efficient) is to free our
2332 * allocated block and tail-call ourselves. Note that the free is
2333 * to the dirty list and _not_ to the free list. This is to prevent
2334 * races with allocators, above.
2335 */
2336 dvar->dtdv_hashval = DTRACE_DYNHASH_FREE;
2337
2338 dtrace_membar_producer();
2339
2340 do {
2341 free = dcpu->dtdsc_dirty;
2342 dvar->dtdv_next = free;
2343 } while (dtrace_casptr(&dcpu->dtdsc_dirty, free, dvar) != free);
2344
2345 return (dtrace_dynvar(dstate, nkeys, key, dsize, op, mstate, vstate));
2346 }
2347
2348 /*ARGSUSED*/
2349 static void
dtrace_aggregate_min(uint64_t * oval,uint64_t nval,uint64_t arg)2350 dtrace_aggregate_min(uint64_t *oval, uint64_t nval, uint64_t arg)
2351 {
2352 #pragma unused(arg) /* __APPLE__ */
2353 if ((int64_t)nval < (int64_t)*oval)
2354 *oval = nval;
2355 }
2356
2357 /*ARGSUSED*/
2358 static void
dtrace_aggregate_max(uint64_t * oval,uint64_t nval,uint64_t arg)2359 dtrace_aggregate_max(uint64_t *oval, uint64_t nval, uint64_t arg)
2360 {
2361 #pragma unused(arg) /* __APPLE__ */
2362 if ((int64_t)nval > (int64_t)*oval)
2363 *oval = nval;
2364 }
2365
2366 static void
dtrace_aggregate_quantize(uint64_t * quanta,uint64_t nval,uint64_t incr)2367 dtrace_aggregate_quantize(uint64_t *quanta, uint64_t nval, uint64_t incr)
2368 {
2369 int i, zero = DTRACE_QUANTIZE_ZEROBUCKET;
2370 int64_t val = (int64_t)nval;
2371
2372 if (val < 0) {
2373 for (i = 0; i < zero; i++) {
2374 if (val <= DTRACE_QUANTIZE_BUCKETVAL(i)) {
2375 quanta[i] += incr;
2376 return;
2377 }
2378 }
2379 } else {
2380 for (i = zero + 1; i < DTRACE_QUANTIZE_NBUCKETS; i++) {
2381 if (val < DTRACE_QUANTIZE_BUCKETVAL(i)) {
2382 quanta[i - 1] += incr;
2383 return;
2384 }
2385 }
2386
2387 quanta[DTRACE_QUANTIZE_NBUCKETS - 1] += incr;
2388 return;
2389 }
2390
2391 ASSERT(0);
2392 }
2393
2394 static void
dtrace_aggregate_lquantize(uint64_t * lquanta,uint64_t nval,uint64_t incr)2395 dtrace_aggregate_lquantize(uint64_t *lquanta, uint64_t nval, uint64_t incr)
2396 {
2397 uint64_t arg = *lquanta++;
2398 int32_t base = DTRACE_LQUANTIZE_BASE(arg);
2399 uint16_t step = DTRACE_LQUANTIZE_STEP(arg);
2400 uint16_t levels = DTRACE_LQUANTIZE_LEVELS(arg);
2401 int32_t val = (int32_t)nval, level;
2402
2403 ASSERT(step != 0);
2404 ASSERT(levels != 0);
2405
2406 if (val < base) {
2407 /*
2408 * This is an underflow.
2409 */
2410 lquanta[0] += incr;
2411 return;
2412 }
2413
2414 level = (val - base) / step;
2415
2416 if (level < levels) {
2417 lquanta[level + 1] += incr;
2418 return;
2419 }
2420
2421 /*
2422 * This is an overflow.
2423 */
2424 lquanta[levels + 1] += incr;
2425 }
2426
2427 static int
dtrace_aggregate_llquantize_bucket(int16_t factor,int16_t low,int16_t high,int16_t nsteps,int64_t value)2428 dtrace_aggregate_llquantize_bucket(int16_t factor, int16_t low, int16_t high,
2429 int16_t nsteps, int64_t value)
2430 {
2431 int64_t this = 1, last, next;
2432 int base = 1, order;
2433
2434 for (order = 0; order < low; ++order)
2435 this *= factor;
2436
2437 /*
2438 * If our value is less than our factor taken to the power of the
2439 * low order of magnitude, it goes into the zeroth bucket.
2440 */
2441 if (value < this)
2442 return 0;
2443 else
2444 last = this;
2445
2446 for (this *= factor; order <= high; ++order) {
2447 int nbuckets = this > nsteps ? nsteps : this;
2448
2449 /*
2450 * We should not generally get log/linear quantizations
2451 * with a high magnitude that allows 64-bits to
2452 * overflow, but we nonetheless protect against this
2453 * by explicitly checking for overflow, and clamping
2454 * our value accordingly.
2455 */
2456 next = this * factor;
2457 if (next < this) {
2458 value = this - 1;
2459 }
2460
2461 /*
2462 * If our value lies within this order of magnitude,
2463 * determine its position by taking the offset within
2464 * the order of magnitude, dividing by the bucket
2465 * width, and adding to our (accumulated) base.
2466 */
2467 if (value < this) {
2468 return (base + (value - last) / (this / nbuckets));
2469 }
2470
2471 base += nbuckets - (nbuckets / factor);
2472 last = this;
2473 this = next;
2474 }
2475
2476 /*
2477 * Our value is greater than or equal to our factor taken to the
2478 * power of one plus the high magnitude -- return the top bucket.
2479 */
2480 return base;
2481 }
2482
2483 static void
dtrace_aggregate_llquantize(uint64_t * llquanta,uint64_t nval,uint64_t incr)2484 dtrace_aggregate_llquantize(uint64_t *llquanta, uint64_t nval, uint64_t incr)
2485 {
2486 uint64_t arg = *llquanta++;
2487 uint16_t factor = DTRACE_LLQUANTIZE_FACTOR(arg);
2488 uint16_t low = DTRACE_LLQUANTIZE_LOW(arg);
2489 uint16_t high = DTRACE_LLQUANTIZE_HIGH(arg);
2490 uint16_t nsteps = DTRACE_LLQUANTIZE_NSTEP(arg);
2491
2492 llquanta[dtrace_aggregate_llquantize_bucket(factor, low, high, nsteps, nval)] += incr;
2493 }
2494
2495 /*ARGSUSED*/
2496 static void
dtrace_aggregate_avg(uint64_t * data,uint64_t nval,uint64_t arg)2497 dtrace_aggregate_avg(uint64_t *data, uint64_t nval, uint64_t arg)
2498 {
2499 #pragma unused(arg) /* __APPLE__ */
2500 data[0]++;
2501 data[1] += nval;
2502 }
2503
2504 /*ARGSUSED*/
2505 static void
dtrace_aggregate_stddev(uint64_t * data,uint64_t nval,uint64_t arg)2506 dtrace_aggregate_stddev(uint64_t *data, uint64_t nval, uint64_t arg)
2507 {
2508 #pragma unused(arg) /* __APPLE__ */
2509 int64_t snval = (int64_t)nval;
2510 uint64_t tmp[2];
2511
2512 data[0]++;
2513 data[1] += nval;
2514
2515 /*
2516 * What we want to say here is:
2517 *
2518 * data[2] += nval * nval;
2519 *
2520 * But given that nval is 64-bit, we could easily overflow, so
2521 * we do this as 128-bit arithmetic.
2522 */
2523 if (snval < 0)
2524 snval = -snval;
2525
2526 dtrace_multiply_128((uint64_t)snval, (uint64_t)snval, tmp);
2527 dtrace_add_128(data + 2, tmp, data + 2);
2528 }
2529
2530 /*ARGSUSED*/
2531 static void
dtrace_aggregate_count(uint64_t * oval,uint64_t nval,uint64_t arg)2532 dtrace_aggregate_count(uint64_t *oval, uint64_t nval, uint64_t arg)
2533 {
2534 #pragma unused(nval, arg) /* __APPLE__ */
2535 *oval = *oval + 1;
2536 }
2537
2538 /*ARGSUSED*/
2539 static void
dtrace_aggregate_sum(uint64_t * oval,uint64_t nval,uint64_t arg)2540 dtrace_aggregate_sum(uint64_t *oval, uint64_t nval, uint64_t arg)
2541 {
2542 #pragma unused(arg) /* __APPLE__ */
2543 *oval += nval;
2544 }
2545
2546 /*
2547 * Aggregate given the tuple in the principal data buffer, and the aggregating
2548 * action denoted by the specified dtrace_aggregation_t. The aggregation
2549 * buffer is specified as the buf parameter. This routine does not return
2550 * failure; if there is no space in the aggregation buffer, the data will be
2551 * dropped, and a corresponding counter incremented.
2552 */
2553 __attribute__((noinline))
2554 static void
dtrace_aggregate(dtrace_aggregation_t * agg,dtrace_buffer_t * dbuf,intptr_t offset,dtrace_buffer_t * buf,uint64_t expr,uint64_t arg)2555 dtrace_aggregate(dtrace_aggregation_t *agg, dtrace_buffer_t *dbuf,
2556 intptr_t offset, dtrace_buffer_t *buf, uint64_t expr, uint64_t arg)
2557 {
2558 #pragma unused(arg)
2559 dtrace_recdesc_t *rec = &agg->dtag_action.dta_rec;
2560 uint32_t i, ndx, size, fsize;
2561 uint32_t align = sizeof (uint64_t) - 1;
2562 dtrace_aggbuffer_t *agb;
2563 dtrace_aggkey_t *key;
2564 uint32_t hashval = 0, limit, isstr;
2565 caddr_t tomax, data, kdata;
2566 dtrace_actkind_t action;
2567 dtrace_action_t *act;
2568 uintptr_t offs;
2569
2570 if (buf == NULL)
2571 return;
2572
2573 if (!agg->dtag_hasarg) {
2574 /*
2575 * Currently, only quantize() and lquantize() take additional
2576 * arguments, and they have the same semantics: an increment
2577 * value that defaults to 1 when not present. If additional
2578 * aggregating actions take arguments, the setting of the
2579 * default argument value will presumably have to become more
2580 * sophisticated...
2581 */
2582 arg = 1;
2583 }
2584
2585 action = agg->dtag_action.dta_kind - DTRACEACT_AGGREGATION;
2586 size = rec->dtrd_offset - agg->dtag_base;
2587 fsize = size + rec->dtrd_size;
2588
2589 ASSERT(dbuf->dtb_tomax != NULL);
2590 data = dbuf->dtb_tomax + offset + agg->dtag_base;
2591
2592 if ((tomax = buf->dtb_tomax) == NULL) {
2593 dtrace_buffer_drop(buf);
2594 return;
2595 }
2596
2597 /*
2598 * The metastructure is always at the bottom of the buffer.
2599 */
2600 agb = (dtrace_aggbuffer_t *)(tomax + buf->dtb_size -
2601 sizeof (dtrace_aggbuffer_t));
2602
2603 if (buf->dtb_offset == 0) {
2604 /*
2605 * We just kludge up approximately 1/8th of the size to be
2606 * buckets. If this guess ends up being routinely
2607 * off-the-mark, we may need to dynamically readjust this
2608 * based on past performance.
2609 */
2610 uintptr_t hashsize = (buf->dtb_size >> 3) / sizeof (uintptr_t);
2611
2612 if ((uintptr_t)agb - hashsize * sizeof (dtrace_aggkey_t *) <
2613 (uintptr_t)tomax || hashsize == 0) {
2614 /*
2615 * We've been given a ludicrously small buffer;
2616 * increment our drop count and leave.
2617 */
2618 dtrace_buffer_drop(buf);
2619 return;
2620 }
2621
2622 /*
2623 * And now, a pathetic attempt to try to get a an odd (or
2624 * perchance, a prime) hash size for better hash distribution.
2625 */
2626 if (hashsize > (DTRACE_AGGHASHSIZE_SLEW << 3))
2627 hashsize -= DTRACE_AGGHASHSIZE_SLEW;
2628
2629 agb->dtagb_hashsize = hashsize;
2630 agb->dtagb_hash = (dtrace_aggkey_t **)((uintptr_t)agb -
2631 agb->dtagb_hashsize * sizeof (dtrace_aggkey_t *));
2632 agb->dtagb_free = (uintptr_t)agb->dtagb_hash;
2633
2634 for (i = 0; i < agb->dtagb_hashsize; i++)
2635 agb->dtagb_hash[i] = NULL;
2636 }
2637
2638 ASSERT(agg->dtag_first != NULL);
2639 ASSERT(agg->dtag_first->dta_intuple);
2640
2641 /*
2642 * Calculate the hash value based on the key. Note that we _don't_
2643 * include the aggid in the hashing (but we will store it as part of
2644 * the key). The hashing algorithm is Bob Jenkins' "One-at-a-time"
2645 * algorithm: a simple, quick algorithm that has no known funnels, and
2646 * gets good distribution in practice. The efficacy of the hashing
2647 * algorithm (and a comparison with other algorithms) may be found by
2648 * running the ::dtrace_aggstat MDB dcmd.
2649 */
2650 for (act = agg->dtag_first; act->dta_intuple; act = act->dta_next) {
2651 i = act->dta_rec.dtrd_offset - agg->dtag_base;
2652 limit = i + act->dta_rec.dtrd_size;
2653 ASSERT(limit <= size);
2654 isstr = DTRACEACT_ISSTRING(act);
2655
2656 for (; i < limit; i++) {
2657 hashval += data[i];
2658 hashval += (hashval << 10);
2659 hashval ^= (hashval >> 6);
2660
2661 if (isstr && data[i] == '\0')
2662 break;
2663 }
2664 }
2665
2666 hashval += (hashval << 3);
2667 hashval ^= (hashval >> 11);
2668 hashval += (hashval << 15);
2669
2670 /*
2671 * Yes, the divide here is expensive -- but it's generally the least
2672 * of the performance issues given the amount of data that we iterate
2673 * over to compute hash values, compare data, etc.
2674 */
2675 ndx = hashval % agb->dtagb_hashsize;
2676
2677 for (key = agb->dtagb_hash[ndx]; key != NULL; key = key->dtak_next) {
2678 ASSERT((caddr_t)key >= tomax);
2679 ASSERT((caddr_t)key < tomax + buf->dtb_size);
2680
2681 if (hashval != key->dtak_hashval || key->dtak_size != size)
2682 continue;
2683
2684 kdata = key->dtak_data;
2685 ASSERT(kdata >= tomax && kdata < tomax + buf->dtb_size);
2686
2687 for (act = agg->dtag_first; act->dta_intuple;
2688 act = act->dta_next) {
2689 i = act->dta_rec.dtrd_offset - agg->dtag_base;
2690 limit = i + act->dta_rec.dtrd_size;
2691 ASSERT(limit <= size);
2692 isstr = DTRACEACT_ISSTRING(act);
2693
2694 for (; i < limit; i++) {
2695 if (kdata[i] != data[i])
2696 goto next;
2697
2698 if (isstr && data[i] == '\0')
2699 break;
2700 }
2701 }
2702
2703 if (action != key->dtak_action) {
2704 /*
2705 * We are aggregating on the same value in the same
2706 * aggregation with two different aggregating actions.
2707 * (This should have been picked up in the compiler,
2708 * so we may be dealing with errant or devious DIF.)
2709 * This is an error condition; we indicate as much,
2710 * and return.
2711 */
2712 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
2713 return;
2714 }
2715
2716 /*
2717 * This is a hit: we need to apply the aggregator to
2718 * the value at this key.
2719 */
2720 agg->dtag_aggregate((uint64_t *)(kdata + size), expr, arg);
2721 return;
2722 next:
2723 continue;
2724 }
2725
2726 /*
2727 * We didn't find it. We need to allocate some zero-filled space,
2728 * link it into the hash table appropriately, and apply the aggregator
2729 * to the (zero-filled) value.
2730 */
2731 offs = buf->dtb_offset;
2732 while (offs & (align - 1))
2733 offs += sizeof (uint32_t);
2734
2735 /*
2736 * If we don't have enough room to both allocate a new key _and_
2737 * its associated data, increment the drop count and return.
2738 */
2739 if ((uintptr_t)tomax + offs + fsize >
2740 agb->dtagb_free - sizeof (dtrace_aggkey_t)) {
2741 dtrace_buffer_drop(buf);
2742 return;
2743 }
2744
2745 /*CONSTCOND*/
2746 ASSERT(!(sizeof (dtrace_aggkey_t) & (sizeof (uintptr_t) - 1)));
2747 key = (dtrace_aggkey_t *)(agb->dtagb_free - sizeof (dtrace_aggkey_t));
2748 agb->dtagb_free -= sizeof (dtrace_aggkey_t);
2749
2750 key->dtak_data = kdata = tomax + offs;
2751 buf->dtb_offset = offs + fsize;
2752
2753 /*
2754 * Now copy the data across.
2755 */
2756 *((dtrace_aggid_t *)kdata) = agg->dtag_id;
2757
2758 for (i = sizeof (dtrace_aggid_t); i < size; i++)
2759 kdata[i] = data[i];
2760
2761 /*
2762 * Because strings are not zeroed out by default, we need to iterate
2763 * looking for actions that store strings, and we need to explicitly
2764 * pad these strings out with zeroes.
2765 */
2766 for (act = agg->dtag_first; act->dta_intuple; act = act->dta_next) {
2767 int nul;
2768
2769 if (!DTRACEACT_ISSTRING(act))
2770 continue;
2771
2772 i = act->dta_rec.dtrd_offset - agg->dtag_base;
2773 limit = i + act->dta_rec.dtrd_size;
2774 ASSERT(limit <= size);
2775
2776 for (nul = 0; i < limit; i++) {
2777 if (nul) {
2778 kdata[i] = '\0';
2779 continue;
2780 }
2781
2782 if (data[i] != '\0')
2783 continue;
2784
2785 nul = 1;
2786 }
2787 }
2788
2789 for (i = size; i < fsize; i++)
2790 kdata[i] = 0;
2791
2792 key->dtak_hashval = hashval;
2793 key->dtak_size = size;
2794 key->dtak_action = action;
2795 key->dtak_next = agb->dtagb_hash[ndx];
2796 agb->dtagb_hash[ndx] = key;
2797
2798 /*
2799 * Finally, apply the aggregator.
2800 */
2801 *((uint64_t *)(key->dtak_data + size)) = agg->dtag_initial;
2802 agg->dtag_aggregate((uint64_t *)(key->dtak_data + size), expr, arg);
2803 }
2804
2805 /*
2806 * Given consumer state, this routine finds a speculation in the INACTIVE
2807 * state and transitions it into the ACTIVE state. If there is no speculation
2808 * in the INACTIVE state, 0 is returned. In this case, no error counter is
2809 * incremented -- it is up to the caller to take appropriate action.
2810 */
2811 static int
dtrace_speculation(dtrace_state_t * state)2812 dtrace_speculation(dtrace_state_t *state)
2813 {
2814 int i = 0;
2815 dtrace_speculation_state_t current;
2816 uint32_t *stat = &state->dts_speculations_unavail, count;
2817
2818 while (i < state->dts_nspeculations) {
2819 dtrace_speculation_t *spec = &state->dts_speculations[i];
2820
2821 current = spec->dtsp_state;
2822
2823 if (current != DTRACESPEC_INACTIVE) {
2824 if (current == DTRACESPEC_COMMITTINGMANY ||
2825 current == DTRACESPEC_COMMITTING ||
2826 current == DTRACESPEC_DISCARDING)
2827 stat = &state->dts_speculations_busy;
2828 i++;
2829 continue;
2830 }
2831
2832 if (dtrace_cas32((uint32_t *)&spec->dtsp_state,
2833 current, DTRACESPEC_ACTIVE) == current)
2834 return (i + 1);
2835 }
2836
2837 /*
2838 * We couldn't find a speculation. If we found as much as a single
2839 * busy speculation buffer, we'll attribute this failure as "busy"
2840 * instead of "unavail".
2841 */
2842 do {
2843 count = *stat;
2844 } while (dtrace_cas32(stat, count, count + 1) != count);
2845
2846 return (0);
2847 }
2848
2849 /*
2850 * This routine commits an active speculation. If the specified speculation
2851 * is not in a valid state to perform a commit(), this routine will silently do
2852 * nothing. The state of the specified speculation is transitioned according
2853 * to the state transition diagram outlined in <sys/dtrace_impl.h>
2854 */
2855 static void
dtrace_speculation_commit(dtrace_state_t * state,processorid_t cpu,dtrace_specid_t which)2856 dtrace_speculation_commit(dtrace_state_t *state, processorid_t cpu,
2857 dtrace_specid_t which)
2858 {
2859 dtrace_speculation_t *spec;
2860 dtrace_buffer_t *src, *dest;
2861 uintptr_t daddr, saddr, dlimit, slimit;
2862 dtrace_speculation_state_t current, new = DTRACESPEC_INACTIVE;
2863 intptr_t offs;
2864 uint64_t timestamp;
2865
2866 if (which == 0)
2867 return;
2868
2869 if (which > (dtrace_specid_t)state->dts_nspeculations) {
2870 cpu_core[cpu].cpuc_dtrace_flags |= CPU_DTRACE_ILLOP;
2871 return;
2872 }
2873
2874 spec = &state->dts_speculations[which - 1];
2875 src = &spec->dtsp_buffer[cpu];
2876 dest = &state->dts_buffer[cpu];
2877
2878 do {
2879 current = spec->dtsp_state;
2880
2881 if (current == DTRACESPEC_COMMITTINGMANY)
2882 break;
2883
2884 switch (current) {
2885 case DTRACESPEC_INACTIVE:
2886 case DTRACESPEC_DISCARDING:
2887 return;
2888
2889 case DTRACESPEC_COMMITTING:
2890 /*
2891 * This is only possible if we are (a) commit()'ing
2892 * without having done a prior speculate() on this CPU
2893 * and (b) racing with another commit() on a different
2894 * CPU. There's nothing to do -- we just assert that
2895 * our offset is 0.
2896 */
2897 ASSERT(src->dtb_offset == 0);
2898 return;
2899
2900 case DTRACESPEC_ACTIVE:
2901 new = DTRACESPEC_COMMITTING;
2902 break;
2903
2904 case DTRACESPEC_ACTIVEONE:
2905 /*
2906 * This speculation is active on one CPU. If our
2907 * buffer offset is non-zero, we know that the one CPU
2908 * must be us. Otherwise, we are committing on a
2909 * different CPU from the speculate(), and we must
2910 * rely on being asynchronously cleaned.
2911 */
2912 if (src->dtb_offset != 0) {
2913 new = DTRACESPEC_COMMITTING;
2914 break;
2915 }
2916 OS_FALLTHROUGH;
2917
2918 case DTRACESPEC_ACTIVEMANY:
2919 new = DTRACESPEC_COMMITTINGMANY;
2920 break;
2921
2922 default:
2923 ASSERT(0);
2924 }
2925 } while (dtrace_cas32((uint32_t *)&spec->dtsp_state,
2926 current, new) != current);
2927
2928 /*
2929 * We have set the state to indicate that we are committing this
2930 * speculation. Now reserve the necessary space in the destination
2931 * buffer.
2932 */
2933 if ((offs = dtrace_buffer_reserve(dest, src->dtb_offset,
2934 sizeof (uint64_t), state, NULL)) < 0) {
2935 dtrace_buffer_drop(dest);
2936 goto out;
2937 }
2938
2939 /*
2940 * We have sufficient space to copy the speculative buffer into the
2941 * primary buffer. First, modify the speculative buffer, filling
2942 * in the timestamp of all entries with the current time. The data
2943 * must have the commit() time rather than the time it was traced,
2944 * so that all entries in the primary buffer are in timestamp order.
2945 */
2946 timestamp = dtrace_gethrtime();
2947 saddr = (uintptr_t)src->dtb_tomax;
2948 slimit = saddr + src->dtb_offset;
2949 while (saddr < slimit) {
2950 size_t size;
2951 dtrace_rechdr_t *dtrh = (dtrace_rechdr_t *)saddr;
2952
2953 if (dtrh->dtrh_epid == DTRACE_EPIDNONE) {
2954 saddr += sizeof (dtrace_epid_t);
2955 continue;
2956 }
2957
2958 ASSERT(dtrh->dtrh_epid <= ((dtrace_epid_t) state->dts_necbs));
2959 size = state->dts_ecbs[dtrh->dtrh_epid - 1]->dte_size;
2960
2961 ASSERT(saddr + size <= slimit);
2962 ASSERT(size >= sizeof(dtrace_rechdr_t));
2963 ASSERT(DTRACE_RECORD_LOAD_TIMESTAMP(dtrh) == UINT64_MAX);
2964
2965 DTRACE_RECORD_STORE_TIMESTAMP(dtrh, timestamp);
2966
2967 saddr += size;
2968 }
2969
2970 /*
2971 * Copy the buffer across. (Note that this is a
2972 * highly subobtimal bcopy(); in the unlikely event that this becomes
2973 * a serious performance issue, a high-performance DTrace-specific
2974 * bcopy() should obviously be invented.)
2975 */
2976 daddr = (uintptr_t)dest->dtb_tomax + offs;
2977 dlimit = daddr + src->dtb_offset;
2978 saddr = (uintptr_t)src->dtb_tomax;
2979
2980 /*
2981 * First, the aligned portion.
2982 */
2983 while (dlimit - daddr >= sizeof (uint64_t)) {
2984 *((uint64_t *)daddr) = *((uint64_t *)saddr);
2985
2986 daddr += sizeof (uint64_t);
2987 saddr += sizeof (uint64_t);
2988 }
2989
2990 /*
2991 * Now any left-over bit...
2992 */
2993 while (dlimit - daddr)
2994 *((uint8_t *)daddr++) = *((uint8_t *)saddr++);
2995
2996 /*
2997 * Finally, commit the reserved space in the destination buffer.
2998 */
2999 dest->dtb_offset = offs + src->dtb_offset;
3000
3001 out:
3002 /*
3003 * If we're lucky enough to be the only active CPU on this speculation
3004 * buffer, we can just set the state back to DTRACESPEC_INACTIVE.
3005 */
3006 if (current == DTRACESPEC_ACTIVE ||
3007 (current == DTRACESPEC_ACTIVEONE && new == DTRACESPEC_COMMITTING)) {
3008 uint32_t rval = dtrace_cas32((uint32_t *)&spec->dtsp_state,
3009 DTRACESPEC_COMMITTING, DTRACESPEC_INACTIVE);
3010 #pragma unused(rval) /* __APPLE__ */
3011
3012 ASSERT(rval == DTRACESPEC_COMMITTING);
3013 }
3014
3015 src->dtb_offset = 0;
3016 src->dtb_xamot_drops += src->dtb_drops;
3017 src->dtb_drops = 0;
3018 }
3019
3020 /*
3021 * This routine discards an active speculation. If the specified speculation
3022 * is not in a valid state to perform a discard(), this routine will silently
3023 * do nothing. The state of the specified speculation is transitioned
3024 * according to the state transition diagram outlined in <sys/dtrace_impl.h>
3025 */
3026 __attribute__((noinline))
3027 static void
dtrace_speculation_discard(dtrace_state_t * state,processorid_t cpu,dtrace_specid_t which)3028 dtrace_speculation_discard(dtrace_state_t *state, processorid_t cpu,
3029 dtrace_specid_t which)
3030 {
3031 dtrace_speculation_t *spec;
3032 dtrace_speculation_state_t current, new = DTRACESPEC_INACTIVE;
3033 dtrace_buffer_t *buf;
3034
3035 if (which == 0)
3036 return;
3037
3038 if (which > (dtrace_specid_t)state->dts_nspeculations) {
3039 cpu_core[cpu].cpuc_dtrace_flags |= CPU_DTRACE_ILLOP;
3040 return;
3041 }
3042
3043 spec = &state->dts_speculations[which - 1];
3044 buf = &spec->dtsp_buffer[cpu];
3045
3046 do {
3047 current = spec->dtsp_state;
3048
3049 switch (current) {
3050 case DTRACESPEC_INACTIVE:
3051 case DTRACESPEC_COMMITTINGMANY:
3052 case DTRACESPEC_COMMITTING:
3053 case DTRACESPEC_DISCARDING:
3054 return;
3055
3056 case DTRACESPEC_ACTIVE:
3057 case DTRACESPEC_ACTIVEMANY:
3058 new = DTRACESPEC_DISCARDING;
3059 break;
3060
3061 case DTRACESPEC_ACTIVEONE:
3062 if (buf->dtb_offset != 0) {
3063 new = DTRACESPEC_INACTIVE;
3064 } else {
3065 new = DTRACESPEC_DISCARDING;
3066 }
3067 break;
3068
3069 default:
3070 ASSERT(0);
3071 }
3072 } while (dtrace_cas32((uint32_t *)&spec->dtsp_state,
3073 current, new) != current);
3074
3075 buf->dtb_offset = 0;
3076 buf->dtb_drops = 0;
3077 }
3078
3079 /*
3080 * Note: not called from probe context. This function is called
3081 * asynchronously from cross call context to clean any speculations that are
3082 * in the COMMITTINGMANY or DISCARDING states. These speculations may not be
3083 * transitioned back to the INACTIVE state until all CPUs have cleaned the
3084 * speculation.
3085 */
3086 static void
dtrace_speculation_clean_here(dtrace_state_t * state)3087 dtrace_speculation_clean_here(dtrace_state_t *state)
3088 {
3089 dtrace_icookie_t cookie;
3090 processorid_t cpu = CPU->cpu_id;
3091 dtrace_buffer_t *dest = &state->dts_buffer[cpu];
3092 dtrace_specid_t i;
3093
3094 cookie = dtrace_interrupt_disable();
3095
3096 if (dest->dtb_tomax == NULL) {
3097 dtrace_interrupt_enable(cookie);
3098 return;
3099 }
3100
3101 for (i = 0; i < (dtrace_specid_t)state->dts_nspeculations; i++) {
3102 dtrace_speculation_t *spec = &state->dts_speculations[i];
3103 dtrace_buffer_t *src = &spec->dtsp_buffer[cpu];
3104
3105 if (src->dtb_tomax == NULL)
3106 continue;
3107
3108 if (spec->dtsp_state == DTRACESPEC_DISCARDING) {
3109 src->dtb_offset = 0;
3110 continue;
3111 }
3112
3113 if (spec->dtsp_state != DTRACESPEC_COMMITTINGMANY)
3114 continue;
3115
3116 if (src->dtb_offset == 0)
3117 continue;
3118
3119 dtrace_speculation_commit(state, cpu, i + 1);
3120 }
3121
3122 dtrace_interrupt_enable(cookie);
3123 }
3124
3125 /*
3126 * Note: not called from probe context. This function is called
3127 * asynchronously (and at a regular interval) to clean any speculations that
3128 * are in the COMMITTINGMANY or DISCARDING states. If it discovers that there
3129 * is work to be done, it cross calls all CPUs to perform that work;
3130 * COMMITMANY and DISCARDING speculations may not be transitioned back to the
3131 * INACTIVE state until they have been cleaned by all CPUs.
3132 */
3133 static void
dtrace_speculation_clean(dtrace_state_t * state)3134 dtrace_speculation_clean(dtrace_state_t *state)
3135 {
3136 int work = 0;
3137 uint32_t rv;
3138 dtrace_specid_t i;
3139
3140 for (i = 0; i < (dtrace_specid_t)state->dts_nspeculations; i++) {
3141 dtrace_speculation_t *spec = &state->dts_speculations[i];
3142
3143 ASSERT(!spec->dtsp_cleaning);
3144
3145 if (spec->dtsp_state != DTRACESPEC_DISCARDING &&
3146 spec->dtsp_state != DTRACESPEC_COMMITTINGMANY)
3147 continue;
3148
3149 work++;
3150 spec->dtsp_cleaning = 1;
3151 }
3152
3153 if (!work)
3154 return;
3155
3156 dtrace_xcall(DTRACE_CPUALL,
3157 (dtrace_xcall_t)dtrace_speculation_clean_here, state);
3158
3159 /*
3160 * We now know that all CPUs have committed or discarded their
3161 * speculation buffers, as appropriate. We can now set the state
3162 * to inactive.
3163 */
3164 for (i = 0; i < (dtrace_specid_t)state->dts_nspeculations; i++) {
3165 dtrace_speculation_t *spec = &state->dts_speculations[i];
3166 dtrace_speculation_state_t current, new;
3167
3168 if (!spec->dtsp_cleaning)
3169 continue;
3170
3171 current = spec->dtsp_state;
3172 ASSERT(current == DTRACESPEC_DISCARDING ||
3173 current == DTRACESPEC_COMMITTINGMANY);
3174
3175 new = DTRACESPEC_INACTIVE;
3176
3177 rv = dtrace_cas32((uint32_t *)&spec->dtsp_state, current, new);
3178 ASSERT(rv == current);
3179 spec->dtsp_cleaning = 0;
3180 }
3181 }
3182
3183 /*
3184 * Called as part of a speculate() to get the speculative buffer associated
3185 * with a given speculation. Returns NULL if the specified speculation is not
3186 * in an ACTIVE state. If the speculation is in the ACTIVEONE state -- and
3187 * the active CPU is not the specified CPU -- the speculation will be
3188 * atomically transitioned into the ACTIVEMANY state.
3189 */
3190 __attribute__((noinline))
3191 static dtrace_buffer_t *
dtrace_speculation_buffer(dtrace_state_t * state,processorid_t cpuid,dtrace_specid_t which)3192 dtrace_speculation_buffer(dtrace_state_t *state, processorid_t cpuid,
3193 dtrace_specid_t which)
3194 {
3195 dtrace_speculation_t *spec;
3196 dtrace_speculation_state_t current, new = DTRACESPEC_INACTIVE;
3197 dtrace_buffer_t *buf;
3198
3199 if (which == 0)
3200 return (NULL);
3201
3202 if (which > (dtrace_specid_t)state->dts_nspeculations) {
3203 cpu_core[cpuid].cpuc_dtrace_flags |= CPU_DTRACE_ILLOP;
3204 return (NULL);
3205 }
3206
3207 spec = &state->dts_speculations[which - 1];
3208 buf = &spec->dtsp_buffer[cpuid];
3209
3210 do {
3211 current = spec->dtsp_state;
3212
3213 switch (current) {
3214 case DTRACESPEC_INACTIVE:
3215 case DTRACESPEC_COMMITTINGMANY:
3216 case DTRACESPEC_DISCARDING:
3217 return (NULL);
3218
3219 case DTRACESPEC_COMMITTING:
3220 ASSERT(buf->dtb_offset == 0);
3221 return (NULL);
3222
3223 case DTRACESPEC_ACTIVEONE:
3224 /*
3225 * This speculation is currently active on one CPU.
3226 * Check the offset in the buffer; if it's non-zero,
3227 * that CPU must be us (and we leave the state alone).
3228 * If it's zero, assume that we're starting on a new
3229 * CPU -- and change the state to indicate that the
3230 * speculation is active on more than one CPU.
3231 */
3232 if (buf->dtb_offset != 0)
3233 return (buf);
3234
3235 new = DTRACESPEC_ACTIVEMANY;
3236 break;
3237
3238 case DTRACESPEC_ACTIVEMANY:
3239 return (buf);
3240
3241 case DTRACESPEC_ACTIVE:
3242 new = DTRACESPEC_ACTIVEONE;
3243 break;
3244
3245 default:
3246 ASSERT(0);
3247 }
3248 } while (dtrace_cas32((uint32_t *)&spec->dtsp_state,
3249 current, new) != current);
3250
3251 ASSERT(new == DTRACESPEC_ACTIVEONE || new == DTRACESPEC_ACTIVEMANY);
3252 return (buf);
3253 }
3254
3255 /*
3256 * Return a string. In the event that the user lacks the privilege to access
3257 * arbitrary kernel memory, we copy the string out to scratch memory so that we
3258 * don't fail access checking.
3259 *
3260 * dtrace_dif_variable() uses this routine as a helper for various
3261 * builtin values such as 'execname' and 'probefunc.'
3262 */
3263 static
3264 uintptr_t
dtrace_dif_varstr(uintptr_t addr,dtrace_state_t * state,dtrace_mstate_t * mstate)3265 dtrace_dif_varstr(uintptr_t addr, dtrace_state_t *state,
3266 dtrace_mstate_t *mstate)
3267 {
3268 uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
3269 uintptr_t ret;
3270 size_t strsz;
3271
3272 /*
3273 * The easy case: this probe is allowed to read all of memory, so
3274 * we can just return this as a vanilla pointer.
3275 */
3276 if ((mstate->dtms_access & DTRACE_ACCESS_KERNEL) != 0)
3277 return (addr);
3278
3279 /*
3280 * This is the tougher case: we copy the string in question from
3281 * kernel memory into scratch memory and return it that way: this
3282 * ensures that we won't trip up when access checking tests the
3283 * BYREF return value.
3284 */
3285 strsz = dtrace_strlen((char *)addr, size) + 1;
3286
3287 if (mstate->dtms_scratch_ptr + strsz >
3288 mstate->dtms_scratch_base + mstate->dtms_scratch_size) {
3289 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
3290 return (0);
3291 }
3292
3293 dtrace_strcpy((const void *)addr, (void *)mstate->dtms_scratch_ptr,
3294 strsz);
3295 ret = mstate->dtms_scratch_ptr;
3296 mstate->dtms_scratch_ptr += strsz;
3297 return (ret);
3298 }
3299
3300 /*
3301 * This function implements the DIF emulator's variable lookups. The emulator
3302 * passes a reserved variable identifier and optional built-in array index.
3303 */
3304 static uint64_t
dtrace_dif_variable(dtrace_mstate_t * mstate,dtrace_state_t * state,uint64_t v,uint64_t ndx)3305 dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v,
3306 uint64_t ndx)
3307 {
3308 /*
3309 * If we're accessing one of the uncached arguments, we'll turn this
3310 * into a reference in the args array.
3311 */
3312 if (v >= DIF_VAR_ARG0 && v <= DIF_VAR_ARG9) {
3313 ndx = v - DIF_VAR_ARG0;
3314 v = DIF_VAR_ARGS;
3315 }
3316
3317 switch (v) {
3318 case DIF_VAR_ARGS:
3319 ASSERT(mstate->dtms_present & DTRACE_MSTATE_ARGS);
3320 if (ndx >= sizeof (mstate->dtms_arg) /
3321 sizeof (mstate->dtms_arg[0])) {
3322 int aframes = mstate->dtms_probe->dtpr_aframes + 2;
3323 dtrace_vstate_t *vstate = &state->dts_vstate;
3324 dtrace_provider_t *pv;
3325 uint64_t val;
3326
3327 pv = mstate->dtms_probe->dtpr_provider;
3328 if (pv->dtpv_pops.dtps_getargval != NULL)
3329 val = pv->dtpv_pops.dtps_getargval(pv->dtpv_arg,
3330 mstate->dtms_probe->dtpr_id,
3331 mstate->dtms_probe->dtpr_arg, ndx, aframes);
3332 /* Special case access of arg5 as passed to dtrace_probe_error() (which see.) */
3333 else if (mstate->dtms_probe->dtpr_id == dtrace_probeid_error && ndx == 5) {
3334 return ((dtrace_state_t *)(uintptr_t)(mstate->dtms_arg[0]))->dts_arg_error_illval;
3335 }
3336
3337 else
3338 val = dtrace_getarg(ndx, aframes, mstate, vstate);
3339
3340 /*
3341 * This is regrettably required to keep the compiler
3342 * from tail-optimizing the call to dtrace_getarg().
3343 * The condition always evaluates to true, but the
3344 * compiler has no way of figuring that out a priori.
3345 * (None of this would be necessary if the compiler
3346 * could be relied upon to _always_ tail-optimize
3347 * the call to dtrace_getarg() -- but it can't.)
3348 */
3349 if (mstate->dtms_probe != NULL)
3350 return (val);
3351
3352 ASSERT(0);
3353 }
3354
3355 return (mstate->dtms_arg[ndx]);
3356
3357 case DIF_VAR_UREGS: {
3358 thread_t thread;
3359
3360 if (!dtrace_priv_proc(state))
3361 return (0);
3362
3363 if ((thread = current_thread()) == NULL) {
3364 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
3365 cpu_core[CPU->cpu_id].cpuc_dtrace_illval = 0;
3366 return (0);
3367 }
3368
3369 return (dtrace_getreg(find_user_regs(thread), ndx));
3370 }
3371
3372 case DIF_VAR_VMREGS: {
3373 uint64_t rval;
3374
3375 if (!dtrace_priv_kernel(state))
3376 return (0);
3377
3378 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
3379
3380 rval = dtrace_getvmreg(ndx);
3381
3382 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
3383
3384 return (rval);
3385 }
3386
3387 case DIF_VAR_CURTHREAD:
3388 if (!dtrace_priv_kernel(state))
3389 return (0);
3390
3391 return ((uint64_t)(uintptr_t)current_thread());
3392
3393 case DIF_VAR_TIMESTAMP:
3394 if (!(mstate->dtms_present & DTRACE_MSTATE_TIMESTAMP)) {
3395 mstate->dtms_timestamp = dtrace_gethrtime();
3396 mstate->dtms_present |= DTRACE_MSTATE_TIMESTAMP;
3397 }
3398 return (mstate->dtms_timestamp);
3399
3400 case DIF_VAR_VTIMESTAMP:
3401 ASSERT(dtrace_vtime_references != 0);
3402 return (dtrace_get_thread_vtime(current_thread()));
3403
3404 case DIF_VAR_WALLTIMESTAMP:
3405 if (!(mstate->dtms_present & DTRACE_MSTATE_WALLTIMESTAMP)) {
3406 mstate->dtms_walltimestamp = dtrace_gethrestime();
3407 mstate->dtms_present |= DTRACE_MSTATE_WALLTIMESTAMP;
3408 }
3409 return (mstate->dtms_walltimestamp);
3410
3411 case DIF_VAR_MACHTIMESTAMP:
3412 if (!(mstate->dtms_present & DTRACE_MSTATE_MACHTIMESTAMP)) {
3413 mstate->dtms_machtimestamp = mach_absolute_time();
3414 mstate->dtms_present |= DTRACE_MSTATE_MACHTIMESTAMP;
3415 }
3416 return (mstate->dtms_machtimestamp);
3417
3418 case DIF_VAR_MACHCTIMESTAMP:
3419 if (!(mstate->dtms_present & DTRACE_MSTATE_MACHCTIMESTAMP)) {
3420 mstate->dtms_machctimestamp = mach_continuous_time();
3421 mstate->dtms_present |= DTRACE_MSTATE_MACHCTIMESTAMP;
3422 }
3423 return (mstate->dtms_machctimestamp);
3424
3425
3426 case DIF_VAR_CPU:
3427 return ((uint64_t) dtrace_get_thread_last_cpu_id(current_thread()));
3428
3429 case DIF_VAR_IPL:
3430 if (!dtrace_priv_kernel(state))
3431 return (0);
3432 if (!(mstate->dtms_present & DTRACE_MSTATE_IPL)) {
3433 mstate->dtms_ipl = dtrace_getipl();
3434 mstate->dtms_present |= DTRACE_MSTATE_IPL;
3435 }
3436 return (mstate->dtms_ipl);
3437
3438 case DIF_VAR_EPID:
3439 ASSERT(mstate->dtms_present & DTRACE_MSTATE_EPID);
3440 return (mstate->dtms_epid);
3441
3442 case DIF_VAR_ID:
3443 ASSERT(mstate->dtms_present & DTRACE_MSTATE_PROBE);
3444 return (mstate->dtms_probe->dtpr_id);
3445
3446 case DIF_VAR_STACKDEPTH:
3447 if (!dtrace_priv_kernel(state))
3448 return (0);
3449 if (!(mstate->dtms_present & DTRACE_MSTATE_STACKDEPTH)) {
3450 int aframes = mstate->dtms_probe->dtpr_aframes + 2;
3451
3452 mstate->dtms_stackdepth = dtrace_getstackdepth(aframes);
3453 mstate->dtms_present |= DTRACE_MSTATE_STACKDEPTH;
3454 }
3455 return (mstate->dtms_stackdepth);
3456
3457 case DIF_VAR_USTACKDEPTH:
3458 if (!dtrace_priv_proc(state))
3459 return (0);
3460 if (!(mstate->dtms_present & DTRACE_MSTATE_USTACKDEPTH)) {
3461 /*
3462 * See comment in DIF_VAR_PID.
3463 */
3464 if (DTRACE_ANCHORED(mstate->dtms_probe) &&
3465 CPU_ON_INTR(CPU)) {
3466 mstate->dtms_ustackdepth = 0;
3467 } else {
3468 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
3469 mstate->dtms_ustackdepth =
3470 dtrace_getustackdepth();
3471 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
3472 }
3473 mstate->dtms_present |= DTRACE_MSTATE_USTACKDEPTH;
3474 }
3475 return (mstate->dtms_ustackdepth);
3476
3477 case DIF_VAR_CALLER:
3478 if (!dtrace_priv_kernel(state))
3479 return (0);
3480 if (!(mstate->dtms_present & DTRACE_MSTATE_CALLER)) {
3481 int aframes = mstate->dtms_probe->dtpr_aframes + 2;
3482
3483 if (!DTRACE_ANCHORED(mstate->dtms_probe)) {
3484 /*
3485 * If this is an unanchored probe, we are
3486 * required to go through the slow path:
3487 * dtrace_caller() only guarantees correct
3488 * results for anchored probes.
3489 */
3490 pc_t caller[2];
3491
3492 dtrace_getpcstack(caller, 2, aframes,
3493 (uint32_t *)(uintptr_t)mstate->dtms_arg[0]);
3494 mstate->dtms_caller = caller[1];
3495 } else if ((mstate->dtms_caller =
3496 dtrace_caller(aframes)) == (uintptr_t)-1) {
3497 /*
3498 * We have failed to do this the quick way;
3499 * we must resort to the slower approach of
3500 * calling dtrace_getpcstack().
3501 */
3502 pc_t caller;
3503
3504 dtrace_getpcstack(&caller, 1, aframes, NULL);
3505 mstate->dtms_caller = caller;
3506 }
3507
3508 mstate->dtms_present |= DTRACE_MSTATE_CALLER;
3509 }
3510 return (mstate->dtms_caller);
3511
3512 case DIF_VAR_UCALLER:
3513 if (!dtrace_priv_proc(state))
3514 return (0);
3515
3516 if (!(mstate->dtms_present & DTRACE_MSTATE_UCALLER)) {
3517 uint64_t ustack[3];
3518
3519 /*
3520 * dtrace_getupcstack() fills in the first uint64_t
3521 * with the current PID. The second uint64_t will
3522 * be the program counter at user-level. The third
3523 * uint64_t will contain the caller, which is what
3524 * we're after.
3525 */
3526 ustack[2] = 0;
3527 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
3528 dtrace_getupcstack(ustack, 3);
3529 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
3530 mstate->dtms_ucaller = ustack[2];
3531 mstate->dtms_present |= DTRACE_MSTATE_UCALLER;
3532 }
3533
3534 return (mstate->dtms_ucaller);
3535
3536 case DIF_VAR_PROBEPROV:
3537 ASSERT(mstate->dtms_present & DTRACE_MSTATE_PROBE);
3538 return (dtrace_dif_varstr(
3539 (uintptr_t)mstate->dtms_probe->dtpr_provider->dtpv_name,
3540 state, mstate));
3541
3542 case DIF_VAR_PROBEMOD:
3543 ASSERT(mstate->dtms_present & DTRACE_MSTATE_PROBE);
3544 return (dtrace_dif_varstr(
3545 (uintptr_t)mstate->dtms_probe->dtpr_mod,
3546 state, mstate));
3547
3548 case DIF_VAR_PROBEFUNC:
3549 ASSERT(mstate->dtms_present & DTRACE_MSTATE_PROBE);
3550 return (dtrace_dif_varstr(
3551 (uintptr_t)mstate->dtms_probe->dtpr_func,
3552 state, mstate));
3553
3554 case DIF_VAR_PROBENAME:
3555 ASSERT(mstate->dtms_present & DTRACE_MSTATE_PROBE);
3556 return (dtrace_dif_varstr(
3557 (uintptr_t)mstate->dtms_probe->dtpr_name,
3558 state, mstate));
3559
3560 case DIF_VAR_PID:
3561 if (!dtrace_priv_proc_relaxed(state))
3562 return (0);
3563
3564 /*
3565 * Note that we are assuming that an unanchored probe is
3566 * always due to a high-level interrupt. (And we're assuming
3567 * that there is only a single high level interrupt.)
3568 */
3569 if (DTRACE_ANCHORED(mstate->dtms_probe) && CPU_ON_INTR(CPU))
3570 /* Anchored probe that fires while on an interrupt accrues to process 0 */
3571 return 0;
3572
3573 return ((uint64_t)dtrace_proc_selfpid());
3574
3575 case DIF_VAR_PPID:
3576 if (!dtrace_priv_proc_relaxed(state))
3577 return (0);
3578
3579 /*
3580 * See comment in DIF_VAR_PID.
3581 */
3582 if (DTRACE_ANCHORED(mstate->dtms_probe) && CPU_ON_INTR(CPU))
3583 return (0);
3584
3585 return ((uint64_t)dtrace_proc_selfppid());
3586
3587 case DIF_VAR_TID:
3588 /* We do not need to check for null current_thread() */
3589 return thread_tid(current_thread()); /* globally unique */
3590
3591 case DIF_VAR_PTHREAD_SELF:
3592 if (!dtrace_priv_proc(state))
3593 return (0);
3594
3595 /* Not currently supported, but we should be able to delta the dispatchqaddr and dispatchqoffset to get pthread_self */
3596 return 0;
3597
3598 case DIF_VAR_DISPATCHQADDR:
3599 if (!dtrace_priv_proc(state))
3600 return (0);
3601
3602 /* We do not need to check for null current_thread() */
3603 return thread_dispatchqaddr(current_thread());
3604
3605 case DIF_VAR_EXECNAME:
3606 {
3607 char *xname = (char *)mstate->dtms_scratch_ptr;
3608 char *pname = proc_best_name(curproc);
3609 size_t scratch_size = sizeof(proc_name_t);
3610
3611 /* The scratch allocation's lifetime is that of the clause. */
3612 if (!DTRACE_INSCRATCH(mstate, scratch_size)) {
3613 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
3614 return 0;
3615 }
3616
3617 if (!dtrace_priv_proc_relaxed(state))
3618 return (0);
3619
3620 mstate->dtms_scratch_ptr += scratch_size;
3621 strlcpy(xname, pname, scratch_size);
3622
3623 return ((uint64_t)(uintptr_t)xname);
3624 }
3625
3626
3627 case DIF_VAR_ZONENAME:
3628 {
3629 /* scratch_size is equal to length('global') + 1 for the null-terminator. */
3630 char *zname = (char *)mstate->dtms_scratch_ptr;
3631 size_t scratch_size = 6 + 1;
3632
3633 if (!dtrace_priv_proc(state))
3634 return (0);
3635
3636 /* The scratch allocation's lifetime is that of the clause. */
3637 if (!DTRACE_INSCRATCH(mstate, scratch_size)) {
3638 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
3639 return 0;
3640 }
3641
3642 mstate->dtms_scratch_ptr += scratch_size;
3643
3644 /* The kernel does not provide zonename, it will always return 'global'. */
3645 strlcpy(zname, "global", scratch_size);
3646
3647 return ((uint64_t)(uintptr_t)zname);
3648 }
3649
3650 #if MONOTONIC
3651 case DIF_VAR_CPUINSTRS:
3652 return mt_cur_cpu_instrs();
3653
3654 case DIF_VAR_CPUCYCLES:
3655 return mt_cur_cpu_cycles();
3656
3657 case DIF_VAR_VINSTRS:
3658 return mt_cur_thread_instrs();
3659
3660 case DIF_VAR_VCYCLES:
3661 return mt_cur_thread_cycles();
3662 #else /* MONOTONIC */
3663 case DIF_VAR_CPUINSTRS: /* FALLTHROUGH */
3664 case DIF_VAR_CPUCYCLES: /* FALLTHROUGH */
3665 case DIF_VAR_VINSTRS: /* FALLTHROUGH */
3666 case DIF_VAR_VCYCLES: /* FALLTHROUGH */
3667 return 0;
3668 #endif /* !MONOTONIC */
3669
3670 case DIF_VAR_UID:
3671 if (!dtrace_priv_proc_relaxed(state))
3672 return (0);
3673
3674 /*
3675 * See comment in DIF_VAR_PID.
3676 */
3677 if (DTRACE_ANCHORED(mstate->dtms_probe) && CPU_ON_INTR(CPU))
3678 return (0);
3679
3680 return ((uint64_t) dtrace_proc_selfruid());
3681
3682 case DIF_VAR_GID:
3683 if (!dtrace_priv_proc(state))
3684 return (0);
3685
3686 /*
3687 * See comment in DIF_VAR_PID.
3688 */
3689 if (DTRACE_ANCHORED(mstate->dtms_probe) && CPU_ON_INTR(CPU))
3690 return (0);
3691
3692 if (dtrace_CRED() != NULL)
3693 /* Credential does not require lazy initialization. */
3694 return ((uint64_t)kauth_getgid());
3695 else {
3696 /* proc_lock would be taken under kauth_cred_proc_ref() in kauth_cred_get(). */
3697 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
3698 return -1ULL;
3699 }
3700
3701 case DIF_VAR_ERRNO: {
3702 uthread_t uthread = current_uthread();
3703 if (!dtrace_priv_proc(state))
3704 return (0);
3705
3706 /*
3707 * See comment in DIF_VAR_PID.
3708 */
3709 if (DTRACE_ANCHORED(mstate->dtms_probe) && CPU_ON_INTR(CPU))
3710 return (0);
3711
3712 if (uthread)
3713 return (uint64_t)uthread->t_dtrace_errno;
3714 else {
3715 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
3716 return -1ULL;
3717 }
3718 }
3719
3720 default:
3721 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
3722 return (0);
3723 }
3724 }
3725
3726 typedef enum dtrace_json_state {
3727 DTRACE_JSON_REST = 1,
3728 DTRACE_JSON_OBJECT,
3729 DTRACE_JSON_STRING,
3730 DTRACE_JSON_STRING_ESCAPE,
3731 DTRACE_JSON_STRING_ESCAPE_UNICODE,
3732 DTRACE_JSON_COLON,
3733 DTRACE_JSON_COMMA,
3734 DTRACE_JSON_VALUE,
3735 DTRACE_JSON_IDENTIFIER,
3736 DTRACE_JSON_NUMBER,
3737 DTRACE_JSON_NUMBER_FRAC,
3738 DTRACE_JSON_NUMBER_EXP,
3739 DTRACE_JSON_COLLECT_OBJECT
3740 } dtrace_json_state_t;
3741
3742 /*
3743 * This function possesses just enough knowledge about JSON to extract a single
3744 * value from a JSON string and store it in the scratch buffer. It is able
3745 * to extract nested object values, and members of arrays by index.
3746 *
3747 * elemlist is a list of JSON keys, stored as packed NUL-terminated strings, to
3748 * be looked up as we descend into the object tree. e.g.
3749 *
3750 * foo[0].bar.baz[32] --> "foo" NUL "0" NUL "bar" NUL "baz" NUL "32" NUL
3751 * with nelems = 5.
3752 *
3753 * The run time of this function must be bounded above by strsize to limit the
3754 * amount of work done in probe context. As such, it is implemented as a
3755 * simple state machine, reading one character at a time using safe loads
3756 * until we find the requested element, hit a parsing error or run off the
3757 * end of the object or string.
3758 *
3759 * As there is no way for a subroutine to return an error without interrupting
3760 * clause execution, we simply return NULL in the event of a missing key or any
3761 * other error condition. Each NULL return in this function is commented with
3762 * the error condition it represents -- parsing or otherwise.
3763 *
3764 * The set of states for the state machine closely matches the JSON
3765 * specification (http://json.org/). Briefly:
3766 *
3767 * DTRACE_JSON_REST:
3768 * Skip whitespace until we find either a top-level Object, moving
3769 * to DTRACE_JSON_OBJECT; or an Array, moving to DTRACE_JSON_VALUE.
3770 *
3771 * DTRACE_JSON_OBJECT:
3772 * Locate the next key String in an Object. Sets a flag to denote
3773 * the next String as a key string and moves to DTRACE_JSON_STRING.
3774 *
3775 * DTRACE_JSON_COLON:
3776 * Skip whitespace until we find the colon that separates key Strings
3777 * from their values. Once found, move to DTRACE_JSON_VALUE.
3778 *
3779 * DTRACE_JSON_VALUE:
3780 * Detects the type of the next value (String, Number, Identifier, Object
3781 * or Array) and routes to the states that process that type. Here we also
3782 * deal with the element selector list if we are requested to traverse down
3783 * into the object tree.
3784 *
3785 * DTRACE_JSON_COMMA:
3786 * Skip whitespace until we find the comma that separates key-value pairs
3787 * in Objects (returning to DTRACE_JSON_OBJECT) or values in Arrays
3788 * (similarly DTRACE_JSON_VALUE). All following literal value processing
3789 * states return to this state at the end of their value, unless otherwise
3790 * noted.
3791 *
3792 * DTRACE_JSON_NUMBER, DTRACE_JSON_NUMBER_FRAC, DTRACE_JSON_NUMBER_EXP:
3793 * Processes a Number literal from the JSON, including any exponent
3794 * component that may be present. Numbers are returned as strings, which
3795 * may be passed to strtoll() if an integer is required.
3796 *
3797 * DTRACE_JSON_IDENTIFIER:
3798 * Processes a "true", "false" or "null" literal in the JSON.
3799 *
3800 * DTRACE_JSON_STRING, DTRACE_JSON_STRING_ESCAPE,
3801 * DTRACE_JSON_STRING_ESCAPE_UNICODE:
3802 * Processes a String literal from the JSON, whether the String denotes
3803 * a key, a value or part of a larger Object. Handles all escape sequences
3804 * present in the specification, including four-digit unicode characters,
3805 * but merely includes the escape sequence without converting it to the
3806 * actual escaped character. If the String is flagged as a key, we
3807 * move to DTRACE_JSON_COLON rather than DTRACE_JSON_COMMA.
3808 *
3809 * DTRACE_JSON_COLLECT_OBJECT:
3810 * This state collects an entire Object (or Array), correctly handling
3811 * embedded strings. If the full element selector list matches this nested
3812 * object, we return the Object in full as a string. If not, we use this
3813 * state to skip to the next value at this level and continue processing.
3814 */
3815 static char *
dtrace_json(uint64_t size,uintptr_t json,char * elemlist,int nelems,char * dest)3816 dtrace_json(uint64_t size, uintptr_t json, char *elemlist, int nelems,
3817 char *dest)
3818 {
3819 dtrace_json_state_t state = DTRACE_JSON_REST;
3820 int64_t array_elem = INT64_MIN;
3821 int64_t array_pos = 0;
3822 uint8_t escape_unicount = 0;
3823 boolean_t string_is_key = B_FALSE;
3824 boolean_t collect_object = B_FALSE;
3825 boolean_t found_key = B_FALSE;
3826 boolean_t in_array = B_FALSE;
3827 uint32_t braces = 0, brackets = 0;
3828 char *elem = elemlist;
3829 char *dd = dest;
3830 uintptr_t cur;
3831
3832 for (cur = json; cur < json + size; cur++) {
3833 char cc = dtrace_load8(cur);
3834 if (cc == '\0')
3835 return (NULL);
3836
3837 switch (state) {
3838 case DTRACE_JSON_REST:
3839 if (isspace(cc))
3840 break;
3841
3842 if (cc == '{') {
3843 state = DTRACE_JSON_OBJECT;
3844 break;
3845 }
3846
3847 if (cc == '[') {
3848 in_array = B_TRUE;
3849 array_pos = 0;
3850 array_elem = dtrace_strtoll(elem, 10, size);
3851 found_key = array_elem == 0 ? B_TRUE : B_FALSE;
3852 state = DTRACE_JSON_VALUE;
3853 break;
3854 }
3855
3856 /*
3857 * ERROR: expected to find a top-level object or array.
3858 */
3859 return (NULL);
3860 case DTRACE_JSON_OBJECT:
3861 if (isspace(cc))
3862 break;
3863
3864 if (cc == '"') {
3865 state = DTRACE_JSON_STRING;
3866 string_is_key = B_TRUE;
3867 break;
3868 }
3869
3870 /*
3871 * ERROR: either the object did not start with a key
3872 * string, or we've run off the end of the object
3873 * without finding the requested key.
3874 */
3875 return (NULL);
3876 case DTRACE_JSON_STRING:
3877 if (cc == '\\') {
3878 *dd++ = '\\';
3879 state = DTRACE_JSON_STRING_ESCAPE;
3880 break;
3881 }
3882
3883 if (cc == '"') {
3884 if (collect_object) {
3885 /*
3886 * We don't reset the dest here, as
3887 * the string is part of a larger
3888 * object being collected.
3889 */
3890 *dd++ = cc;
3891 collect_object = B_FALSE;
3892 state = DTRACE_JSON_COLLECT_OBJECT;
3893 break;
3894 }
3895 *dd = '\0';
3896 dd = dest; /* reset string buffer */
3897 if (string_is_key) {
3898 if (dtrace_strncmp(dest, elem,
3899 size) == 0)
3900 found_key = B_TRUE;
3901 } else if (found_key) {
3902 if (nelems > 1) {
3903 /*
3904 * We expected an object, not
3905 * this string.
3906 */
3907 return (NULL);
3908 }
3909 return (dest);
3910 }
3911 state = string_is_key ? DTRACE_JSON_COLON :
3912 DTRACE_JSON_COMMA;
3913 string_is_key = B_FALSE;
3914 break;
3915 }
3916
3917 *dd++ = cc;
3918 break;
3919 case DTRACE_JSON_STRING_ESCAPE:
3920 *dd++ = cc;
3921 if (cc == 'u') {
3922 escape_unicount = 0;
3923 state = DTRACE_JSON_STRING_ESCAPE_UNICODE;
3924 } else {
3925 state = DTRACE_JSON_STRING;
3926 }
3927 break;
3928 case DTRACE_JSON_STRING_ESCAPE_UNICODE:
3929 if (!isxdigit(cc)) {
3930 /*
3931 * ERROR: invalid unicode escape, expected
3932 * four valid hexidecimal digits.
3933 */
3934 return (NULL);
3935 }
3936
3937 *dd++ = cc;
3938 if (++escape_unicount == 4)
3939 state = DTRACE_JSON_STRING;
3940 break;
3941 case DTRACE_JSON_COLON:
3942 if (isspace(cc))
3943 break;
3944
3945 if (cc == ':') {
3946 state = DTRACE_JSON_VALUE;
3947 break;
3948 }
3949
3950 /*
3951 * ERROR: expected a colon.
3952 */
3953 return (NULL);
3954 case DTRACE_JSON_COMMA:
3955 if (isspace(cc))
3956 break;
3957
3958 if (cc == ',') {
3959 if (in_array) {
3960 state = DTRACE_JSON_VALUE;
3961 if (++array_pos == array_elem)
3962 found_key = B_TRUE;
3963 } else {
3964 state = DTRACE_JSON_OBJECT;
3965 }
3966 break;
3967 }
3968
3969 /*
3970 * ERROR: either we hit an unexpected character, or
3971 * we reached the end of the object or array without
3972 * finding the requested key.
3973 */
3974 return (NULL);
3975 case DTRACE_JSON_IDENTIFIER:
3976 if (islower(cc)) {
3977 *dd++ = cc;
3978 break;
3979 }
3980
3981 *dd = '\0';
3982 dd = dest; /* reset string buffer */
3983
3984 if (dtrace_strncmp(dest, "true", 5) == 0 ||
3985 dtrace_strncmp(dest, "false", 6) == 0 ||
3986 dtrace_strncmp(dest, "null", 5) == 0) {
3987 if (found_key) {
3988 if (nelems > 1) {
3989 /*
3990 * ERROR: We expected an object,
3991 * not this identifier.
3992 */
3993 return (NULL);
3994 }
3995 return (dest);
3996 } else {
3997 cur--;
3998 state = DTRACE_JSON_COMMA;
3999 break;
4000 }
4001 }
4002
4003 /*
4004 * ERROR: we did not recognise the identifier as one
4005 * of those in the JSON specification.
4006 */
4007 return (NULL);
4008 case DTRACE_JSON_NUMBER:
4009 if (cc == '.') {
4010 *dd++ = cc;
4011 state = DTRACE_JSON_NUMBER_FRAC;
4012 break;
4013 }
4014
4015 if (cc == 'x' || cc == 'X') {
4016 /*
4017 * ERROR: specification explicitly excludes
4018 * hexidecimal or octal numbers.
4019 */
4020 return (NULL);
4021 }
4022
4023 OS_FALLTHROUGH;
4024 case DTRACE_JSON_NUMBER_FRAC:
4025 if (cc == 'e' || cc == 'E') {
4026 *dd++ = cc;
4027 state = DTRACE_JSON_NUMBER_EXP;
4028 break;
4029 }
4030
4031 if (cc == '+' || cc == '-') {
4032 /*
4033 * ERROR: expect sign as part of exponent only.
4034 */
4035 return (NULL);
4036 }
4037 OS_FALLTHROUGH;
4038 case DTRACE_JSON_NUMBER_EXP:
4039 if (isdigit(cc) || cc == '+' || cc == '-') {
4040 *dd++ = cc;
4041 break;
4042 }
4043
4044 *dd = '\0';
4045 dd = dest; /* reset string buffer */
4046 if (found_key) {
4047 if (nelems > 1) {
4048 /*
4049 * ERROR: We expected an object, not
4050 * this number.
4051 */
4052 return (NULL);
4053 }
4054 return (dest);
4055 }
4056
4057 cur--;
4058 state = DTRACE_JSON_COMMA;
4059 break;
4060 case DTRACE_JSON_VALUE:
4061 if (isspace(cc))
4062 break;
4063
4064 if (cc == '{' || cc == '[') {
4065 if (nelems > 1 && found_key) {
4066 in_array = cc == '[' ? B_TRUE : B_FALSE;
4067 /*
4068 * If our element selector directs us
4069 * to descend into this nested object,
4070 * then move to the next selector
4071 * element in the list and restart the
4072 * state machine.
4073 */
4074 while (*elem != '\0')
4075 elem++;
4076 elem++; /* skip the inter-element NUL */
4077 nelems--;
4078 dd = dest;
4079 if (in_array) {
4080 state = DTRACE_JSON_VALUE;
4081 array_pos = 0;
4082 array_elem = dtrace_strtoll(
4083 elem, 10, size);
4084 found_key = array_elem == 0 ?
4085 B_TRUE : B_FALSE;
4086 } else {
4087 found_key = B_FALSE;
4088 state = DTRACE_JSON_OBJECT;
4089 }
4090 break;
4091 }
4092
4093 /*
4094 * Otherwise, we wish to either skip this
4095 * nested object or return it in full.
4096 */
4097 if (cc == '[')
4098 brackets = 1;
4099 else
4100 braces = 1;
4101 *dd++ = cc;
4102 state = DTRACE_JSON_COLLECT_OBJECT;
4103 break;
4104 }
4105
4106 if (cc == '"') {
4107 state = DTRACE_JSON_STRING;
4108 break;
4109 }
4110
4111 if (islower(cc)) {
4112 /*
4113 * Here we deal with true, false and null.
4114 */
4115 *dd++ = cc;
4116 state = DTRACE_JSON_IDENTIFIER;
4117 break;
4118 }
4119
4120 if (cc == '-' || isdigit(cc)) {
4121 *dd++ = cc;
4122 state = DTRACE_JSON_NUMBER;
4123 break;
4124 }
4125
4126 /*
4127 * ERROR: unexpected character at start of value.
4128 */
4129 return (NULL);
4130 case DTRACE_JSON_COLLECT_OBJECT:
4131 if (cc == '\0')
4132 /*
4133 * ERROR: unexpected end of input.
4134 */
4135 return (NULL);
4136
4137 *dd++ = cc;
4138 if (cc == '"') {
4139 collect_object = B_TRUE;
4140 state = DTRACE_JSON_STRING;
4141 break;
4142 }
4143
4144 if (cc == ']') {
4145 if (brackets-- == 0) {
4146 /*
4147 * ERROR: unbalanced brackets.
4148 */
4149 return (NULL);
4150 }
4151 } else if (cc == '}') {
4152 if (braces-- == 0) {
4153 /*
4154 * ERROR: unbalanced braces.
4155 */
4156 return (NULL);
4157 }
4158 } else if (cc == '{') {
4159 braces++;
4160 } else if (cc == '[') {
4161 brackets++;
4162 }
4163
4164 if (brackets == 0 && braces == 0) {
4165 if (found_key) {
4166 *dd = '\0';
4167 return (dest);
4168 }
4169 dd = dest; /* reset string buffer */
4170 state = DTRACE_JSON_COMMA;
4171 }
4172 break;
4173 }
4174 }
4175 return (NULL);
4176 }
4177
4178 /*
4179 * Emulate the execution of DTrace ID subroutines invoked by the call opcode.
4180 * Notice that we don't bother validating the proper number of arguments or
4181 * their types in the tuple stack. This isn't needed because all argument
4182 * interpretation is safe because of our load safety -- the worst that can
4183 * happen is that a bogus program can obtain bogus results.
4184 */
4185 static void
dtrace_dif_subr(uint_t subr,uint_t rd,uint64_t * regs,dtrace_key_t * tupregs,int nargs,dtrace_mstate_t * mstate,dtrace_state_t * state)4186 dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
4187 dtrace_key_t *tupregs, int nargs,
4188 dtrace_mstate_t *mstate, dtrace_state_t *state)
4189 {
4190 volatile uint16_t *flags = &cpu_core[CPU->cpu_id].cpuc_dtrace_flags;
4191 volatile uint64_t *illval = &cpu_core[CPU->cpu_id].cpuc_dtrace_illval;
4192 dtrace_vstate_t *vstate = &state->dts_vstate;
4193
4194 #if !defined(__APPLE__)
4195 union {
4196 mutex_impl_t mi;
4197 uint64_t mx;
4198 } m;
4199
4200 union {
4201 krwlock_t ri;
4202 uintptr_t rw;
4203 } r;
4204 #else
4205 /* FIXME: awaits lock/mutex work */
4206 #endif /* __APPLE__ */
4207
4208 switch (subr) {
4209 case DIF_SUBR_RAND:
4210 regs[rd] = dtrace_xoroshiro128_plus_next(
4211 state->dts_rstate[CPU->cpu_id]);
4212 break;
4213
4214 #if !defined(__APPLE__)
4215 case DIF_SUBR_MUTEX_OWNED:
4216 if (!dtrace_canload(tupregs[0].dttk_value, sizeof (kmutex_t),
4217 mstate, vstate)) {
4218 regs[rd] = 0;
4219 break;
4220 }
4221
4222 m.mx = dtrace_load64(tupregs[0].dttk_value);
4223 if (MUTEX_TYPE_ADAPTIVE(&m.mi))
4224 regs[rd] = MUTEX_OWNER(&m.mi) != MUTEX_NO_OWNER;
4225 else
4226 regs[rd] = LOCK_HELD(&m.mi.m_spin.m_spinlock);
4227 break;
4228
4229 case DIF_SUBR_MUTEX_OWNER:
4230 if (!dtrace_canload(tupregs[0].dttk_value, sizeof (kmutex_t),
4231 mstate, vstate)) {
4232 regs[rd] = 0;
4233 break;
4234 }
4235
4236 m.mx = dtrace_load64(tupregs[0].dttk_value);
4237 if (MUTEX_TYPE_ADAPTIVE(&m.mi) &&
4238 MUTEX_OWNER(&m.mi) != MUTEX_NO_OWNER)
4239 regs[rd] = (uintptr_t)MUTEX_OWNER(&m.mi);
4240 else
4241 regs[rd] = 0;
4242 break;
4243
4244 case DIF_SUBR_MUTEX_TYPE_ADAPTIVE:
4245 if (!dtrace_canload(tupregs[0].dttk_value, sizeof (kmutex_t),
4246 mstate, vstate)) {
4247 regs[rd] = 0;
4248 break;
4249 }
4250
4251 m.mx = dtrace_load64(tupregs[0].dttk_value);
4252 regs[rd] = MUTEX_TYPE_ADAPTIVE(&m.mi);
4253 break;
4254
4255 case DIF_SUBR_MUTEX_TYPE_SPIN:
4256 if (!dtrace_canload(tupregs[0].dttk_value, sizeof (kmutex_t),
4257 mstate, vstate)) {
4258 regs[rd] = 0;
4259 break;
4260 }
4261
4262 m.mx = dtrace_load64(tupregs[0].dttk_value);
4263 regs[rd] = MUTEX_TYPE_SPIN(&m.mi);
4264 break;
4265
4266 case DIF_SUBR_RW_READ_HELD: {
4267 uintptr_t tmp;
4268
4269 if (!dtrace_canload(tupregs[0].dttk_value, sizeof (uintptr_t),
4270 mstate, vstate)) {
4271 regs[rd] = 0;
4272 break;
4273 }
4274
4275 r.rw = dtrace_loadptr(tupregs[0].dttk_value);
4276 regs[rd] = _RW_READ_HELD(&r.ri, tmp);
4277 break;
4278 }
4279
4280 case DIF_SUBR_RW_WRITE_HELD:
4281 if (!dtrace_canload(tupregs[0].dttk_value, sizeof (krwlock_t),
4282 mstate, vstate)) {
4283 regs[rd] = 0;
4284 break;
4285 }
4286
4287 r.rw = dtrace_loadptr(tupregs[0].dttk_value);
4288 regs[rd] = _RW_WRITE_HELD(&r.ri);
4289 break;
4290
4291 case DIF_SUBR_RW_ISWRITER:
4292 if (!dtrace_canload(tupregs[0].dttk_value, sizeof (krwlock_t),
4293 mstate, vstate)) {
4294 regs[rd] = 0;
4295 break;
4296 }
4297
4298 r.rw = dtrace_loadptr(tupregs[0].dttk_value);
4299 regs[rd] = _RW_ISWRITER(&r.ri);
4300 break;
4301 #else
4302 /* FIXME: awaits lock/mutex work */
4303 #endif /* __APPLE__ */
4304
4305 case DIF_SUBR_BCOPY: {
4306 /*
4307 * We need to be sure that the destination is in the scratch
4308 * region -- no other region is allowed.
4309 */
4310 uintptr_t src = tupregs[0].dttk_value;
4311 uintptr_t dest = tupregs[1].dttk_value;
4312 size_t size = tupregs[2].dttk_value;
4313
4314 if (!dtrace_inscratch(dest, size, mstate)) {
4315 *flags |= CPU_DTRACE_BADADDR;
4316 *illval = regs[rd];
4317 break;
4318 }
4319
4320 if (!dtrace_canload(src, size, mstate, vstate)) {
4321 regs[rd] = 0;
4322 break;
4323 }
4324
4325 dtrace_bcopy((void *)src, (void *)dest, size);
4326 break;
4327 }
4328
4329 case DIF_SUBR_ALLOCA:
4330 case DIF_SUBR_COPYIN: {
4331 uintptr_t dest = P2ROUNDUP(mstate->dtms_scratch_ptr, 8);
4332 uint64_t size =
4333 tupregs[subr == DIF_SUBR_ALLOCA ? 0 : 1].dttk_value;
4334 size_t scratch_size = (dest - mstate->dtms_scratch_ptr) + size;
4335
4336 /*
4337 * Check whether the user can access kernel memory
4338 */
4339 if (dtrace_priv_kernel(state) == 0) {
4340 DTRACE_CPUFLAG_SET(CPU_DTRACE_KPRIV);
4341 regs[rd] = 0;
4342 break;
4343 }
4344 /*
4345 * This action doesn't require any credential checks since
4346 * probes will not activate in user contexts to which the
4347 * enabling user does not have permissions.
4348 */
4349
4350 /*
4351 * Rounding up the user allocation size could have overflowed
4352 * a large, bogus allocation (like -1ULL) to 0.
4353 */
4354 if (scratch_size < size ||
4355 !DTRACE_INSCRATCH(mstate, scratch_size)) {
4356 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
4357 regs[rd] = 0;
4358 break;
4359 }
4360
4361 if (subr == DIF_SUBR_COPYIN) {
4362 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
4363 if (dtrace_priv_proc(state))
4364 dtrace_copyin(tupregs[0].dttk_value, dest, size, flags);
4365 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
4366 }
4367
4368 mstate->dtms_scratch_ptr += scratch_size;
4369 regs[rd] = dest;
4370 break;
4371 }
4372
4373 case DIF_SUBR_COPYINTO: {
4374 uint64_t size = tupregs[1].dttk_value;
4375 uintptr_t dest = tupregs[2].dttk_value;
4376
4377 /*
4378 * This action doesn't require any credential checks since
4379 * probes will not activate in user contexts to which the
4380 * enabling user does not have permissions.
4381 */
4382 if (!dtrace_inscratch(dest, size, mstate)) {
4383 *flags |= CPU_DTRACE_BADADDR;
4384 *illval = regs[rd];
4385 break;
4386 }
4387
4388 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
4389 if (dtrace_priv_proc(state))
4390 dtrace_copyin(tupregs[0].dttk_value, dest, size, flags);
4391 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
4392 break;
4393 }
4394
4395 case DIF_SUBR_COPYINSTR: {
4396 uintptr_t dest = mstate->dtms_scratch_ptr;
4397 uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
4398
4399 if (nargs > 1 && tupregs[1].dttk_value < size)
4400 size = tupregs[1].dttk_value + 1;
4401
4402 /*
4403 * This action doesn't require any credential checks since
4404 * probes will not activate in user contexts to which the
4405 * enabling user does not have permissions.
4406 */
4407 if (!DTRACE_INSCRATCH(mstate, size)) {
4408 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
4409 regs[rd] = 0;
4410 break;
4411 }
4412
4413 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
4414 if (dtrace_priv_proc(state))
4415 dtrace_copyinstr(tupregs[0].dttk_value, dest, size, flags);
4416 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
4417
4418 ((char *)dest)[size - 1] = '\0';
4419 mstate->dtms_scratch_ptr += size;
4420 regs[rd] = dest;
4421 break;
4422 }
4423
4424 case DIF_SUBR_MSGSIZE:
4425 case DIF_SUBR_MSGDSIZE: {
4426 /* Darwin does not implement SysV streams messages */
4427 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
4428 regs[rd] = 0;
4429 break;
4430 }
4431
4432 case DIF_SUBR_PROGENYOF: {
4433 pid_t pid = tupregs[0].dttk_value;
4434 struct proc *p = current_proc();
4435 int rval = 0, lim = nprocs;
4436
4437 while(p && (lim-- > 0)) {
4438 pid_t ppid;
4439
4440 ppid = (pid_t)dtrace_load32((uintptr_t)&(p->p_pid));
4441 if (*flags & CPU_DTRACE_FAULT)
4442 break;
4443
4444 if (ppid == pid) {
4445 rval = 1;
4446 break;
4447 }
4448
4449 if (ppid == 0)
4450 break; /* Can't climb process tree any further. */
4451
4452 p = (struct proc *)dtrace_loadptr((uintptr_t)&(p->p_pptr));
4453 #if __has_feature(ptrauth_calls)
4454 p = ptrauth_strip(p, ptrauth_key_process_independent_data);
4455 #endif
4456 if (*flags & CPU_DTRACE_FAULT)
4457 break;
4458 }
4459
4460 regs[rd] = rval;
4461 break;
4462 }
4463
4464 case DIF_SUBR_SPECULATION:
4465 regs[rd] = dtrace_speculation(state);
4466 break;
4467
4468
4469 case DIF_SUBR_COPYOUT: {
4470 uintptr_t kaddr = tupregs[0].dttk_value;
4471 user_addr_t uaddr = tupregs[1].dttk_value;
4472 uint64_t size = tupregs[2].dttk_value;
4473
4474 if (!dtrace_destructive_disallow &&
4475 dtrace_priv_proc_control(state) &&
4476 !dtrace_istoxic(kaddr, size) &&
4477 dtrace_canload(kaddr, size, mstate, vstate)) {
4478 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
4479 dtrace_copyout(kaddr, uaddr, size, flags);
4480 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
4481 }
4482 break;
4483 }
4484
4485 case DIF_SUBR_COPYOUTSTR: {
4486 uintptr_t kaddr = tupregs[0].dttk_value;
4487 user_addr_t uaddr = tupregs[1].dttk_value;
4488 uint64_t size = tupregs[2].dttk_value;
4489 size_t lim;
4490
4491 if (!dtrace_destructive_disallow &&
4492 dtrace_priv_proc_control(state) &&
4493 !dtrace_istoxic(kaddr, size) &&
4494 dtrace_strcanload(kaddr, size, &lim, mstate, vstate)) {
4495 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
4496 dtrace_copyoutstr(kaddr, uaddr, lim, flags);
4497 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
4498 }
4499 break;
4500 }
4501
4502 case DIF_SUBR_STRLEN: {
4503 size_t size = state->dts_options[DTRACEOPT_STRSIZE];
4504 uintptr_t addr = (uintptr_t)tupregs[0].dttk_value;
4505 size_t lim;
4506
4507 if (!dtrace_strcanload(addr, size, &lim, mstate, vstate)) {
4508 regs[rd] = 0;
4509 break;
4510 }
4511
4512 regs[rd] = dtrace_strlen((char *)addr, lim);
4513
4514 break;
4515 }
4516
4517 case DIF_SUBR_STRCHR:
4518 case DIF_SUBR_STRRCHR: {
4519 /*
4520 * We're going to iterate over the string looking for the
4521 * specified character. We will iterate until we have reached
4522 * the string length or we have found the character. If this
4523 * is DIF_SUBR_STRRCHR, we will look for the last occurrence
4524 * of the specified character instead of the first.
4525 */
4526 uintptr_t addr = tupregs[0].dttk_value;
4527 uintptr_t addr_limit;
4528 uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
4529 size_t lim;
4530 char c, target = (char)tupregs[1].dttk_value;
4531
4532 if (!dtrace_strcanload(addr, size, &lim, mstate, vstate)) {
4533 regs[rd] = 0;
4534 break;
4535 }
4536 addr_limit = addr + lim;
4537
4538 for (regs[rd] = 0; addr < addr_limit; addr++) {
4539 if ((c = dtrace_load8(addr)) == target) {
4540 regs[rd] = addr;
4541
4542 if (subr == DIF_SUBR_STRCHR)
4543 break;
4544 }
4545
4546 if (c == '\0')
4547 break;
4548 }
4549
4550 break;
4551 }
4552
4553 case DIF_SUBR_STRSTR:
4554 case DIF_SUBR_INDEX:
4555 case DIF_SUBR_RINDEX: {
4556 /*
4557 * We're going to iterate over the string looking for the
4558 * specified string. We will iterate until we have reached
4559 * the string length or we have found the string. (Yes, this
4560 * is done in the most naive way possible -- but considering
4561 * that the string we're searching for is likely to be
4562 * relatively short, the complexity of Rabin-Karp or similar
4563 * hardly seems merited.)
4564 */
4565 char *addr = (char *)(uintptr_t)tupregs[0].dttk_value;
4566 char *substr = (char *)(uintptr_t)tupregs[1].dttk_value;
4567 uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
4568 size_t len = dtrace_strlen(addr, size);
4569 size_t sublen = dtrace_strlen(substr, size);
4570 char *limit = addr + len, *orig = addr;
4571 int notfound = subr == DIF_SUBR_STRSTR ? 0 : -1;
4572 int inc = 1;
4573
4574 regs[rd] = notfound;
4575
4576 if (!dtrace_canload((uintptr_t)addr, len + 1, mstate, vstate)) {
4577 regs[rd] = 0;
4578 break;
4579 }
4580
4581 if (!dtrace_canload((uintptr_t)substr, sublen + 1, mstate,
4582 vstate)) {
4583 regs[rd] = 0;
4584 break;
4585 }
4586
4587 /*
4588 * strstr() and index()/rindex() have similar semantics if
4589 * both strings are the empty string: strstr() returns a
4590 * pointer to the (empty) string, and index() and rindex()
4591 * both return index 0 (regardless of any position argument).
4592 */
4593 if (sublen == 0 && len == 0) {
4594 if (subr == DIF_SUBR_STRSTR)
4595 regs[rd] = (uintptr_t)addr;
4596 else
4597 regs[rd] = 0;
4598 break;
4599 }
4600
4601 if (subr != DIF_SUBR_STRSTR) {
4602 if (subr == DIF_SUBR_RINDEX) {
4603 limit = orig - 1;
4604 addr += len;
4605 inc = -1;
4606 }
4607
4608 /*
4609 * Both index() and rindex() take an optional position
4610 * argument that denotes the starting position.
4611 */
4612 if (nargs == 3) {
4613 int64_t pos = (int64_t)tupregs[2].dttk_value;
4614
4615 /*
4616 * If the position argument to index() is
4617 * negative, Perl implicitly clamps it at
4618 * zero. This semantic is a little surprising
4619 * given the special meaning of negative
4620 * positions to similar Perl functions like
4621 * substr(), but it appears to reflect a
4622 * notion that index() can start from a
4623 * negative index and increment its way up to
4624 * the string. Given this notion, Perl's
4625 * rindex() is at least self-consistent in
4626 * that it implicitly clamps positions greater
4627 * than the string length to be the string
4628 * length. Where Perl completely loses
4629 * coherence, however, is when the specified
4630 * substring is the empty string (""). In
4631 * this case, even if the position is
4632 * negative, rindex() returns 0 -- and even if
4633 * the position is greater than the length,
4634 * index() returns the string length. These
4635 * semantics violate the notion that index()
4636 * should never return a value less than the
4637 * specified position and that rindex() should
4638 * never return a value greater than the
4639 * specified position. (One assumes that
4640 * these semantics are artifacts of Perl's
4641 * implementation and not the results of
4642 * deliberate design -- it beggars belief that
4643 * even Larry Wall could desire such oddness.)
4644 * While in the abstract one would wish for
4645 * consistent position semantics across
4646 * substr(), index() and rindex() -- or at the
4647 * very least self-consistent position
4648 * semantics for index() and rindex() -- we
4649 * instead opt to keep with the extant Perl
4650 * semantics, in all their broken glory. (Do
4651 * we have more desire to maintain Perl's
4652 * semantics than Perl does? Probably.)
4653 */
4654 if (subr == DIF_SUBR_RINDEX) {
4655 if (pos < 0) {
4656 if (sublen == 0)
4657 regs[rd] = 0;
4658 break;
4659 }
4660
4661 if ((size_t)pos > len)
4662 pos = len;
4663 } else {
4664 if (pos < 0)
4665 pos = 0;
4666
4667 if ((size_t)pos >= len) {
4668 if (sublen == 0)
4669 regs[rd] = len;
4670 break;
4671 }
4672 }
4673
4674 addr = orig + pos;
4675 }
4676 }
4677
4678 for (regs[rd] = notfound; addr != limit; addr += inc) {
4679 if (dtrace_strncmp(addr, substr, sublen) == 0) {
4680 if (subr != DIF_SUBR_STRSTR) {
4681 /*
4682 * As D index() and rindex() are
4683 * modeled on Perl (and not on awk),
4684 * we return a zero-based (and not a
4685 * one-based) index. (For you Perl
4686 * weenies: no, we're not going to add
4687 * $[ -- and shouldn't you be at a con
4688 * or something?)
4689 */
4690 regs[rd] = (uintptr_t)(addr - orig);
4691 break;
4692 }
4693
4694 ASSERT(subr == DIF_SUBR_STRSTR);
4695 regs[rd] = (uintptr_t)addr;
4696 break;
4697 }
4698 }
4699
4700 break;
4701 }
4702
4703 case DIF_SUBR_STRTOK: {
4704 uintptr_t addr = tupregs[0].dttk_value;
4705 uintptr_t tokaddr = tupregs[1].dttk_value;
4706 uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
4707 uintptr_t limit, toklimit;
4708 size_t clim;
4709 char *dest = (char *)mstate->dtms_scratch_ptr;
4710 uint8_t c='\0', tokmap[32]; /* 256 / 8 */
4711 uint64_t i = 0;
4712
4713 /*
4714 * Check both the token buffer and (later) the input buffer,
4715 * since both could be non-scratch addresses.
4716 */
4717 if (!dtrace_strcanload(tokaddr, size, &clim, mstate, vstate)) {
4718 regs[rd] = 0;
4719 break;
4720 }
4721 toklimit = tokaddr + clim;
4722
4723 if (!DTRACE_INSCRATCH(mstate, size)) {
4724 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
4725 regs[rd] = 0;
4726 break;
4727 }
4728
4729 if (addr == 0) {
4730 /*
4731 * If the address specified is NULL, we use our saved
4732 * strtok pointer from the mstate. Note that this
4733 * means that the saved strtok pointer is _only_
4734 * valid within multiple enablings of the same probe --
4735 * it behaves like an implicit clause-local variable.
4736 */
4737 addr = mstate->dtms_strtok;
4738 limit = mstate->dtms_strtok_limit;
4739 } else {
4740 /*
4741 * If the user-specified address is non-NULL we must
4742 * access check it. This is the only time we have
4743 * a chance to do so, since this address may reside
4744 * in the string table of this clause-- future calls
4745 * (when we fetch addr from mstate->dtms_strtok)
4746 * would fail this access check.
4747 */
4748 if (!dtrace_strcanload(addr, size, &clim, mstate,
4749 vstate)) {
4750 regs[rd] = 0;
4751 break;
4752 }
4753 limit = addr + clim;
4754 }
4755
4756 /*
4757 * First, zero the token map, and then process the token
4758 * string -- setting a bit in the map for every character
4759 * found in the token string.
4760 */
4761 for (i = 0; i < (int)sizeof (tokmap); i++)
4762 tokmap[i] = 0;
4763
4764 for (; tokaddr < toklimit; tokaddr++) {
4765 if ((c = dtrace_load8(tokaddr)) == '\0')
4766 break;
4767
4768 ASSERT((c >> 3) < sizeof (tokmap));
4769 tokmap[c >> 3] |= (1 << (c & 0x7));
4770 }
4771
4772 for (; addr < limit; addr++) {
4773 /*
4774 * We're looking for a character that is _not_
4775 * contained in the token string.
4776 */
4777 if ((c = dtrace_load8(addr)) == '\0')
4778 break;
4779
4780 if (!(tokmap[c >> 3] & (1 << (c & 0x7))))
4781 break;
4782 }
4783
4784 if (c == '\0') {
4785 /*
4786 * We reached the end of the string without finding
4787 * any character that was not in the token string.
4788 * We return NULL in this case, and we set the saved
4789 * address to NULL as well.
4790 */
4791 regs[rd] = 0;
4792 mstate->dtms_strtok = 0;
4793 mstate->dtms_strtok_limit = 0;
4794 break;
4795 }
4796
4797 /*
4798 * From here on, we're copying into the destination string.
4799 */
4800 for (i = 0; addr < limit && i < size - 1; addr++) {
4801 if ((c = dtrace_load8(addr)) == '\0')
4802 break;
4803
4804 if (tokmap[c >> 3] & (1 << (c & 0x7)))
4805 break;
4806
4807 ASSERT(i < size);
4808 dest[i++] = c;
4809 }
4810
4811 ASSERT(i < size);
4812 dest[i] = '\0';
4813 regs[rd] = (uintptr_t)dest;
4814 mstate->dtms_scratch_ptr += size;
4815 mstate->dtms_strtok = addr;
4816 mstate->dtms_strtok_limit = limit;
4817 break;
4818 }
4819
4820 case DIF_SUBR_SUBSTR: {
4821 uintptr_t s = tupregs[0].dttk_value;
4822 uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
4823 char *d = (char *)mstate->dtms_scratch_ptr;
4824 int64_t index = (int64_t)tupregs[1].dttk_value;
4825 int64_t remaining = (int64_t)tupregs[2].dttk_value;
4826 size_t len = dtrace_strlen((char *)s, size);
4827 int64_t i = 0;
4828
4829 if (!dtrace_canload(s, len + 1, mstate, vstate)) {
4830 regs[rd] = 0;
4831 break;
4832 }
4833
4834 if (!DTRACE_INSCRATCH(mstate, size)) {
4835 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
4836 regs[rd] = 0;
4837 break;
4838 }
4839
4840 if (nargs <= 2)
4841 remaining = (int64_t)size;
4842
4843 if (index < 0) {
4844 index += len;
4845
4846 if (index < 0 && index + remaining > 0) {
4847 remaining += index;
4848 index = 0;
4849 }
4850 }
4851
4852 if ((size_t)index >= len || index < 0) {
4853 remaining = 0;
4854 } else if (remaining < 0) {
4855 remaining += len - index;
4856 } else if ((uint64_t)index + (uint64_t)remaining > size) {
4857 remaining = size - index;
4858 }
4859
4860 for (i = 0; i < remaining; i++) {
4861 if ((d[i] = dtrace_load8(s + index + i)) == '\0')
4862 break;
4863 }
4864
4865 d[i] = '\0';
4866
4867 mstate->dtms_scratch_ptr += size;
4868 regs[rd] = (uintptr_t)d;
4869 break;
4870 }
4871
4872 case DIF_SUBR_GETMAJOR:
4873 regs[rd] = (uintptr_t)major( (dev_t)tupregs[0].dttk_value );
4874 break;
4875
4876 case DIF_SUBR_GETMINOR:
4877 regs[rd] = (uintptr_t)minor( (dev_t)tupregs[0].dttk_value );
4878 break;
4879
4880 case DIF_SUBR_DDI_PATHNAME: {
4881 /* APPLE NOTE: currently unsupported on Darwin */
4882 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
4883 regs[rd] = 0;
4884 break;
4885 }
4886
4887 case DIF_SUBR_STRJOIN: {
4888 char *d = (char *)mstate->dtms_scratch_ptr;
4889 uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
4890 uintptr_t s1 = tupregs[0].dttk_value;
4891 uintptr_t s2 = tupregs[1].dttk_value;
4892 uint64_t i = 0, j = 0;
4893 size_t lim1, lim2;
4894 char c;
4895
4896 if (!dtrace_strcanload(s1, size, &lim1, mstate, vstate) ||
4897 !dtrace_strcanload(s2, size, &lim2, mstate, vstate)) {
4898 regs[rd] = 0;
4899 break;
4900 }
4901
4902 if (!DTRACE_INSCRATCH(mstate, size)) {
4903 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
4904 regs[rd] = 0;
4905 break;
4906 }
4907
4908 for (;;) {
4909 if (i >= size) {
4910 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
4911 regs[rd] = 0;
4912 break;
4913 }
4914 c = (i >= lim1) ? '\0' : dtrace_load8(s1++);
4915 if ((d[i++] = c) == '\0') {
4916 i--;
4917 break;
4918 }
4919 }
4920
4921 for (;;) {
4922 if (i >= size) {
4923 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
4924 regs[rd] = 0;
4925 break;
4926 }
4927 c = (j++ >= lim2) ? '\0' : dtrace_load8(s2++);
4928 if ((d[i++] = c) == '\0')
4929 break;
4930 }
4931
4932 if (i < size) {
4933 mstate->dtms_scratch_ptr += i;
4934 regs[rd] = (uintptr_t)d;
4935 }
4936
4937 break;
4938 }
4939
4940 case DIF_SUBR_STRTOLL: {
4941 uintptr_t s = tupregs[0].dttk_value;
4942 uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
4943 size_t lim;
4944 int base = 10;
4945
4946 if (nargs > 1) {
4947 if ((base = tupregs[1].dttk_value) <= 1 ||
4948 base > ('z' - 'a' + 1) + ('9' - '0' + 1)) {
4949 *flags |= CPU_DTRACE_ILLOP;
4950 break;
4951 }
4952 }
4953
4954 if (!dtrace_strcanload(s, size, &lim, mstate, vstate)) {
4955 regs[rd] = INT64_MIN;
4956 break;
4957 }
4958
4959 regs[rd] = dtrace_strtoll((char *)s, base, lim);
4960 break;
4961 }
4962
4963 case DIF_SUBR_LLTOSTR: {
4964 int64_t i = (int64_t)tupregs[0].dttk_value;
4965 uint64_t val, digit;
4966 uint64_t size = 65; /* enough room for 2^64 in binary */
4967 char *end = (char *)mstate->dtms_scratch_ptr + size - 1;
4968 int base = 10;
4969
4970 if (nargs > 1) {
4971 if ((base = tupregs[1].dttk_value) <= 1 ||
4972 base > ('z' - 'a' + 1) + ('9' - '0' + 1)) {
4973 *flags |= CPU_DTRACE_ILLOP;
4974 break;
4975 }
4976 }
4977
4978 val = (base == 10 && i < 0) ? i * -1 : i;
4979
4980 if (!DTRACE_INSCRATCH(mstate, size)) {
4981 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
4982 regs[rd] = 0;
4983 break;
4984 }
4985
4986 for (*end-- = '\0'; val; val /= base) {
4987 if ((digit = val % base) <= '9' - '0') {
4988 *end-- = '0' + digit;
4989 } else {
4990 *end-- = 'a' + (digit - ('9' - '0') - 1);
4991 }
4992 }
4993
4994 if (i == 0 && base == 16)
4995 *end-- = '0';
4996
4997 if (base == 16)
4998 *end-- = 'x';
4999
5000 if (i == 0 || base == 8 || base == 16)
5001 *end-- = '0';
5002
5003 if (i < 0 && base == 10)
5004 *end-- = '-';
5005
5006 regs[rd] = (uintptr_t)end + 1;
5007 mstate->dtms_scratch_ptr += size;
5008 break;
5009 }
5010
5011 case DIF_SUBR_HTONS:
5012 case DIF_SUBR_NTOHS:
5013 #ifdef _BIG_ENDIAN
5014 regs[rd] = (uint16_t)tupregs[0].dttk_value;
5015 #else
5016 regs[rd] = DT_BSWAP_16((uint16_t)tupregs[0].dttk_value);
5017 #endif
5018 break;
5019
5020
5021 case DIF_SUBR_HTONL:
5022 case DIF_SUBR_NTOHL:
5023 #ifdef _BIG_ENDIAN
5024 regs[rd] = (uint32_t)tupregs[0].dttk_value;
5025 #else
5026 regs[rd] = DT_BSWAP_32((uint32_t)tupregs[0].dttk_value);
5027 #endif
5028 break;
5029
5030
5031 case DIF_SUBR_HTONLL:
5032 case DIF_SUBR_NTOHLL:
5033 #ifdef _BIG_ENDIAN
5034 regs[rd] = (uint64_t)tupregs[0].dttk_value;
5035 #else
5036 regs[rd] = DT_BSWAP_64((uint64_t)tupregs[0].dttk_value);
5037 #endif
5038 break;
5039
5040
5041 case DIF_SUBR_DIRNAME:
5042 case DIF_SUBR_BASENAME: {
5043 char *dest = (char *)mstate->dtms_scratch_ptr;
5044 uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
5045 uintptr_t src = tupregs[0].dttk_value;
5046 int i, j, len = dtrace_strlen((char *)src, size);
5047 int lastbase = -1, firstbase = -1, lastdir = -1;
5048 int start, end;
5049
5050 if (!dtrace_canload(src, len + 1, mstate, vstate)) {
5051 regs[rd] = 0;
5052 break;
5053 }
5054
5055 if (!DTRACE_INSCRATCH(mstate, size)) {
5056 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
5057 regs[rd] = 0;
5058 break;
5059 }
5060
5061 /*
5062 * The basename and dirname for a zero-length string is
5063 * defined to be "."
5064 */
5065 if (len == 0) {
5066 len = 1;
5067 src = (uintptr_t)".";
5068 }
5069
5070 /*
5071 * Start from the back of the string, moving back toward the
5072 * front until we see a character that isn't a slash. That
5073 * character is the last character in the basename.
5074 */
5075 for (i = len - 1; i >= 0; i--) {
5076 if (dtrace_load8(src + i) != '/')
5077 break;
5078 }
5079
5080 if (i >= 0)
5081 lastbase = i;
5082
5083 /*
5084 * Starting from the last character in the basename, move
5085 * towards the front until we find a slash. The character
5086 * that we processed immediately before that is the first
5087 * character in the basename.
5088 */
5089 for (; i >= 0; i--) {
5090 if (dtrace_load8(src + i) == '/')
5091 break;
5092 }
5093
5094 if (i >= 0)
5095 firstbase = i + 1;
5096
5097 /*
5098 * Now keep going until we find a non-slash character. That
5099 * character is the last character in the dirname.
5100 */
5101 for (; i >= 0; i--) {
5102 if (dtrace_load8(src + i) != '/')
5103 break;
5104 }
5105
5106 if (i >= 0)
5107 lastdir = i;
5108
5109 ASSERT(!(lastbase == -1 && firstbase != -1));
5110 ASSERT(!(firstbase == -1 && lastdir != -1));
5111
5112 if (lastbase == -1) {
5113 /*
5114 * We didn't find a non-slash character. We know that
5115 * the length is non-zero, so the whole string must be
5116 * slashes. In either the dirname or the basename
5117 * case, we return '/'.
5118 */
5119 ASSERT(firstbase == -1);
5120 firstbase = lastbase = lastdir = 0;
5121 }
5122
5123 if (firstbase == -1) {
5124 /*
5125 * The entire string consists only of a basename
5126 * component. If we're looking for dirname, we need
5127 * to change our string to be just "."; if we're
5128 * looking for a basename, we'll just set the first
5129 * character of the basename to be 0.
5130 */
5131 if (subr == DIF_SUBR_DIRNAME) {
5132 ASSERT(lastdir == -1);
5133 src = (uintptr_t)".";
5134 lastdir = 0;
5135 } else {
5136 firstbase = 0;
5137 }
5138 }
5139
5140 if (subr == DIF_SUBR_DIRNAME) {
5141 if (lastdir == -1) {
5142 /*
5143 * We know that we have a slash in the name --
5144 * or lastdir would be set to 0, above. And
5145 * because lastdir is -1, we know that this
5146 * slash must be the first character. (That
5147 * is, the full string must be of the form
5148 * "/basename".) In this case, the last
5149 * character of the directory name is 0.
5150 */
5151 lastdir = 0;
5152 }
5153
5154 start = 0;
5155 end = lastdir;
5156 } else {
5157 ASSERT(subr == DIF_SUBR_BASENAME);
5158 ASSERT(firstbase != -1 && lastbase != -1);
5159 start = firstbase;
5160 end = lastbase;
5161 }
5162
5163 for (i = start, j = 0; i <= end && (uint64_t)j < size - 1; i++, j++)
5164 dest[j] = dtrace_load8(src + i);
5165
5166 dest[j] = '\0';
5167 regs[rd] = (uintptr_t)dest;
5168 mstate->dtms_scratch_ptr += size;
5169 break;
5170 }
5171
5172 case DIF_SUBR_CLEANPATH: {
5173 char *dest = (char *)mstate->dtms_scratch_ptr, c;
5174 uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
5175 uintptr_t src = tupregs[0].dttk_value;
5176 size_t lim;
5177 size_t i = 0, j = 0;
5178
5179 if (!dtrace_strcanload(src, size, &lim, mstate, vstate)) {
5180 regs[rd] = 0;
5181 break;
5182 }
5183
5184 if (!DTRACE_INSCRATCH(mstate, size)) {
5185 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
5186 regs[rd] = 0;
5187 break;
5188 }
5189
5190 /*
5191 * Move forward, loading each character.
5192 */
5193 do {
5194 c = (i >= lim) ? '\0' : dtrace_load8(src + i++);
5195 next:
5196 if ((uint64_t)(j + 5) >= size) /* 5 = strlen("/..c\0") */
5197 break;
5198
5199 if (c != '/') {
5200 dest[j++] = c;
5201 continue;
5202 }
5203
5204 c = (i >= lim) ? '\0' : dtrace_load8(src + i++);
5205
5206 if (c == '/') {
5207 /*
5208 * We have two slashes -- we can just advance
5209 * to the next character.
5210 */
5211 goto next;
5212 }
5213
5214 if (c != '.') {
5215 /*
5216 * This is not "." and it's not ".." -- we can
5217 * just store the "/" and this character and
5218 * drive on.
5219 */
5220 dest[j++] = '/';
5221 dest[j++] = c;
5222 continue;
5223 }
5224
5225 c = (i >= lim) ? '\0' : dtrace_load8(src + i++);
5226
5227 if (c == '/') {
5228 /*
5229 * This is a "/./" component. We're not going
5230 * to store anything in the destination buffer;
5231 * we're just going to go to the next component.
5232 */
5233 goto next;
5234 }
5235
5236 if (c != '.') {
5237 /*
5238 * This is not ".." -- we can just store the
5239 * "/." and this character and continue
5240 * processing.
5241 */
5242 dest[j++] = '/';
5243 dest[j++] = '.';
5244 dest[j++] = c;
5245 continue;
5246 }
5247
5248 c = (i >= lim) ? '\0' : dtrace_load8(src + i++);
5249
5250 if (c != '/' && c != '\0') {
5251 /*
5252 * This is not ".." -- it's "..[mumble]".
5253 * We'll store the "/.." and this character
5254 * and continue processing.
5255 */
5256 dest[j++] = '/';
5257 dest[j++] = '.';
5258 dest[j++] = '.';
5259 dest[j++] = c;
5260 continue;
5261 }
5262
5263 /*
5264 * This is "/../" or "/..\0". We need to back up
5265 * our destination pointer until we find a "/".
5266 */
5267 i--;
5268 while (j != 0 && dest[--j] != '/')
5269 continue;
5270
5271 if (c == '\0')
5272 dest[++j] = '/';
5273 } while (c != '\0');
5274
5275 dest[j] = '\0';
5276 regs[rd] = (uintptr_t)dest;
5277 mstate->dtms_scratch_ptr += size;
5278 break;
5279 }
5280
5281 case DIF_SUBR_INET_NTOA:
5282 case DIF_SUBR_INET_NTOA6:
5283 case DIF_SUBR_INET_NTOP: {
5284 size_t size;
5285 int af, argi, i;
5286 char *base, *end;
5287
5288 if (subr == DIF_SUBR_INET_NTOP) {
5289 af = (int)tupregs[0].dttk_value;
5290 argi = 1;
5291 } else {
5292 af = subr == DIF_SUBR_INET_NTOA ? AF_INET: AF_INET6;
5293 argi = 0;
5294 }
5295
5296 if (af == AF_INET) {
5297 #if !defined(__APPLE__)
5298 ipaddr_t ip4;
5299 #else
5300 uint32_t ip4;
5301 #endif /* __APPLE__ */
5302 uint8_t *ptr8, val;
5303
5304 /*
5305 * Safely load the IPv4 address.
5306 */
5307 #if !defined(__APPLE__)
5308 ip4 = dtrace_load32(tupregs[argi].dttk_value);
5309 #else
5310 if (!dtrace_canload(tupregs[argi].dttk_value, sizeof(ip4),
5311 mstate, vstate)) {
5312 regs[rd] = 0;
5313 break;
5314 }
5315
5316 dtrace_bcopy(
5317 (void *)(uintptr_t)tupregs[argi].dttk_value,
5318 (void *)(uintptr_t)&ip4, sizeof (ip4));
5319 #endif /* __APPLE__ */
5320 /*
5321 * Check an IPv4 string will fit in scratch.
5322 */
5323 #if !defined(__APPLE__)
5324 size = INET_ADDRSTRLEN;
5325 #else
5326 size = MAX_IPv4_STR_LEN;
5327 #endif /* __APPLE__ */
5328 if (!DTRACE_INSCRATCH(mstate, size)) {
5329 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
5330 regs[rd] = 0;
5331 break;
5332 }
5333 base = (char *)mstate->dtms_scratch_ptr;
5334 end = (char *)mstate->dtms_scratch_ptr + size - 1;
5335
5336 /*
5337 * Stringify as a dotted decimal quad.
5338 */
5339 *end-- = '\0';
5340 ptr8 = (uint8_t *)&ip4;
5341 for (i = 3; i >= 0; i--) {
5342 val = ptr8[i];
5343
5344 if (val == 0) {
5345 *end-- = '0';
5346 } else {
5347 for (; val; val /= 10) {
5348 *end-- = '0' + (val % 10);
5349 }
5350 }
5351
5352 if (i > 0)
5353 *end-- = '.';
5354 }
5355 ASSERT(end + 1 >= base);
5356
5357 } else if (af == AF_INET6) {
5358 #if defined(__APPLE__)
5359 #define _S6_un __u6_addr
5360 #define _S6_u8 __u6_addr8
5361 #endif /* __APPLE__ */
5362 struct in6_addr ip6;
5363 int firstzero, tryzero, numzero, v6end;
5364 uint16_t val;
5365 const char digits[] = "0123456789abcdef";
5366
5367 /*
5368 * Stringify using RFC 1884 convention 2 - 16 bit
5369 * hexadecimal values with a zero-run compression.
5370 * Lower case hexadecimal digits are used.
5371 * eg, fe80::214:4fff:fe0b:76c8.
5372 * The IPv4 embedded form is returned for inet_ntop,
5373 * just the IPv4 string is returned for inet_ntoa6.
5374 */
5375
5376 if (!dtrace_canload(tupregs[argi].dttk_value,
5377 sizeof(struct in6_addr), mstate, vstate)) {
5378 regs[rd] = 0;
5379 break;
5380 }
5381
5382 /*
5383 * Safely load the IPv6 address.
5384 */
5385 dtrace_bcopy(
5386 (void *)(uintptr_t)tupregs[argi].dttk_value,
5387 (void *)(uintptr_t)&ip6, sizeof (struct in6_addr));
5388
5389 /*
5390 * Check an IPv6 string will fit in scratch.
5391 */
5392 size = INET6_ADDRSTRLEN;
5393 if (!DTRACE_INSCRATCH(mstate, size)) {
5394 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
5395 regs[rd] = 0;
5396 break;
5397 }
5398 base = (char *)mstate->dtms_scratch_ptr;
5399 end = (char *)mstate->dtms_scratch_ptr + size - 1;
5400 *end-- = '\0';
5401
5402 /*
5403 * Find the longest run of 16 bit zero values
5404 * for the single allowed zero compression - "::".
5405 */
5406 firstzero = -1;
5407 tryzero = -1;
5408 numzero = 1;
5409 for (i = 0; i < (int)sizeof (struct in6_addr); i++) {
5410 if (ip6._S6_un._S6_u8[i] == 0 &&
5411 tryzero == -1 && i % 2 == 0) {
5412 tryzero = i;
5413 continue;
5414 }
5415
5416 if (tryzero != -1 &&
5417 (ip6._S6_un._S6_u8[i] != 0 ||
5418 i == sizeof (struct in6_addr) - 1)) {
5419
5420 if (i - tryzero <= numzero) {
5421 tryzero = -1;
5422 continue;
5423 }
5424
5425 firstzero = tryzero;
5426 numzero = i - i % 2 - tryzero;
5427 tryzero = -1;
5428
5429 if (ip6._S6_un._S6_u8[i] == 0 &&
5430 i == sizeof (struct in6_addr) - 1)
5431 numzero += 2;
5432 }
5433 }
5434 ASSERT(firstzero + numzero <= (int)sizeof (struct in6_addr));
5435
5436 /*
5437 * Check for an IPv4 embedded address.
5438 */
5439 v6end = sizeof (struct in6_addr) - 2;
5440 if (IN6_IS_ADDR_V4MAPPED(&ip6) ||
5441 IN6_IS_ADDR_V4COMPAT(&ip6)) {
5442 for (i = sizeof (struct in6_addr) - 1;
5443 i >= (int)DTRACE_V4MAPPED_OFFSET; i--) {
5444 ASSERT(end >= base);
5445
5446 val = ip6._S6_un._S6_u8[i];
5447
5448 if (val == 0) {
5449 *end-- = '0';
5450 } else {
5451 for (; val; val /= 10) {
5452 *end-- = '0' + val % 10;
5453 }
5454 }
5455
5456 if (i > (int)DTRACE_V4MAPPED_OFFSET)
5457 *end-- = '.';
5458 }
5459
5460 if (subr == DIF_SUBR_INET_NTOA6)
5461 goto inetout;
5462
5463 /*
5464 * Set v6end to skip the IPv4 address that
5465 * we have already stringified.
5466 */
5467 v6end = 10;
5468 }
5469
5470 /*
5471 * Build the IPv6 string by working through the
5472 * address in reverse.
5473 */
5474 for (i = v6end; i >= 0; i -= 2) {
5475 ASSERT(end >= base);
5476
5477 if (i == firstzero + numzero - 2) {
5478 *end-- = ':';
5479 *end-- = ':';
5480 i -= numzero - 2;
5481 continue;
5482 }
5483
5484 if (i < 14 && i != firstzero - 2)
5485 *end-- = ':';
5486
5487 val = (ip6._S6_un._S6_u8[i] << 8) +
5488 ip6._S6_un._S6_u8[i + 1];
5489
5490 if (val == 0) {
5491 *end-- = '0';
5492 } else {
5493 for (; val; val /= 16) {
5494 *end-- = digits[val % 16];
5495 }
5496 }
5497 }
5498 ASSERT(end + 1 >= base);
5499
5500 #if defined(__APPLE__)
5501 #undef _S6_un
5502 #undef _S6_u8
5503 #endif /* __APPLE__ */
5504 } else {
5505 /*
5506 * The user didn't use AH_INET or AH_INET6.
5507 */
5508 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
5509 regs[rd] = 0;
5510 break;
5511 }
5512
5513 inetout: regs[rd] = (uintptr_t)end + 1;
5514 mstate->dtms_scratch_ptr += size;
5515 break;
5516 }
5517
5518 case DIF_SUBR_JSON: {
5519 uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
5520 uintptr_t json = tupregs[0].dttk_value;
5521 size_t jsonlen = dtrace_strlen((char *)json, size);
5522 uintptr_t elem = tupregs[1].dttk_value;
5523 size_t elemlen = dtrace_strlen((char *)elem, size);
5524
5525 char *dest = (char *)mstate->dtms_scratch_ptr;
5526 char *elemlist = (char *)mstate->dtms_scratch_ptr + jsonlen + 1;
5527 char *ee = elemlist;
5528 int nelems = 1;
5529 uintptr_t cur;
5530
5531 if (!dtrace_canload(json, jsonlen + 1, mstate, vstate) ||
5532 !dtrace_canload(elem, elemlen + 1, mstate, vstate)) {
5533 regs[rd] = 0;
5534 break;
5535 }
5536
5537 if (!DTRACE_INSCRATCH(mstate, jsonlen + 1 + elemlen + 1)) {
5538 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
5539 regs[rd] = 0;
5540 break;
5541 }
5542
5543 /*
5544 * Read the element selector and split it up into a packed list
5545 * of strings.
5546 */
5547 for (cur = elem; cur < elem + elemlen; cur++) {
5548 char cc = dtrace_load8(cur);
5549
5550 if (cur == elem && cc == '[') {
5551 /*
5552 * If the first element selector key is
5553 * actually an array index then ignore the
5554 * bracket.
5555 */
5556 continue;
5557 }
5558
5559 if (cc == ']')
5560 continue;
5561
5562 if (cc == '.' || cc == '[') {
5563 nelems++;
5564 cc = '\0';
5565 }
5566
5567 *ee++ = cc;
5568 }
5569 *ee++ = '\0';
5570
5571 if ((regs[rd] = (uintptr_t)dtrace_json(size, json, elemlist,
5572 nelems, dest)) != 0)
5573 mstate->dtms_scratch_ptr += jsonlen + 1;
5574 break;
5575 }
5576
5577 case DIF_SUBR_TOUPPER:
5578 case DIF_SUBR_TOLOWER: {
5579 uintptr_t src = tupregs[0].dttk_value;
5580 char *dest = (char *)mstate->dtms_scratch_ptr;
5581 char lower, upper, base, c;
5582 uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
5583 size_t len = dtrace_strlen((char*) src, size);
5584 size_t i = 0;
5585
5586 lower = (subr == DIF_SUBR_TOUPPER) ? 'a' : 'A';
5587 upper = (subr == DIF_SUBR_TOUPPER) ? 'z' : 'Z';
5588 base = (subr == DIF_SUBR_TOUPPER) ? 'A' : 'a';
5589
5590 if (!dtrace_canload(src, len + 1, mstate, vstate)) {
5591 regs[rd] = 0;
5592 break;
5593 }
5594
5595 if (!DTRACE_INSCRATCH(mstate, size)) {
5596 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
5597 regs[rd] = 0;
5598 break;
5599 }
5600
5601 for (i = 0; i < size - 1; ++i) {
5602 if ((c = dtrace_load8(src + i)) == '\0')
5603 break;
5604 if (c >= lower && c <= upper)
5605 c = base + (c - lower);
5606 dest[i] = c;
5607 }
5608
5609 ASSERT(i < size);
5610
5611 dest[i] = '\0';
5612 regs[rd] = (uintptr_t) dest;
5613 mstate->dtms_scratch_ptr += size;
5614
5615 break;
5616 }
5617
5618 case DIF_SUBR_STRIP:
5619 if (!dtrace_is_valid_ptrauth_key(tupregs[1].dttk_value)) {
5620 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
5621 break;
5622 }
5623 regs[rd] = (uint64_t)dtrace_ptrauth_strip(
5624 (void*)tupregs[0].dttk_value, tupregs[1].dttk_value);
5625 break;
5626
5627 #if defined(__APPLE__)
5628 case DIF_SUBR_VM_KERNEL_ADDRPERM: {
5629 if (!dtrace_priv_kernel(state)) {
5630 regs[rd] = 0;
5631 } else {
5632 regs[rd] = VM_KERNEL_ADDRPERM((vm_offset_t) tupregs[0].dttk_value);
5633 }
5634
5635 break;
5636 }
5637
5638 case DIF_SUBR_KDEBUG_TRACE: {
5639 uint32_t debugid;
5640 uintptr_t args[4] = {0};
5641 int i;
5642
5643 if (nargs < 2 || nargs > 5) {
5644 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
5645 break;
5646 }
5647
5648 if (dtrace_destructive_disallow ||
5649 !dtrace_priv_kernel_destructive(state)) {
5650 return;
5651 }
5652
5653 debugid = tupregs[0].dttk_value;
5654 for (i = 0; i < nargs - 1; i++)
5655 args[i] = tupregs[i + 1].dttk_value;
5656
5657 kernel_debug(debugid, args[0], args[1], args[2], args[3], 0);
5658
5659 break;
5660 }
5661
5662 case DIF_SUBR_KDEBUG_TRACE_STRING: {
5663 if (nargs != 3) {
5664 break;
5665 }
5666
5667 if (dtrace_destructive_disallow ||
5668 !dtrace_priv_kernel_destructive(state)) {
5669 return;
5670 }
5671
5672 uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
5673 uint32_t debugid = tupregs[0].dttk_value;
5674 uint64_t str_id = tupregs[1].dttk_value;
5675 uintptr_t src = tupregs[2].dttk_value;
5676 size_t lim;
5677 char buf[size];
5678 char* str = NULL;
5679
5680 if (src != (uintptr_t)0) {
5681 str = buf;
5682 if (!dtrace_strcanload(src, size, &lim, mstate, vstate)) {
5683 break;
5684 }
5685 dtrace_strcpy((void*)src, buf, size);
5686 }
5687
5688 (void)kernel_debug_string(debugid, &str_id, str);
5689 regs[rd] = str_id;
5690
5691 break;
5692 }
5693
5694 case DIF_SUBR_MTONS:
5695 absolutetime_to_nanoseconds(tupregs[0].dttk_value, ®s[rd]);
5696
5697 break;
5698 case DIF_SUBR_PHYSMEM_READ: {
5699 #if DEBUG || DEVELOPMENT
5700 if (dtrace_destructive_disallow ||
5701 !dtrace_priv_kernel_destructive(state)) {
5702 return;
5703 }
5704 regs[rd] = dtrace_physmem_read(tupregs[0].dttk_value,
5705 tupregs[1].dttk_value);
5706 #else
5707 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
5708 #endif /* DEBUG || DEVELOPMENT */
5709 break;
5710 }
5711 case DIF_SUBR_PHYSMEM_WRITE: {
5712 #if DEBUG || DEVELOPMENT
5713 if (dtrace_destructive_disallow ||
5714 !dtrace_priv_kernel_destructive(state)) {
5715 return;
5716 }
5717
5718 dtrace_physmem_write(tupregs[0].dttk_value,
5719 tupregs[1].dttk_value, (size_t)tupregs[2].dttk_value);
5720 #else
5721 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
5722 #endif /* DEBUG || DEVELOPMENT */
5723 break;
5724 }
5725
5726 case DIF_SUBR_KVTOPHYS: {
5727 #if DEBUG || DEVELOPMENT
5728 regs[rd] = kvtophys(tupregs[0].dttk_value);
5729 #else
5730 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
5731 #endif /* DEBUG || DEVELOPMENT */
5732 break;
5733 }
5734
5735 case DIF_SUBR_LIVEDUMP: {
5736 #if DEBUG || DEVELOPMENT
5737 if (dtrace_destructive_disallow ||
5738 !dtrace_priv_kernel_destructive(state)) {
5739 break;
5740 }
5741
5742 /* For the moment, there is only one type of livedump. */
5743 if (nargs != 1 || tupregs[0].dttk_value != 0) {
5744 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
5745 break;
5746 }
5747
5748 char *dest = (char *)mstate->dtms_scratch_ptr;
5749 uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
5750
5751 if (!DTRACE_INSCRATCH(mstate, size)) {
5752 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
5753 regs[rd] = 0;
5754 break;
5755 }
5756
5757 dtrace_livedump(dest, size);
5758 regs[rd] = (uintptr_t) dest;
5759 mstate->dtms_scratch_ptr += strlen(dest) + 1;
5760 #else
5761 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
5762 #endif /* DEBUG || DEVELOPMENT */
5763 break;
5764 }
5765 #endif /* defined(__APPLE__) */
5766
5767 }
5768 }
5769
5770 /*
5771 * Emulate the execution of DTrace IR instructions specified by the given
5772 * DIF object. This function is deliberately void of assertions as all of
5773 * the necessary checks are handled by a call to dtrace_difo_validate().
5774 */
5775 static uint64_t
dtrace_dif_emulate(dtrace_difo_t * difo,dtrace_mstate_t * mstate,dtrace_vstate_t * vstate,dtrace_state_t * state)5776 dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate,
5777 dtrace_vstate_t *vstate, dtrace_state_t *state)
5778 {
5779 const dif_instr_t *text = difo->dtdo_buf;
5780 const uint_t textlen = difo->dtdo_len;
5781 const char *strtab = difo->dtdo_strtab;
5782 const uint64_t *inttab = difo->dtdo_inttab;
5783
5784 uint64_t rval = 0;
5785 dtrace_statvar_t *svar;
5786 dtrace_dstate_t *dstate = &vstate->dtvs_dynvars;
5787 dtrace_difv_t *v;
5788 volatile uint16_t *flags = &cpu_core[CPU->cpu_id].cpuc_dtrace_flags;
5789 volatile uint64_t *illval = &cpu_core[CPU->cpu_id].cpuc_dtrace_illval;
5790
5791 dtrace_key_t tupregs[DIF_DTR_NREGS + 2]; /* +2 for thread and id */
5792 uint64_t regs[DIF_DIR_NREGS];
5793 uint64_t *tmp;
5794
5795 uint8_t cc_n = 0, cc_z = 0, cc_v = 0, cc_c = 0;
5796 int64_t cc_r;
5797 uint_t pc = 0, id, opc = 0;
5798 uint8_t ttop = 0;
5799 dif_instr_t instr;
5800 uint_t r1, r2, rd;
5801
5802 /*
5803 * We stash the current DIF object into the machine state: we need it
5804 * for subsequent access checking.
5805 */
5806 mstate->dtms_difo = difo;
5807
5808 regs[DIF_REG_R0] = 0; /* %r0 is fixed at zero */
5809
5810 while (pc < textlen && !(*flags & CPU_DTRACE_FAULT)) {
5811 opc = pc;
5812
5813 instr = text[pc++];
5814 r1 = DIF_INSTR_R1(instr);
5815 r2 = DIF_INSTR_R2(instr);
5816 rd = DIF_INSTR_RD(instr);
5817
5818 switch (DIF_INSTR_OP(instr)) {
5819 case DIF_OP_OR:
5820 regs[rd] = regs[r1] | regs[r2];
5821 break;
5822 case DIF_OP_XOR:
5823 regs[rd] = regs[r1] ^ regs[r2];
5824 break;
5825 case DIF_OP_AND:
5826 regs[rd] = regs[r1] & regs[r2];
5827 break;
5828 case DIF_OP_SLL:
5829 regs[rd] = regs[r1] << regs[r2];
5830 break;
5831 case DIF_OP_SRL:
5832 regs[rd] = regs[r1] >> regs[r2];
5833 break;
5834 case DIF_OP_SUB:
5835 regs[rd] = regs[r1] - regs[r2];
5836 break;
5837 case DIF_OP_ADD:
5838 regs[rd] = regs[r1] + regs[r2];
5839 break;
5840 case DIF_OP_MUL:
5841 regs[rd] = regs[r1] * regs[r2];
5842 break;
5843 case DIF_OP_SDIV:
5844 if (regs[r2] == 0) {
5845 regs[rd] = 0;
5846 *flags |= CPU_DTRACE_DIVZERO;
5847 } else {
5848 regs[rd] = (int64_t)regs[r1] /
5849 (int64_t)regs[r2];
5850 }
5851 break;
5852
5853 case DIF_OP_UDIV:
5854 if (regs[r2] == 0) {
5855 regs[rd] = 0;
5856 *flags |= CPU_DTRACE_DIVZERO;
5857 } else {
5858 regs[rd] = regs[r1] / regs[r2];
5859 }
5860 break;
5861
5862 case DIF_OP_SREM:
5863 if (regs[r2] == 0) {
5864 regs[rd] = 0;
5865 *flags |= CPU_DTRACE_DIVZERO;
5866 } else {
5867 regs[rd] = (int64_t)regs[r1] %
5868 (int64_t)regs[r2];
5869 }
5870 break;
5871
5872 case DIF_OP_UREM:
5873 if (regs[r2] == 0) {
5874 regs[rd] = 0;
5875 *flags |= CPU_DTRACE_DIVZERO;
5876 } else {
5877 regs[rd] = regs[r1] % regs[r2];
5878 }
5879 break;
5880
5881 case DIF_OP_NOT:
5882 regs[rd] = ~regs[r1];
5883 break;
5884 case DIF_OP_MOV:
5885 regs[rd] = regs[r1];
5886 break;
5887 case DIF_OP_CMP:
5888 cc_r = regs[r1] - regs[r2];
5889 cc_n = cc_r < 0;
5890 cc_z = cc_r == 0;
5891 cc_v = 0;
5892 cc_c = regs[r1] < regs[r2];
5893 break;
5894 case DIF_OP_TST:
5895 cc_n = cc_v = cc_c = 0;
5896 cc_z = regs[r1] == 0;
5897 break;
5898 case DIF_OP_BA:
5899 pc = DIF_INSTR_LABEL(instr);
5900 break;
5901 case DIF_OP_BE:
5902 if (cc_z)
5903 pc = DIF_INSTR_LABEL(instr);
5904 break;
5905 case DIF_OP_BNE:
5906 if (cc_z == 0)
5907 pc = DIF_INSTR_LABEL(instr);
5908 break;
5909 case DIF_OP_BG:
5910 if ((cc_z | (cc_n ^ cc_v)) == 0)
5911 pc = DIF_INSTR_LABEL(instr);
5912 break;
5913 case DIF_OP_BGU:
5914 if ((cc_c | cc_z) == 0)
5915 pc = DIF_INSTR_LABEL(instr);
5916 break;
5917 case DIF_OP_BGE:
5918 if ((cc_n ^ cc_v) == 0)
5919 pc = DIF_INSTR_LABEL(instr);
5920 break;
5921 case DIF_OP_BGEU:
5922 if (cc_c == 0)
5923 pc = DIF_INSTR_LABEL(instr);
5924 break;
5925 case DIF_OP_BL:
5926 if (cc_n ^ cc_v)
5927 pc = DIF_INSTR_LABEL(instr);
5928 break;
5929 case DIF_OP_BLU:
5930 if (cc_c)
5931 pc = DIF_INSTR_LABEL(instr);
5932 break;
5933 case DIF_OP_BLE:
5934 if (cc_z | (cc_n ^ cc_v))
5935 pc = DIF_INSTR_LABEL(instr);
5936 break;
5937 case DIF_OP_BLEU:
5938 if (cc_c | cc_z)
5939 pc = DIF_INSTR_LABEL(instr);
5940 break;
5941 case DIF_OP_RLDSB:
5942 if (!dtrace_canstore(regs[r1], 1, mstate, vstate)) {
5943 *flags |= CPU_DTRACE_KPRIV;
5944 *illval = regs[r1];
5945 break;
5946 }
5947 OS_FALLTHROUGH;
5948 case DIF_OP_LDSB:
5949 regs[rd] = (int8_t)dtrace_load8(regs[r1]);
5950 break;
5951 case DIF_OP_RLDSH:
5952 if (!dtrace_canstore(regs[r1], 2, mstate, vstate)) {
5953 *flags |= CPU_DTRACE_KPRIV;
5954 *illval = regs[r1];
5955 break;
5956 }
5957 OS_FALLTHROUGH;
5958 case DIF_OP_LDSH:
5959 regs[rd] = (int16_t)dtrace_load16(regs[r1]);
5960 break;
5961 case DIF_OP_RLDSW:
5962 if (!dtrace_canstore(regs[r1], 4, mstate, vstate)) {
5963 *flags |= CPU_DTRACE_KPRIV;
5964 *illval = regs[r1];
5965 break;
5966 }
5967 OS_FALLTHROUGH;
5968 case DIF_OP_LDSW:
5969 regs[rd] = (int32_t)dtrace_load32(regs[r1]);
5970 break;
5971 case DIF_OP_RLDUB:
5972 if (!dtrace_canstore(regs[r1], 1, mstate, vstate)) {
5973 *flags |= CPU_DTRACE_KPRIV;
5974 *illval = regs[r1];
5975 break;
5976 }
5977 OS_FALLTHROUGH;
5978 case DIF_OP_LDUB:
5979 regs[rd] = dtrace_load8(regs[r1]);
5980 break;
5981 case DIF_OP_RLDUH:
5982 if (!dtrace_canstore(regs[r1], 2, mstate, vstate)) {
5983 *flags |= CPU_DTRACE_KPRIV;
5984 *illval = regs[r1];
5985 break;
5986 }
5987 OS_FALLTHROUGH;
5988 case DIF_OP_LDUH:
5989 regs[rd] = dtrace_load16(regs[r1]);
5990 break;
5991 case DIF_OP_RLDUW:
5992 if (!dtrace_canstore(regs[r1], 4, mstate, vstate)) {
5993 *flags |= CPU_DTRACE_KPRIV;
5994 *illval = regs[r1];
5995 break;
5996 }
5997 OS_FALLTHROUGH;
5998 case DIF_OP_LDUW:
5999 regs[rd] = dtrace_load32(regs[r1]);
6000 break;
6001 case DIF_OP_RLDX:
6002 if (!dtrace_canstore(regs[r1], 8, mstate, vstate)) {
6003 *flags |= CPU_DTRACE_KPRIV;
6004 *illval = regs[r1];
6005 break;
6006 }
6007 OS_FALLTHROUGH;
6008 case DIF_OP_LDX:
6009 regs[rd] = dtrace_load64(regs[r1]);
6010 break;
6011 /*
6012 * Darwin 32-bit kernel may fetch from 64-bit user.
6013 * Do not cast regs to uintptr_t
6014 * DIF_OP_ULDSB,DIF_OP_ULDSH, DIF_OP_ULDSW, DIF_OP_ULDUB
6015 * DIF_OP_ULDUH, DIF_OP_ULDUW, DIF_OP_ULDX
6016 */
6017 case DIF_OP_ULDSB:
6018 regs[rd] = (int8_t)
6019 dtrace_fuword8(regs[r1]);
6020 break;
6021 case DIF_OP_ULDSH:
6022 regs[rd] = (int16_t)
6023 dtrace_fuword16(regs[r1]);
6024 break;
6025 case DIF_OP_ULDSW:
6026 regs[rd] = (int32_t)
6027 dtrace_fuword32(regs[r1]);
6028 break;
6029 case DIF_OP_ULDUB:
6030 regs[rd] =
6031 dtrace_fuword8(regs[r1]);
6032 break;
6033 case DIF_OP_ULDUH:
6034 regs[rd] =
6035 dtrace_fuword16(regs[r1]);
6036 break;
6037 case DIF_OP_ULDUW:
6038 regs[rd] =
6039 dtrace_fuword32(regs[r1]);
6040 break;
6041 case DIF_OP_ULDX:
6042 regs[rd] =
6043 dtrace_fuword64(regs[r1]);
6044 break;
6045 case DIF_OP_RET:
6046 rval = regs[rd];
6047 pc = textlen;
6048 break;
6049 case DIF_OP_NOP:
6050 break;
6051 case DIF_OP_SETX:
6052 regs[rd] = inttab[DIF_INSTR_INTEGER(instr)];
6053 break;
6054 case DIF_OP_SETS:
6055 regs[rd] = (uint64_t)(uintptr_t)
6056 (strtab + DIF_INSTR_STRING(instr));
6057 break;
6058 case DIF_OP_SCMP: {
6059 size_t sz = state->dts_options[DTRACEOPT_STRSIZE];
6060 uintptr_t s1 = regs[r1];
6061 uintptr_t s2 = regs[r2];
6062 size_t lim1 = sz, lim2 = sz;
6063
6064 if (s1 != 0 &&
6065 !dtrace_strcanload(s1, sz, &lim1, mstate, vstate))
6066 break;
6067 if (s2 != 0 &&
6068 !dtrace_strcanload(s2, sz, &lim2, mstate, vstate))
6069 break;
6070
6071 cc_r = dtrace_strncmp((char *)s1, (char *)s2,
6072 MIN(lim1, lim2));
6073
6074 cc_n = cc_r < 0;
6075 cc_z = cc_r == 0;
6076 cc_v = cc_c = 0;
6077 break;
6078 }
6079 case DIF_OP_LDGA:
6080 regs[rd] = dtrace_dif_variable(mstate, state,
6081 r1, regs[r2]);
6082 break;
6083 case DIF_OP_LDGS:
6084 id = DIF_INSTR_VAR(instr);
6085
6086 if (id >= DIF_VAR_OTHER_UBASE) {
6087 uintptr_t a;
6088
6089 id -= DIF_VAR_OTHER_UBASE;
6090 svar = vstate->dtvs_globals[id];
6091 ASSERT(svar != NULL);
6092 v = &svar->dtsv_var;
6093
6094 if (!(v->dtdv_type.dtdt_flags & DIF_TF_BYREF)) {
6095 regs[rd] = svar->dtsv_data;
6096 break;
6097 }
6098
6099 a = (uintptr_t)svar->dtsv_data;
6100
6101 if (*(uint8_t *)a == UINT8_MAX) {
6102 /*
6103 * If the 0th byte is set to UINT8_MAX
6104 * then this is to be treated as a
6105 * reference to a NULL variable.
6106 */
6107 regs[rd] = 0;
6108 } else {
6109 regs[rd] = a + sizeof (uint64_t);
6110 }
6111
6112 break;
6113 }
6114
6115 regs[rd] = dtrace_dif_variable(mstate, state, id, 0);
6116 break;
6117
6118 case DIF_OP_STGS:
6119 id = DIF_INSTR_VAR(instr);
6120
6121 ASSERT(id >= DIF_VAR_OTHER_UBASE);
6122 id -= DIF_VAR_OTHER_UBASE;
6123
6124 VERIFY(id < (uint_t)vstate->dtvs_nglobals);
6125 svar = vstate->dtvs_globals[id];
6126 ASSERT(svar != NULL);
6127 v = &svar->dtsv_var;
6128
6129 if (v->dtdv_type.dtdt_flags & DIF_TF_BYREF) {
6130 uintptr_t a = (uintptr_t)svar->dtsv_data;
6131 size_t lim = 0;
6132
6133 ASSERT(a != 0);
6134 ASSERT(svar->dtsv_size != 0);
6135
6136 if (regs[rd] == 0) {
6137 *(uint8_t *)a = UINT8_MAX;
6138 break;
6139 } else {
6140 *(uint8_t *)a = 0;
6141 a += sizeof (uint64_t);
6142 }
6143 if (!dtrace_vcanload(
6144 (void *)(uintptr_t)regs[rd], &v->dtdv_type,
6145 &lim, mstate, vstate))
6146 break;
6147
6148 dtrace_vcopy((void *)(uintptr_t)regs[rd],
6149 (void *)a, &v->dtdv_type, lim);
6150 break;
6151 }
6152
6153 svar->dtsv_data = regs[rd];
6154 break;
6155
6156 case DIF_OP_LDTA:
6157 /*
6158 * There are no DTrace built-in thread-local arrays at
6159 * present. This opcode is saved for future work.
6160 */
6161 *flags |= CPU_DTRACE_ILLOP;
6162 regs[rd] = 0;
6163 break;
6164
6165 case DIF_OP_LDLS:
6166 id = DIF_INSTR_VAR(instr);
6167
6168 if (id < DIF_VAR_OTHER_UBASE) {
6169 /*
6170 * For now, this has no meaning.
6171 */
6172 regs[rd] = 0;
6173 break;
6174 }
6175
6176 id -= DIF_VAR_OTHER_UBASE;
6177
6178 ASSERT(id < (uint_t)vstate->dtvs_nlocals);
6179 ASSERT(vstate->dtvs_locals != NULL);
6180 svar = vstate->dtvs_locals[id];
6181 ASSERT(svar != NULL);
6182 v = &svar->dtsv_var;
6183
6184 if (v->dtdv_type.dtdt_flags & DIF_TF_BYREF) {
6185 uintptr_t a = (uintptr_t)svar->dtsv_data;
6186 size_t sz = v->dtdv_type.dtdt_size;
6187
6188 sz += sizeof (uint64_t);
6189 ASSERT(svar->dtsv_size == (int)NCPU * sz);
6190 a += CPU->cpu_id * sz;
6191
6192 if (*(uint8_t *)a == UINT8_MAX) {
6193 /*
6194 * If the 0th byte is set to UINT8_MAX
6195 * then this is to be treated as a
6196 * reference to a NULL variable.
6197 */
6198 regs[rd] = 0;
6199 } else {
6200 regs[rd] = a + sizeof (uint64_t);
6201 }
6202
6203 break;
6204 }
6205
6206 ASSERT(svar->dtsv_size == (int)NCPU * sizeof (uint64_t));
6207 tmp = (uint64_t *)(uintptr_t)svar->dtsv_data;
6208 regs[rd] = tmp[CPU->cpu_id];
6209 break;
6210
6211 case DIF_OP_STLS:
6212 id = DIF_INSTR_VAR(instr);
6213
6214 ASSERT(id >= DIF_VAR_OTHER_UBASE);
6215 id -= DIF_VAR_OTHER_UBASE;
6216 VERIFY(id < (uint_t)vstate->dtvs_nlocals);
6217 ASSERT(vstate->dtvs_locals != NULL);
6218 svar = vstate->dtvs_locals[id];
6219 ASSERT(svar != NULL);
6220 v = &svar->dtsv_var;
6221
6222 if (v->dtdv_type.dtdt_flags & DIF_TF_BYREF) {
6223 uintptr_t a = (uintptr_t)svar->dtsv_data;
6224 size_t sz = v->dtdv_type.dtdt_size;
6225 size_t lim = 0;
6226
6227 sz += sizeof (uint64_t);
6228 ASSERT(svar->dtsv_size == (int)NCPU * sz);
6229 a += CPU->cpu_id * sz;
6230
6231 if (regs[rd] == 0) {
6232 *(uint8_t *)a = UINT8_MAX;
6233 break;
6234 } else {
6235 *(uint8_t *)a = 0;
6236 a += sizeof (uint64_t);
6237 }
6238
6239 if (!dtrace_vcanload(
6240 (void *)(uintptr_t)regs[rd], &v->dtdv_type,
6241 &lim, mstate, vstate))
6242 break;
6243
6244 dtrace_vcopy((void *)(uintptr_t)regs[rd],
6245 (void *)a, &v->dtdv_type, lim);
6246 break;
6247 }
6248
6249 ASSERT(svar->dtsv_size == (int)NCPU * sizeof (uint64_t));
6250 tmp = (uint64_t *)(uintptr_t)svar->dtsv_data;
6251 tmp[CPU->cpu_id] = regs[rd];
6252 break;
6253
6254 case DIF_OP_LDTS: {
6255 dtrace_dynvar_t *dvar;
6256 dtrace_key_t *key;
6257
6258 id = DIF_INSTR_VAR(instr);
6259 ASSERT(id >= DIF_VAR_OTHER_UBASE);
6260 id -= DIF_VAR_OTHER_UBASE;
6261 v = &vstate->dtvs_tlocals[id];
6262
6263 key = &tupregs[DIF_DTR_NREGS];
6264 key[0].dttk_value = (uint64_t)id;
6265 key[0].dttk_size = 0;
6266 DTRACE_TLS_THRKEY(key[1].dttk_value);
6267 key[1].dttk_size = 0;
6268
6269 dvar = dtrace_dynvar(dstate, 2, key,
6270 sizeof (uint64_t), DTRACE_DYNVAR_NOALLOC,
6271 mstate, vstate);
6272
6273 if (dvar == NULL) {
6274 regs[rd] = 0;
6275 break;
6276 }
6277
6278 if (v->dtdv_type.dtdt_flags & DIF_TF_BYREF) {
6279 regs[rd] = (uint64_t)(uintptr_t)dvar->dtdv_data;
6280 } else {
6281 regs[rd] = *((uint64_t *)dvar->dtdv_data);
6282 }
6283
6284 break;
6285 }
6286
6287 case DIF_OP_STTS: {
6288 dtrace_dynvar_t *dvar;
6289 dtrace_key_t *key;
6290
6291 id = DIF_INSTR_VAR(instr);
6292 ASSERT(id >= DIF_VAR_OTHER_UBASE);
6293 id -= DIF_VAR_OTHER_UBASE;
6294 VERIFY(id < (uint_t)vstate->dtvs_ntlocals);
6295
6296 key = &tupregs[DIF_DTR_NREGS];
6297 key[0].dttk_value = (uint64_t)id;
6298 key[0].dttk_size = 0;
6299 DTRACE_TLS_THRKEY(key[1].dttk_value);
6300 key[1].dttk_size = 0;
6301 v = &vstate->dtvs_tlocals[id];
6302
6303 dvar = dtrace_dynvar(dstate, 2, key,
6304 v->dtdv_type.dtdt_size > sizeof (uint64_t) ?
6305 v->dtdv_type.dtdt_size : sizeof (uint64_t),
6306 regs[rd] ? DTRACE_DYNVAR_ALLOC :
6307 DTRACE_DYNVAR_DEALLOC, mstate, vstate);
6308
6309 /*
6310 * Given that we're storing to thread-local data,
6311 * we need to flush our predicate cache.
6312 */
6313 dtrace_set_thread_predcache(current_thread(), 0);
6314
6315 if (dvar == NULL)
6316 break;
6317
6318 if (v->dtdv_type.dtdt_flags & DIF_TF_BYREF) {
6319 size_t lim = 0;
6320
6321 if (!dtrace_vcanload(
6322 (void *)(uintptr_t)regs[rd],
6323 &v->dtdv_type, &lim, mstate, vstate))
6324 break;
6325
6326 dtrace_vcopy((void *)(uintptr_t)regs[rd],
6327 dvar->dtdv_data, &v->dtdv_type, lim);
6328 } else {
6329 *((uint64_t *)dvar->dtdv_data) = regs[rd];
6330 }
6331
6332 break;
6333 }
6334
6335 case DIF_OP_SRA:
6336 regs[rd] = (int64_t)regs[r1] >> regs[r2];
6337 break;
6338
6339 case DIF_OP_CALL:
6340 dtrace_dif_subr(DIF_INSTR_SUBR(instr), rd,
6341 regs, tupregs, ttop, mstate, state);
6342 break;
6343
6344 case DIF_OP_PUSHTR:
6345 if (ttop == DIF_DTR_NREGS) {
6346 *flags |= CPU_DTRACE_TUPOFLOW;
6347 break;
6348 }
6349
6350 if (r1 == DIF_TYPE_STRING) {
6351 /*
6352 * If this is a string type and the size is 0,
6353 * we'll use the system-wide default string
6354 * size. Note that we are _not_ looking at
6355 * the value of the DTRACEOPT_STRSIZE option;
6356 * had this been set, we would expect to have
6357 * a non-zero size value in the "pushtr".
6358 */
6359 tupregs[ttop].dttk_size =
6360 dtrace_strlen((char *)(uintptr_t)regs[rd],
6361 regs[r2] ? regs[r2] :
6362 dtrace_strsize_default) + 1;
6363 } else {
6364 if (regs[r2] > LONG_MAX) {
6365 *flags |= CPU_DTRACE_ILLOP;
6366 break;
6367 }
6368 tupregs[ttop].dttk_size = regs[r2];
6369 }
6370
6371 tupregs[ttop++].dttk_value = regs[rd];
6372 break;
6373
6374 case DIF_OP_PUSHTV:
6375 if (ttop == DIF_DTR_NREGS) {
6376 *flags |= CPU_DTRACE_TUPOFLOW;
6377 break;
6378 }
6379
6380 tupregs[ttop].dttk_value = regs[rd];
6381 tupregs[ttop++].dttk_size = 0;
6382 break;
6383
6384 case DIF_OP_POPTS:
6385 if (ttop != 0)
6386 ttop--;
6387 break;
6388
6389 case DIF_OP_FLUSHTS:
6390 ttop = 0;
6391 break;
6392
6393 case DIF_OP_LDGAA:
6394 case DIF_OP_LDTAA: {
6395 dtrace_dynvar_t *dvar;
6396 dtrace_key_t *key = tupregs;
6397 uint_t nkeys = ttop;
6398
6399 id = DIF_INSTR_VAR(instr);
6400 ASSERT(id >= DIF_VAR_OTHER_UBASE);
6401 id -= DIF_VAR_OTHER_UBASE;
6402
6403 key[nkeys].dttk_value = (uint64_t)id;
6404 key[nkeys++].dttk_size = 0;
6405
6406 if (DIF_INSTR_OP(instr) == DIF_OP_LDTAA) {
6407 DTRACE_TLS_THRKEY(key[nkeys].dttk_value);
6408 key[nkeys++].dttk_size = 0;
6409 VERIFY(id < (uint_t)vstate->dtvs_ntlocals);
6410 v = &vstate->dtvs_tlocals[id];
6411 } else {
6412 VERIFY(id < (uint_t)vstate->dtvs_nglobals);
6413 v = &vstate->dtvs_globals[id]->dtsv_var;
6414 }
6415
6416 dvar = dtrace_dynvar(dstate, nkeys, key,
6417 v->dtdv_type.dtdt_size > sizeof (uint64_t) ?
6418 v->dtdv_type.dtdt_size : sizeof (uint64_t),
6419 DTRACE_DYNVAR_NOALLOC, mstate, vstate);
6420
6421 if (dvar == NULL) {
6422 regs[rd] = 0;
6423 break;
6424 }
6425
6426 if (v->dtdv_type.dtdt_flags & DIF_TF_BYREF) {
6427 regs[rd] = (uint64_t)(uintptr_t)dvar->dtdv_data;
6428 } else {
6429 regs[rd] = *((uint64_t *)dvar->dtdv_data);
6430 }
6431
6432 break;
6433 }
6434
6435 case DIF_OP_STGAA:
6436 case DIF_OP_STTAA: {
6437 dtrace_dynvar_t *dvar;
6438 dtrace_key_t *key = tupregs;
6439 uint_t nkeys = ttop;
6440
6441 id = DIF_INSTR_VAR(instr);
6442 ASSERT(id >= DIF_VAR_OTHER_UBASE);
6443 id -= DIF_VAR_OTHER_UBASE;
6444
6445 key[nkeys].dttk_value = (uint64_t)id;
6446 key[nkeys++].dttk_size = 0;
6447
6448 if (DIF_INSTR_OP(instr) == DIF_OP_STTAA) {
6449 DTRACE_TLS_THRKEY(key[nkeys].dttk_value);
6450 key[nkeys++].dttk_size = 0;
6451 VERIFY(id < (uint_t)vstate->dtvs_ntlocals);
6452 v = &vstate->dtvs_tlocals[id];
6453 } else {
6454 VERIFY(id < (uint_t)vstate->dtvs_nglobals);
6455 v = &vstate->dtvs_globals[id]->dtsv_var;
6456 }
6457
6458 dvar = dtrace_dynvar(dstate, nkeys, key,
6459 v->dtdv_type.dtdt_size > sizeof (uint64_t) ?
6460 v->dtdv_type.dtdt_size : sizeof (uint64_t),
6461 regs[rd] ? DTRACE_DYNVAR_ALLOC :
6462 DTRACE_DYNVAR_DEALLOC, mstate, vstate);
6463
6464 if (dvar == NULL)
6465 break;
6466
6467 if (v->dtdv_type.dtdt_flags & DIF_TF_BYREF) {
6468 size_t lim = 0;
6469
6470 if (!dtrace_vcanload(
6471 (void *)(uintptr_t)regs[rd], &v->dtdv_type,
6472 &lim, mstate, vstate))
6473 break;
6474
6475 dtrace_vcopy((void *)(uintptr_t)regs[rd],
6476 dvar->dtdv_data, &v->dtdv_type, lim);
6477 } else {
6478 *((uint64_t *)dvar->dtdv_data) = regs[rd];
6479 }
6480
6481 break;
6482 }
6483
6484 case DIF_OP_ALLOCS: {
6485 uintptr_t ptr = P2ROUNDUP(mstate->dtms_scratch_ptr, 8);
6486 size_t size = ptr - mstate->dtms_scratch_ptr + regs[r1];
6487
6488 /*
6489 * Rounding up the user allocation size could have
6490 * overflowed large, bogus allocations (like -1ULL) to
6491 * 0.
6492 */
6493 if (size < regs[r1] ||
6494 !DTRACE_INSCRATCH(mstate, size)) {
6495 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
6496 regs[rd] = 0;
6497 break;
6498 }
6499
6500 dtrace_bzero((void *) mstate->dtms_scratch_ptr, size);
6501 mstate->dtms_scratch_ptr += size;
6502 regs[rd] = ptr;
6503 break;
6504 }
6505
6506 case DIF_OP_COPYS:
6507 if (!dtrace_canstore(regs[rd], regs[r2],
6508 mstate, vstate)) {
6509 *flags |= CPU_DTRACE_BADADDR;
6510 *illval = regs[rd];
6511 break;
6512 }
6513
6514 if (!dtrace_canload(regs[r1], regs[r2], mstate, vstate))
6515 break;
6516
6517 dtrace_bcopy((void *)(uintptr_t)regs[r1],
6518 (void *)(uintptr_t)regs[rd], (size_t)regs[r2]);
6519 break;
6520
6521 case DIF_OP_STB:
6522 if (!dtrace_canstore(regs[rd], 1, mstate, vstate)) {
6523 *flags |= CPU_DTRACE_BADADDR;
6524 *illval = regs[rd];
6525 break;
6526 }
6527 *((uint8_t *)(uintptr_t)regs[rd]) = (uint8_t)regs[r1];
6528 break;
6529
6530 case DIF_OP_STH:
6531 if (!dtrace_canstore(regs[rd], 2, mstate, vstate)) {
6532 *flags |= CPU_DTRACE_BADADDR;
6533 *illval = regs[rd];
6534 break;
6535 }
6536 if (regs[rd] & 1) {
6537 *flags |= CPU_DTRACE_BADALIGN;
6538 *illval = regs[rd];
6539 break;
6540 }
6541 *((uint16_t *)(uintptr_t)regs[rd]) = (uint16_t)regs[r1];
6542 break;
6543
6544 case DIF_OP_STW:
6545 if (!dtrace_canstore(regs[rd], 4, mstate, vstate)) {
6546 *flags |= CPU_DTRACE_BADADDR;
6547 *illval = regs[rd];
6548 break;
6549 }
6550 if (regs[rd] & 3) {
6551 *flags |= CPU_DTRACE_BADALIGN;
6552 *illval = regs[rd];
6553 break;
6554 }
6555 *((uint32_t *)(uintptr_t)regs[rd]) = (uint32_t)regs[r1];
6556 break;
6557
6558 case DIF_OP_STX:
6559 if (!dtrace_canstore(regs[rd], 8, mstate, vstate)) {
6560 *flags |= CPU_DTRACE_BADADDR;
6561 *illval = regs[rd];
6562 break;
6563 }
6564
6565 /*
6566 * Darwin kmem_zalloc() called from
6567 * dtrace_difo_init() is 4-byte aligned.
6568 */
6569 if (regs[rd] & 3) {
6570 *flags |= CPU_DTRACE_BADALIGN;
6571 *illval = regs[rd];
6572 break;
6573 }
6574 *((uint64_t *)(uintptr_t)regs[rd]) = regs[r1];
6575 break;
6576 case DIF_OP_STRIP:
6577 regs[rd] = (uint64_t)dtrace_ptrauth_strip(
6578 (void*)regs[r1], r2);
6579 break;
6580 }
6581 }
6582
6583 if (!(*flags & CPU_DTRACE_FAULT))
6584 return (rval);
6585
6586 mstate->dtms_fltoffs = opc * sizeof (dif_instr_t);
6587 mstate->dtms_present |= DTRACE_MSTATE_FLTOFFS;
6588
6589 return (0);
6590 }
6591
6592 __attribute__((noinline))
6593 static void
dtrace_action_breakpoint(dtrace_ecb_t * ecb)6594 dtrace_action_breakpoint(dtrace_ecb_t *ecb)
6595 {
6596 dtrace_probe_t *probe = ecb->dte_probe;
6597 dtrace_provider_t *prov = probe->dtpr_provider;
6598 char c[DTRACE_FULLNAMELEN + 80], *str;
6599 const char *msg = "dtrace: breakpoint action at probe ";
6600 const char *ecbmsg = " (ecb ";
6601 uintptr_t mask = (0xf << (sizeof (uintptr_t) * NBBY / 4));
6602 uintptr_t val = (uintptr_t)ecb;
6603 int shift = (sizeof (uintptr_t) * NBBY) - 4, i = 0;
6604
6605 if (dtrace_destructive_disallow)
6606 return;
6607
6608 /*
6609 * It's impossible to be taking action on the NULL probe.
6610 */
6611 ASSERT(probe != NULL);
6612
6613 /*
6614 * This is a poor man's (destitute man's?) sprintf(): we want to
6615 * print the provider name, module name, function name and name of
6616 * the probe, along with the hex address of the ECB with the breakpoint
6617 * action -- all of which we must place in the character buffer by
6618 * hand.
6619 */
6620 while (*msg != '\0')
6621 c[i++] = *msg++;
6622
6623 for (str = prov->dtpv_name; *str != '\0'; str++)
6624 c[i++] = *str;
6625 c[i++] = ':';
6626
6627 for (str = probe->dtpr_mod; *str != '\0'; str++)
6628 c[i++] = *str;
6629 c[i++] = ':';
6630
6631 for (str = probe->dtpr_func; *str != '\0'; str++)
6632 c[i++] = *str;
6633 c[i++] = ':';
6634
6635 for (str = probe->dtpr_name; *str != '\0'; str++)
6636 c[i++] = *str;
6637
6638 while (*ecbmsg != '\0')
6639 c[i++] = *ecbmsg++;
6640
6641 while (shift >= 0) {
6642 mask = (uintptr_t)0xf << shift;
6643
6644 if (val >= ((uintptr_t)1 << shift))
6645 c[i++] = "0123456789abcdef"[(val & mask) >> shift];
6646 shift -= 4;
6647 }
6648
6649 c[i++] = ')';
6650 c[i] = '\0';
6651
6652 debug_enter(c);
6653 }
6654
6655 __attribute__((noinline))
6656 static void
dtrace_action_panic(dtrace_ecb_t * ecb)6657 dtrace_action_panic(dtrace_ecb_t *ecb)
6658 {
6659 dtrace_probe_t *probe = ecb->dte_probe;
6660
6661 /*
6662 * It's impossible to be taking action on the NULL probe.
6663 */
6664 ASSERT(probe != NULL);
6665
6666 if (dtrace_destructive_disallow)
6667 return;
6668
6669 if (dtrace_panicked != NULL)
6670 return;
6671
6672 if (dtrace_casptr(&dtrace_panicked, NULL, current_thread()) != NULL)
6673 return;
6674
6675 /*
6676 * We won the right to panic. (We want to be sure that only one
6677 * thread calls panic() from dtrace_probe(), and that panic() is
6678 * called exactly once.)
6679 */
6680 panic("dtrace: panic action at probe %s:%s:%s:%s (ecb %p)",
6681 probe->dtpr_provider->dtpv_name, probe->dtpr_mod,
6682 probe->dtpr_func, probe->dtpr_name, (void *)ecb);
6683
6684 /*
6685 * APPLE NOTE: this was for an old Mac OS X debug feature
6686 * allowing a return from panic(). Revisit someday.
6687 */
6688 dtrace_panicked = NULL;
6689 }
6690
6691 static void
dtrace_action_raise(uint64_t sig)6692 dtrace_action_raise(uint64_t sig)
6693 {
6694 if (dtrace_destructive_disallow)
6695 return;
6696
6697 if (sig >= NSIG) {
6698 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
6699 return;
6700 }
6701
6702 /*
6703 * raise() has a queue depth of 1 -- we ignore all subsequent
6704 * invocations of the raise() action.
6705 */
6706
6707 uthread_t uthread = current_uthread();
6708
6709 if (uthread && uthread->t_dtrace_sig == 0) {
6710 uthread->t_dtrace_sig = sig;
6711 act_set_astbsd(current_thread());
6712 }
6713 }
6714
6715 static void
dtrace_action_stop(void)6716 dtrace_action_stop(void)
6717 {
6718 if (dtrace_destructive_disallow)
6719 return;
6720
6721 uthread_t uthread = current_uthread();
6722 if (uthread) {
6723 /*
6724 * The currently running process will be set to task_suspend
6725 * when it next leaves the kernel.
6726 */
6727 uthread->t_dtrace_stop = 1;
6728 act_set_astbsd(current_thread());
6729 }
6730 }
6731
6732
6733 /*
6734 * APPLE NOTE: pidresume works in conjunction with the dtrace stop action.
6735 * Both activate only when the currently running process next leaves the
6736 * kernel.
6737 */
6738 static void
dtrace_action_pidresume(uint64_t pid)6739 dtrace_action_pidresume(uint64_t pid)
6740 {
6741 if (dtrace_destructive_disallow)
6742 return;
6743
6744 if (kauth_cred_issuser(kauth_cred_get()) == 0) {
6745 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
6746 return;
6747 }
6748 uthread_t uthread = current_uthread();
6749
6750 /*
6751 * When the currently running process leaves the kernel, it attempts to
6752 * task_resume the process (denoted by pid), if that pid appears to have
6753 * been stopped by dtrace_action_stop().
6754 * The currently running process has a pidresume() queue depth of 1 --
6755 * subsequent invocations of the pidresume() action are ignored.
6756 */
6757
6758 if (pid != 0 && uthread && uthread->t_dtrace_resumepid == 0) {
6759 uthread->t_dtrace_resumepid = pid;
6760 act_set_astbsd(current_thread());
6761 }
6762 }
6763
6764 __attribute__((noinline))
6765 static void
dtrace_action_chill(dtrace_mstate_t * mstate,hrtime_t val)6766 dtrace_action_chill(dtrace_mstate_t *mstate, hrtime_t val)
6767 {
6768 hrtime_t now;
6769 volatile uint16_t *flags;
6770 dtrace_cpu_t *cpu = CPU;
6771
6772 if (dtrace_destructive_disallow)
6773 return;
6774
6775 flags = (volatile uint16_t *)&cpu_core[cpu->cpu_id].cpuc_dtrace_flags;
6776
6777 now = dtrace_gethrtime();
6778
6779 if (now - cpu->cpu_dtrace_chillmark > dtrace_chill_interval) {
6780 /*
6781 * We need to advance the mark to the current time.
6782 */
6783 cpu->cpu_dtrace_chillmark = now;
6784 cpu->cpu_dtrace_chilled = 0;
6785 }
6786
6787 /*
6788 * Now check to see if the requested chill time would take us over
6789 * the maximum amount of time allowed in the chill interval. (Or
6790 * worse, if the calculation itself induces overflow.)
6791 */
6792 if (cpu->cpu_dtrace_chilled + val > dtrace_chill_max ||
6793 cpu->cpu_dtrace_chilled + val < cpu->cpu_dtrace_chilled) {
6794 *flags |= CPU_DTRACE_ILLOP;
6795 return;
6796 }
6797
6798 while (dtrace_gethrtime() - now < val)
6799 continue;
6800
6801 /*
6802 * Normally, we assure that the value of the variable "timestamp" does
6803 * not change within an ECB. The presence of chill() represents an
6804 * exception to this rule, however.
6805 */
6806 mstate->dtms_present &= ~DTRACE_MSTATE_TIMESTAMP;
6807 cpu->cpu_dtrace_chilled += val;
6808 }
6809
6810 __attribute__((noinline))
6811 static void
dtrace_action_ustack(dtrace_mstate_t * mstate,dtrace_state_t * state,uint64_t * buf,uint64_t arg)6812 dtrace_action_ustack(dtrace_mstate_t *mstate, dtrace_state_t *state,
6813 uint64_t *buf, uint64_t arg)
6814 {
6815 int nframes = DTRACE_USTACK_NFRAMES(arg);
6816 int strsize = DTRACE_USTACK_STRSIZE(arg);
6817 uint64_t *pcs = &buf[1], *fps;
6818 char *str = (char *)&pcs[nframes];
6819 int size, offs = 0, i, j;
6820 uintptr_t old = mstate->dtms_scratch_ptr, saved;
6821 uint16_t *flags = &cpu_core[CPU->cpu_id].cpuc_dtrace_flags;
6822 char *sym;
6823
6824 /*
6825 * Should be taking a faster path if string space has not been
6826 * allocated.
6827 */
6828 ASSERT(strsize != 0);
6829
6830 /*
6831 * We will first allocate some temporary space for the frame pointers.
6832 */
6833 fps = (uint64_t *)P2ROUNDUP(mstate->dtms_scratch_ptr, 8);
6834 size = (uintptr_t)fps - mstate->dtms_scratch_ptr +
6835 (nframes * sizeof (uint64_t));
6836
6837 if (!DTRACE_INSCRATCH(mstate, (uintptr_t)size)) {
6838 /*
6839 * Not enough room for our frame pointers -- need to indicate
6840 * that we ran out of scratch space.
6841 */
6842 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
6843 return;
6844 }
6845
6846 mstate->dtms_scratch_ptr += size;
6847 saved = mstate->dtms_scratch_ptr;
6848
6849 /*
6850 * Now get a stack with both program counters and frame pointers.
6851 */
6852 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
6853 dtrace_getufpstack(buf, fps, nframes + 1);
6854 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
6855
6856 /*
6857 * If that faulted, we're cooked.
6858 */
6859 if (*flags & CPU_DTRACE_FAULT)
6860 goto out;
6861
6862 /*
6863 * Now we want to walk up the stack, calling the USTACK helper. For
6864 * each iteration, we restore the scratch pointer.
6865 */
6866 for (i = 0; i < nframes; i++) {
6867 mstate->dtms_scratch_ptr = saved;
6868
6869 if (offs >= strsize)
6870 break;
6871
6872 sym = (char *)(uintptr_t)dtrace_helper(
6873 DTRACE_HELPER_ACTION_USTACK,
6874 mstate, state, pcs[i], fps[i]);
6875
6876 /*
6877 * If we faulted while running the helper, we're going to
6878 * clear the fault and null out the corresponding string.
6879 */
6880 if (*flags & CPU_DTRACE_FAULT) {
6881 *flags &= ~CPU_DTRACE_FAULT;
6882 str[offs++] = '\0';
6883 continue;
6884 }
6885
6886 if (sym == NULL) {
6887 str[offs++] = '\0';
6888 continue;
6889 }
6890
6891 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
6892
6893 /*
6894 * Now copy in the string that the helper returned to us.
6895 */
6896 for (j = 0; offs + j < strsize; j++) {
6897 if ((str[offs + j] = sym[j]) == '\0')
6898 break;
6899 }
6900
6901 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
6902
6903 offs += j + 1;
6904 }
6905
6906 if (offs >= strsize) {
6907 /*
6908 * If we didn't have room for all of the strings, we don't
6909 * abort processing -- this needn't be a fatal error -- but we
6910 * still want to increment a counter (dts_stkstroverflows) to
6911 * allow this condition to be warned about. (If this is from
6912 * a jstack() action, it is easily tuned via jstackstrsize.)
6913 */
6914 dtrace_error(&state->dts_stkstroverflows);
6915 }
6916
6917 while (offs < strsize)
6918 str[offs++] = '\0';
6919
6920 out:
6921 mstate->dtms_scratch_ptr = old;
6922 }
6923
6924 __attribute__((noinline))
6925 static void
dtrace_store_by_ref(dtrace_difo_t * dp,caddr_t tomax,size_t size,size_t * valoffsp,uint64_t * valp,uint64_t end,int intuple,int dtkind)6926 dtrace_store_by_ref(dtrace_difo_t *dp, caddr_t tomax, size_t size,
6927 size_t *valoffsp, uint64_t *valp, uint64_t end, int intuple, int dtkind)
6928 {
6929 volatile uint16_t *flags;
6930 uint64_t val = *valp;
6931 size_t valoffs = *valoffsp;
6932
6933 flags = (volatile uint16_t *)&cpu_core[CPU->cpu_id].cpuc_dtrace_flags;
6934 ASSERT(dtkind == DIF_TF_BYREF || dtkind == DIF_TF_BYUREF);
6935
6936 /*
6937 * If this is a string, we're going to only load until we find the zero
6938 * byte -- after which we'll store zero bytes.
6939 */
6940 if (dp->dtdo_rtype.dtdt_kind == DIF_TYPE_STRING) {
6941 char c = '\0' + 1;
6942 size_t s;
6943
6944 for (s = 0; s < size; s++) {
6945 if (c != '\0' && dtkind == DIF_TF_BYREF) {
6946 c = dtrace_load8(val++);
6947 } else if (c != '\0' && dtkind == DIF_TF_BYUREF) {
6948 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
6949 c = dtrace_fuword8((user_addr_t)(uintptr_t)val++);
6950 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
6951 if (*flags & CPU_DTRACE_FAULT)
6952 break;
6953 }
6954
6955 DTRACE_STORE(uint8_t, tomax, valoffs++, c);
6956
6957 if (c == '\0' && intuple)
6958 break;
6959 }
6960 } else {
6961 uint8_t c;
6962 while (valoffs < end) {
6963 if (dtkind == DIF_TF_BYREF) {
6964 c = dtrace_load8(val++);
6965 } else if (dtkind == DIF_TF_BYUREF) {
6966 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
6967 c = dtrace_fuword8((user_addr_t)(uintptr_t)val++);
6968 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
6969 if (*flags & CPU_DTRACE_FAULT)
6970 break;
6971 }
6972
6973 DTRACE_STORE(uint8_t, tomax,
6974 valoffs++, c);
6975 }
6976 }
6977
6978 *valp = val;
6979 *valoffsp = valoffs;
6980 }
6981
6982 /*
6983 * Disables interrupts and sets the per-thread inprobe flag. When DEBUG is
6984 * defined, we also assert that we are not recursing unless the probe ID is an
6985 * error probe.
6986 */
6987 static dtrace_icookie_t
dtrace_probe_enter(dtrace_id_t id)6988 dtrace_probe_enter(dtrace_id_t id)
6989 {
6990 thread_t thread = current_thread();
6991 uint16_t inprobe;
6992
6993 dtrace_icookie_t cookie;
6994
6995 cookie = dtrace_interrupt_disable();
6996
6997 /*
6998 * Unless this is an ERROR probe, we are not allowed to recurse in
6999 * dtrace_probe(). Recursing into DTrace probe usually means that a
7000 * function is instrumented that should not have been instrumented or
7001 * that the ordering guarantee of the records will be violated,
7002 * resulting in unexpected output. If there is an exception to this
7003 * assertion, a new case should be added.
7004 */
7005 inprobe = dtrace_get_thread_inprobe(thread);
7006 VERIFY(inprobe == 0 ||
7007 id == dtrace_probeid_error);
7008 ASSERT(inprobe < UINT16_MAX);
7009 dtrace_set_thread_inprobe(thread, inprobe + 1);
7010
7011 return (cookie);
7012 }
7013
7014 /*
7015 * Clears the per-thread inprobe flag and enables interrupts.
7016 */
7017 static void
dtrace_probe_exit(dtrace_icookie_t cookie)7018 dtrace_probe_exit(dtrace_icookie_t cookie)
7019 {
7020 thread_t thread = current_thread();
7021 uint16_t inprobe = dtrace_get_thread_inprobe(thread);
7022
7023 ASSERT(inprobe > 0);
7024 dtrace_set_thread_inprobe(thread, inprobe - 1);
7025
7026 #if INTERRUPT_MASKED_DEBUG
7027 ml_spin_debug_reset(thread);
7028 #endif /* INTERRUPT_MASKED_DEBUG */
7029
7030 dtrace_interrupt_enable(cookie);
7031 }
7032
7033 /*
7034 * If you're looking for the epicenter of DTrace, you just found it. This
7035 * is the function called by the provider to fire a probe -- from which all
7036 * subsequent probe-context DTrace activity emanates.
7037 */
7038 void
dtrace_probe(dtrace_id_t id,uint64_t arg0,uint64_t arg1,uint64_t arg2,uint64_t arg3,uint64_t arg4)7039 dtrace_probe(dtrace_id_t id, uint64_t arg0, uint64_t arg1,
7040 uint64_t arg2, uint64_t arg3, uint64_t arg4)
7041 {
7042 processorid_t cpuid;
7043 dtrace_icookie_t cookie;
7044 dtrace_probe_t *probe;
7045 dtrace_mstate_t mstate;
7046 dtrace_ecb_t *ecb;
7047 dtrace_action_t *act;
7048 intptr_t offs;
7049 size_t size;
7050 int vtime, onintr;
7051 volatile uint16_t *flags;
7052 hrtime_t now;
7053
7054 cookie = dtrace_probe_enter(id);
7055
7056 /* Ensure that probe id is valid. */
7057 if (id - 1 >= (dtrace_id_t)dtrace_nprobes) {
7058 dtrace_probe_exit(cookie);
7059 return;
7060 }
7061
7062 probe = dtrace_probes[id - 1];
7063 if (probe == NULL) {
7064 dtrace_probe_exit(cookie);
7065 return;
7066 }
7067
7068 cpuid = CPU->cpu_id;
7069 onintr = CPU_ON_INTR(CPU);
7070
7071 if (!onintr && probe->dtpr_predcache != DTRACE_CACHEIDNONE &&
7072 probe->dtpr_predcache == dtrace_get_thread_predcache(current_thread())) {
7073 /*
7074 * We have hit in the predicate cache; we know that
7075 * this predicate would evaluate to be false.
7076 */
7077 dtrace_probe_exit(cookie);
7078 return;
7079 }
7080
7081 if (panic_quiesce) {
7082 /*
7083 * We don't trace anything if we're panicking.
7084 */
7085 dtrace_probe_exit(cookie);
7086 return;
7087 }
7088
7089 #if !defined(__APPLE__)
7090 now = dtrace_gethrtime();
7091 vtime = dtrace_vtime_references != 0;
7092
7093 if (vtime && curthread->t_dtrace_start)
7094 curthread->t_dtrace_vtime += now - curthread->t_dtrace_start;
7095 #else
7096 /*
7097 * APPLE NOTE: The time spent entering DTrace and arriving
7098 * to this point, is attributed to the current thread.
7099 * Instead it should accrue to DTrace. FIXME
7100 */
7101 vtime = dtrace_vtime_references != 0;
7102
7103 if (vtime)
7104 {
7105 int64_t dtrace_accum_time, recent_vtime;
7106 thread_t thread = current_thread();
7107
7108 dtrace_accum_time = dtrace_get_thread_tracing(thread); /* Time spent inside DTrace so far (nanoseconds) */
7109
7110 if (dtrace_accum_time >= 0) {
7111 recent_vtime = dtrace_abs_to_nano(dtrace_calc_thread_recent_vtime(thread)); /* up to the moment thread vtime */
7112
7113 recent_vtime = recent_vtime - dtrace_accum_time; /* Time without DTrace contribution */
7114
7115 dtrace_set_thread_vtime(thread, recent_vtime);
7116 }
7117 }
7118
7119 now = dtrace_gethrtime(); /* must not precede dtrace_calc_thread_recent_vtime() call! */
7120 #endif /* __APPLE__ */
7121
7122 /*
7123 * APPLE NOTE: A provider may call dtrace_probe_error() in lieu of
7124 * dtrace_probe() in some circumstances. See, e.g. fasttrap_isa.c.
7125 * However the provider has no access to ECB context, so passes
7126 * 0 through "arg0" and the probe_id of the overridden probe as arg1.
7127 * Detect that here and cons up a viable state (from the probe_id).
7128 */
7129 if (dtrace_probeid_error == id && 0 == arg0) {
7130 dtrace_id_t ftp_id = (dtrace_id_t)arg1;
7131 dtrace_probe_t *ftp_probe = dtrace_probes[ftp_id - 1];
7132 dtrace_ecb_t *ftp_ecb = ftp_probe->dtpr_ecb;
7133
7134 if (NULL != ftp_ecb) {
7135 dtrace_state_t *ftp_state = ftp_ecb->dte_state;
7136
7137 arg0 = (uint64_t)(uintptr_t)ftp_state;
7138 arg1 = ftp_ecb->dte_epid;
7139 /*
7140 * args[2-4] established by caller.
7141 */
7142 ftp_state->dts_arg_error_illval = -1; /* arg5 */
7143 }
7144 }
7145
7146 mstate.dtms_difo = NULL;
7147 mstate.dtms_probe = probe;
7148 mstate.dtms_strtok = 0;
7149 mstate.dtms_arg[0] = arg0;
7150 mstate.dtms_arg[1] = arg1;
7151 mstate.dtms_arg[2] = arg2;
7152 mstate.dtms_arg[3] = arg3;
7153 mstate.dtms_arg[4] = arg4;
7154
7155 flags = (volatile uint16_t *)&cpu_core[cpuid].cpuc_dtrace_flags;
7156
7157 for (ecb = probe->dtpr_ecb; ecb != NULL; ecb = ecb->dte_next) {
7158 dtrace_predicate_t *pred = ecb->dte_predicate;
7159 dtrace_state_t *state = ecb->dte_state;
7160 dtrace_buffer_t *buf = &state->dts_buffer[cpuid];
7161 dtrace_buffer_t *aggbuf = &state->dts_aggbuffer[cpuid];
7162 dtrace_vstate_t *vstate = &state->dts_vstate;
7163 dtrace_provider_t *prov = probe->dtpr_provider;
7164 uint64_t tracememsize = 0;
7165 int committed = 0;
7166 caddr_t tomax;
7167
7168 /*
7169 * A little subtlety with the following (seemingly innocuous)
7170 * declaration of the automatic 'val': by looking at the
7171 * code, you might think that it could be declared in the
7172 * action processing loop, below. (That is, it's only used in
7173 * the action processing loop.) However, it must be declared
7174 * out of that scope because in the case of DIF expression
7175 * arguments to aggregating actions, one iteration of the
7176 * action loop will use the last iteration's value.
7177 */
7178 #ifdef lint
7179 uint64_t val = 0;
7180 #else
7181 uint64_t val = 0;
7182 #endif
7183
7184 mstate.dtms_present = DTRACE_MSTATE_ARGS | DTRACE_MSTATE_PROBE;
7185 *flags &= ~CPU_DTRACE_ERROR;
7186
7187 if (prov == dtrace_provider) {
7188 /*
7189 * If dtrace itself is the provider of this probe,
7190 * we're only going to continue processing the ECB if
7191 * arg0 (the dtrace_state_t) is equal to the ECB's
7192 * creating state. (This prevents disjoint consumers
7193 * from seeing one another's metaprobes.)
7194 */
7195 if (arg0 != (uint64_t)(uintptr_t)state)
7196 continue;
7197 }
7198
7199 if (state->dts_activity != DTRACE_ACTIVITY_ACTIVE) {
7200 /*
7201 * We're not currently active. If our provider isn't
7202 * the dtrace pseudo provider, we're not interested.
7203 */
7204 if (prov != dtrace_provider)
7205 continue;
7206
7207 /*
7208 * Now we must further check if we are in the BEGIN
7209 * probe. If we are, we will only continue processing
7210 * if we're still in WARMUP -- if one BEGIN enabling
7211 * has invoked the exit() action, we don't want to
7212 * evaluate subsequent BEGIN enablings.
7213 */
7214 if (probe->dtpr_id == dtrace_probeid_begin &&
7215 state->dts_activity != DTRACE_ACTIVITY_WARMUP) {
7216 ASSERT(state->dts_activity ==
7217 DTRACE_ACTIVITY_DRAINING);
7218 continue;
7219 }
7220 }
7221
7222 if (ecb->dte_cond) {
7223 /*
7224 * If the dte_cond bits indicate that this
7225 * consumer is only allowed to see user-mode firings
7226 * of this probe, call the provider's dtps_usermode()
7227 * entry point to check that the probe was fired
7228 * while in a user context. Skip this ECB if that's
7229 * not the case.
7230 */
7231 if ((ecb->dte_cond & DTRACE_COND_USERMODE) &&
7232 prov->dtpv_pops.dtps_usermode &&
7233 prov->dtpv_pops.dtps_usermode(prov->dtpv_arg,
7234 probe->dtpr_id, probe->dtpr_arg) == 0)
7235 continue;
7236
7237 /*
7238 * This is more subtle than it looks. We have to be
7239 * absolutely certain that CRED() isn't going to
7240 * change out from under us so it's only legit to
7241 * examine that structure if we're in constrained
7242 * situations. Currently, the only times we'll this
7243 * check is if a non-super-user has enabled the
7244 * profile or syscall providers -- providers that
7245 * allow visibility of all processes. For the
7246 * profile case, the check above will ensure that
7247 * we're examining a user context.
7248 */
7249 if (ecb->dte_cond & DTRACE_COND_OWNER) {
7250 cred_t *cr;
7251 cred_t *s_cr =
7252 ecb->dte_state->dts_cred.dcr_cred;
7253 proc_t *proc;
7254 #pragma unused(proc) /* __APPLE__ */
7255
7256 ASSERT(s_cr != NULL);
7257
7258 /*
7259 * XXX this is hackish, but so is setting a variable
7260 * XXX in a McCarthy OR...
7261 */
7262 if ((cr = dtrace_CRED()) == NULL ||
7263 posix_cred_get(s_cr)->cr_uid != posix_cred_get(cr)->cr_uid ||
7264 posix_cred_get(s_cr)->cr_uid != posix_cred_get(cr)->cr_ruid ||
7265 posix_cred_get(s_cr)->cr_uid != posix_cred_get(cr)->cr_suid ||
7266 posix_cred_get(s_cr)->cr_gid != posix_cred_get(cr)->cr_gid ||
7267 posix_cred_get(s_cr)->cr_gid != posix_cred_get(cr)->cr_rgid ||
7268 posix_cred_get(s_cr)->cr_gid != posix_cred_get(cr)->cr_sgid ||
7269 #if !defined(__APPLE__)
7270 (proc = ttoproc(curthread)) == NULL ||
7271 (proc->p_flag & SNOCD))
7272 #else
7273 1) /* APPLE NOTE: Darwin omits "No Core Dump" flag */
7274 #endif /* __APPLE__ */
7275 continue;
7276 }
7277
7278 if (ecb->dte_cond & DTRACE_COND_ZONEOWNER) {
7279 cred_t *cr;
7280 cred_t *s_cr =
7281 ecb->dte_state->dts_cred.dcr_cred;
7282 #pragma unused(cr, s_cr) /* __APPLE__ */
7283
7284 ASSERT(s_cr != NULL);
7285
7286 #if !defined(__APPLE__)
7287 if ((cr = CRED()) == NULL ||
7288 s_cr->cr_zone->zone_id !=
7289 cr->cr_zone->zone_id)
7290 continue;
7291 #else
7292 /* APPLE NOTE: Darwin doesn't do zones. */
7293 #endif /* __APPLE__ */
7294 }
7295 }
7296
7297 if (now - state->dts_alive > dtrace_deadman_timeout) {
7298 /*
7299 * We seem to be dead. Unless we (a) have kernel
7300 * destructive permissions (b) have expicitly enabled
7301 * destructive actions and (c) destructive actions have
7302 * not been disabled, we're going to transition into
7303 * the KILLED state, from which no further processing
7304 * on this state will be performed.
7305 */
7306 if (!dtrace_priv_kernel_destructive(state) ||
7307 !state->dts_cred.dcr_destructive ||
7308 dtrace_destructive_disallow) {
7309 void *activity = &state->dts_activity;
7310 dtrace_activity_t current;
7311
7312 do {
7313 current = state->dts_activity;
7314 } while (dtrace_cas32(activity, current,
7315 DTRACE_ACTIVITY_KILLED) != current);
7316
7317 continue;
7318 }
7319 }
7320
7321 if ((offs = dtrace_buffer_reserve(buf, ecb->dte_needed,
7322 ecb->dte_alignment, state, &mstate)) < 0)
7323 continue;
7324
7325 tomax = buf->dtb_tomax;
7326 ASSERT(tomax != NULL);
7327
7328 /*
7329 * Build and store the record header corresponding to the ECB.
7330 */
7331 if (ecb->dte_size != 0) {
7332 dtrace_rechdr_t dtrh;
7333
7334 if (!(mstate.dtms_present & DTRACE_MSTATE_TIMESTAMP)) {
7335 mstate.dtms_timestamp = dtrace_gethrtime();
7336 mstate.dtms_present |= DTRACE_MSTATE_TIMESTAMP;
7337 }
7338
7339 ASSERT(ecb->dte_size >= sizeof(dtrace_rechdr_t));
7340
7341 dtrh.dtrh_epid = ecb->dte_epid;
7342 DTRACE_RECORD_STORE_TIMESTAMP(&dtrh, mstate.dtms_timestamp);
7343 DTRACE_STORE(dtrace_rechdr_t, tomax, offs, dtrh);
7344 }
7345
7346 mstate.dtms_epid = ecb->dte_epid;
7347 mstate.dtms_present |= DTRACE_MSTATE_EPID;
7348
7349 if (state->dts_cred.dcr_visible & DTRACE_CRV_KERNEL)
7350 mstate.dtms_access = DTRACE_ACCESS_KERNEL;
7351 else
7352 mstate.dtms_access = 0;
7353
7354 if (pred != NULL) {
7355 dtrace_difo_t *dp = pred->dtp_difo;
7356 uint64_t rval;
7357
7358 rval = dtrace_dif_emulate(dp, &mstate, vstate, state);
7359
7360 if (!(*flags & CPU_DTRACE_ERROR) && !rval) {
7361 dtrace_cacheid_t cid = probe->dtpr_predcache;
7362
7363 if (cid != DTRACE_CACHEIDNONE && !onintr) {
7364 /*
7365 * Update the predicate cache...
7366 */
7367 ASSERT(cid == pred->dtp_cacheid);
7368
7369 dtrace_set_thread_predcache(current_thread(), cid);
7370 }
7371
7372 continue;
7373 }
7374 }
7375
7376 for (act = ecb->dte_action; !(*flags & CPU_DTRACE_ERROR) &&
7377 act != NULL; act = act->dta_next) {
7378 size_t valoffs;
7379 dtrace_difo_t *dp;
7380 dtrace_recdesc_t *rec = &act->dta_rec;
7381
7382 size = rec->dtrd_size;
7383 valoffs = offs + rec->dtrd_offset;
7384
7385 if (DTRACEACT_ISAGG(act->dta_kind)) {
7386 uint64_t v = 0xbad;
7387 dtrace_aggregation_t *agg;
7388
7389 agg = (dtrace_aggregation_t *)act;
7390
7391 if ((dp = act->dta_difo) != NULL)
7392 v = dtrace_dif_emulate(dp,
7393 &mstate, vstate, state);
7394
7395 if (*flags & CPU_DTRACE_ERROR)
7396 continue;
7397
7398 /*
7399 * Note that we always pass the expression
7400 * value from the previous iteration of the
7401 * action loop. This value will only be used
7402 * if there is an expression argument to the
7403 * aggregating action, denoted by the
7404 * dtag_hasarg field.
7405 */
7406 dtrace_aggregate(agg, buf,
7407 offs, aggbuf, v, val);
7408 continue;
7409 }
7410
7411 switch (act->dta_kind) {
7412 case DTRACEACT_STOP:
7413 if (dtrace_priv_proc_destructive(state))
7414 dtrace_action_stop();
7415 continue;
7416
7417 case DTRACEACT_BREAKPOINT:
7418 if (dtrace_priv_kernel_destructive(state))
7419 dtrace_action_breakpoint(ecb);
7420 continue;
7421
7422 case DTRACEACT_PANIC:
7423 if (dtrace_priv_kernel_destructive(state))
7424 dtrace_action_panic(ecb);
7425 continue;
7426
7427 case DTRACEACT_STACK:
7428 if (!dtrace_priv_kernel(state))
7429 continue;
7430
7431 dtrace_getpcstack((pc_t *)(tomax + valoffs),
7432 size / sizeof (pc_t), probe->dtpr_aframes,
7433 DTRACE_ANCHORED(probe) ? NULL :
7434 (uint32_t *)(uintptr_t)arg0);
7435 continue;
7436
7437 case DTRACEACT_JSTACK:
7438 case DTRACEACT_USTACK:
7439 if (!dtrace_priv_proc(state))
7440 continue;
7441
7442 /*
7443 * See comment in DIF_VAR_PID.
7444 */
7445 if (DTRACE_ANCHORED(mstate.dtms_probe) &&
7446 CPU_ON_INTR(CPU)) {
7447 int depth = DTRACE_USTACK_NFRAMES(
7448 rec->dtrd_arg) + 1;
7449
7450 dtrace_bzero((void *)(tomax + valoffs),
7451 DTRACE_USTACK_STRSIZE(rec->dtrd_arg)
7452 + depth * sizeof (uint64_t));
7453
7454 continue;
7455 }
7456
7457 if (DTRACE_USTACK_STRSIZE(rec->dtrd_arg) != 0 &&
7458 curproc->p_dtrace_helpers != NULL) {
7459 /*
7460 * This is the slow path -- we have
7461 * allocated string space, and we're
7462 * getting the stack of a process that
7463 * has helpers. Call into a separate
7464 * routine to perform this processing.
7465 */
7466 dtrace_action_ustack(&mstate, state,
7467 (uint64_t *)(tomax + valoffs),
7468 rec->dtrd_arg);
7469 continue;
7470 }
7471
7472 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
7473 dtrace_getupcstack((uint64_t *)
7474 (tomax + valoffs),
7475 DTRACE_USTACK_NFRAMES(rec->dtrd_arg) + 1);
7476 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
7477 continue;
7478
7479 default:
7480 break;
7481 }
7482
7483 dp = act->dta_difo;
7484 ASSERT(dp != NULL);
7485
7486 val = dtrace_dif_emulate(dp, &mstate, vstate, state);
7487
7488 if (*flags & CPU_DTRACE_ERROR)
7489 continue;
7490
7491 switch (act->dta_kind) {
7492 case DTRACEACT_SPECULATE: {
7493 dtrace_rechdr_t *dtrh = NULL;
7494
7495 ASSERT(buf == &state->dts_buffer[cpuid]);
7496 buf = dtrace_speculation_buffer(state,
7497 cpuid, val);
7498
7499 if (buf == NULL) {
7500 *flags |= CPU_DTRACE_DROP;
7501 continue;
7502 }
7503
7504 offs = dtrace_buffer_reserve(buf,
7505 ecb->dte_needed, ecb->dte_alignment,
7506 state, NULL);
7507
7508 if (offs < 0) {
7509 *flags |= CPU_DTRACE_DROP;
7510 continue;
7511 }
7512
7513 tomax = buf->dtb_tomax;
7514 ASSERT(tomax != NULL);
7515
7516 if (ecb->dte_size == 0)
7517 continue;
7518
7519 ASSERT(ecb->dte_size >= sizeof(dtrace_rechdr_t));
7520 dtrh = ((void *)(tomax + offs));
7521 dtrh->dtrh_epid = ecb->dte_epid;
7522
7523 /*
7524 * When the speculation is committed, all of
7525 * the records in the speculative buffer will
7526 * have their timestamps set to the commit
7527 * time. Until then, it is set to a sentinel
7528 * value, for debugability.
7529 */
7530 DTRACE_RECORD_STORE_TIMESTAMP(dtrh, UINT64_MAX);
7531
7532 continue;
7533 }
7534
7535 case DTRACEACT_CHILL:
7536 if (dtrace_priv_kernel_destructive(state))
7537 dtrace_action_chill(&mstate, val);
7538 continue;
7539
7540 case DTRACEACT_RAISE:
7541 if (dtrace_priv_proc_destructive(state))
7542 dtrace_action_raise(val);
7543 continue;
7544
7545 case DTRACEACT_PIDRESUME: /* __APPLE__ */
7546 if (dtrace_priv_proc_destructive(state))
7547 dtrace_action_pidresume(val);
7548 continue;
7549
7550 case DTRACEACT_COMMIT:
7551 ASSERT(!committed);
7552
7553 /*
7554 * We need to commit our buffer state.
7555 */
7556 if (ecb->dte_size)
7557 buf->dtb_offset = offs + ecb->dte_size;
7558 buf = &state->dts_buffer[cpuid];
7559 dtrace_speculation_commit(state, cpuid, val);
7560 committed = 1;
7561 continue;
7562
7563 case DTRACEACT_DISCARD:
7564 dtrace_speculation_discard(state, cpuid, val);
7565 continue;
7566
7567 case DTRACEACT_DIFEXPR:
7568 case DTRACEACT_LIBACT:
7569 case DTRACEACT_PRINTF:
7570 case DTRACEACT_PRINTA:
7571 case DTRACEACT_SYSTEM:
7572 case DTRACEACT_FREOPEN:
7573 case DTRACEACT_APPLEBINARY: /* __APPLE__ */
7574 case DTRACEACT_TRACEMEM:
7575 break;
7576
7577 case DTRACEACT_TRACEMEM_DYNSIZE:
7578 tracememsize = val;
7579 break;
7580
7581 case DTRACEACT_SYM:
7582 case DTRACEACT_MOD:
7583 if (!dtrace_priv_kernel(state))
7584 continue;
7585 break;
7586
7587 case DTRACEACT_USYM:
7588 case DTRACEACT_UMOD:
7589 case DTRACEACT_UADDR: {
7590 if (!dtrace_priv_proc(state))
7591 continue;
7592
7593 DTRACE_STORE(uint64_t, tomax,
7594 valoffs, (uint64_t)dtrace_proc_selfpid());
7595 DTRACE_STORE(uint64_t, tomax,
7596 valoffs + sizeof (uint64_t), val);
7597
7598 continue;
7599 }
7600
7601 case DTRACEACT_EXIT: {
7602 /*
7603 * For the exit action, we are going to attempt
7604 * to atomically set our activity to be
7605 * draining. If this fails (either because
7606 * another CPU has beat us to the exit action,
7607 * or because our current activity is something
7608 * other than ACTIVE or WARMUP), we will
7609 * continue. This assures that the exit action
7610 * can be successfully recorded at most once
7611 * when we're in the ACTIVE state. If we're
7612 * encountering the exit() action while in
7613 * COOLDOWN, however, we want to honor the new
7614 * status code. (We know that we're the only
7615 * thread in COOLDOWN, so there is no race.)
7616 */
7617 void *activity = &state->dts_activity;
7618 dtrace_activity_t current = state->dts_activity;
7619
7620 if (current == DTRACE_ACTIVITY_COOLDOWN)
7621 break;
7622
7623 if (current != DTRACE_ACTIVITY_WARMUP)
7624 current = DTRACE_ACTIVITY_ACTIVE;
7625
7626 if (dtrace_cas32(activity, current,
7627 DTRACE_ACTIVITY_DRAINING) != current) {
7628 *flags |= CPU_DTRACE_DROP;
7629 continue;
7630 }
7631
7632 break;
7633 }
7634
7635 default:
7636 ASSERT(0);
7637 }
7638
7639 if (dp->dtdo_rtype.dtdt_flags & (DIF_TF_BYREF | DIF_TF_BYUREF)) {
7640 uintptr_t end = valoffs + size;
7641
7642 if (tracememsize != 0 &&
7643 valoffs + tracememsize < end)
7644 {
7645 end = valoffs + tracememsize;
7646 tracememsize = 0;
7647 }
7648
7649 if (dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF &&
7650 !dtrace_vcanload((void *)(uintptr_t)val,
7651 &dp->dtdo_rtype, NULL, &mstate, vstate))
7652 {
7653 continue;
7654 }
7655
7656 dtrace_store_by_ref(dp, tomax, size, &valoffs,
7657 &val, end, act->dta_intuple,
7658 dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF ?
7659 DIF_TF_BYREF: DIF_TF_BYUREF);
7660
7661 continue;
7662 }
7663
7664 switch (size) {
7665 case 0:
7666 break;
7667
7668 case sizeof (uint8_t):
7669 DTRACE_STORE(uint8_t, tomax, valoffs, val);
7670 break;
7671 case sizeof (uint16_t):
7672 DTRACE_STORE(uint16_t, tomax, valoffs, val);
7673 break;
7674 case sizeof (uint32_t):
7675 DTRACE_STORE(uint32_t, tomax, valoffs, val);
7676 break;
7677 case sizeof (uint64_t):
7678 DTRACE_STORE(uint64_t, tomax, valoffs, val);
7679 break;
7680 default:
7681 /*
7682 * Any other size should have been returned by
7683 * reference, not by value.
7684 */
7685 ASSERT(0);
7686 break;
7687 }
7688 }
7689
7690 if (*flags & CPU_DTRACE_DROP)
7691 continue;
7692
7693 if (*flags & CPU_DTRACE_FAULT) {
7694 int ndx;
7695 dtrace_action_t *err;
7696
7697 buf->dtb_errors++;
7698
7699 if (probe->dtpr_id == dtrace_probeid_error) {
7700 /*
7701 * There's nothing we can do -- we had an
7702 * error on the error probe. We bump an
7703 * error counter to at least indicate that
7704 * this condition happened.
7705 */
7706 dtrace_error(&state->dts_dblerrors);
7707 continue;
7708 }
7709
7710 if (vtime) {
7711 /*
7712 * Before recursing on dtrace_probe(), we
7713 * need to explicitly clear out our start
7714 * time to prevent it from being accumulated
7715 * into t_dtrace_vtime.
7716 */
7717
7718 /*
7719 * Darwin sets the sign bit on t_dtrace_tracing
7720 * to suspend accumulation to it.
7721 */
7722 dtrace_set_thread_tracing(current_thread(),
7723 (1ULL<<63) | dtrace_get_thread_tracing(current_thread()));
7724
7725 }
7726
7727 /*
7728 * Iterate over the actions to figure out which action
7729 * we were processing when we experienced the error.
7730 * Note that act points _past_ the faulting action; if
7731 * act is ecb->dte_action, the fault was in the
7732 * predicate, if it's ecb->dte_action->dta_next it's
7733 * in action #1, and so on.
7734 */
7735 for (err = ecb->dte_action, ndx = 0;
7736 err != act; err = err->dta_next, ndx++)
7737 continue;
7738
7739 dtrace_probe_error(state, ecb->dte_epid, ndx,
7740 (mstate.dtms_present & DTRACE_MSTATE_FLTOFFS) ?
7741 mstate.dtms_fltoffs : -1, DTRACE_FLAGS2FLT(*flags),
7742 cpu_core[cpuid].cpuc_dtrace_illval);
7743
7744 continue;
7745 }
7746
7747 if (!committed)
7748 buf->dtb_offset = offs + ecb->dte_size;
7749 }
7750
7751 /* FIXME: On Darwin the time spent leaving DTrace from this point to the rti is attributed
7752 to the current thread. Instead it should accrue to DTrace. */
7753 if (vtime) {
7754 thread_t thread = current_thread();
7755 int64_t t = dtrace_get_thread_tracing(thread);
7756
7757 if (t >= 0) {
7758 /* Usual case, accumulate time spent here into t_dtrace_tracing */
7759 dtrace_set_thread_tracing(thread, t + (dtrace_gethrtime() - now));
7760 } else {
7761 /* Return from error recursion. No accumulation, just clear the sign bit on t_dtrace_tracing. */
7762 dtrace_set_thread_tracing(thread, (~(1ULL<<63)) & t);
7763 }
7764 }
7765
7766 dtrace_probe_exit(cookie);
7767 }
7768
7769 /*
7770 * DTrace Probe Hashing Functions
7771 *
7772 * The functions in this section (and indeed, the functions in remaining
7773 * sections) are not _called_ from probe context. (Any exceptions to this are
7774 * marked with a "Note:".) Rather, they are called from elsewhere in the
7775 * DTrace framework to look-up probes in, add probes to and remove probes from
7776 * the DTrace probe hashes. (Each probe is hashed by each element of the
7777 * probe tuple -- allowing for fast lookups, regardless of what was
7778 * specified.)
7779 */
7780 static uint_t
dtrace_hash_str(const char * p)7781 dtrace_hash_str(const char *p)
7782 {
7783 unsigned int g;
7784 uint_t hval = 0;
7785
7786 while (*p) {
7787 hval = (hval << 4) + *p++;
7788 if ((g = (hval & 0xf0000000)) != 0)
7789 hval ^= g >> 24;
7790 hval &= ~g;
7791 }
7792 return (hval);
7793 }
7794
7795 static const char*
dtrace_strkey_probe_provider(void * elm,uintptr_t offs)7796 dtrace_strkey_probe_provider(void *elm, uintptr_t offs)
7797 {
7798 #pragma unused(offs)
7799 dtrace_probe_t *probe = (dtrace_probe_t*)elm;
7800 return probe->dtpr_provider->dtpv_name;
7801 }
7802
7803 static const char*
dtrace_strkey_offset(void * elm,uintptr_t offs)7804 dtrace_strkey_offset(void *elm, uintptr_t offs)
7805 {
7806 return ((char *)((uintptr_t)(elm) + offs));
7807 }
7808
7809 static const char*
dtrace_strkey_deref_offset(void * elm,uintptr_t offs)7810 dtrace_strkey_deref_offset(void *elm, uintptr_t offs)
7811 {
7812 return *((char **)((uintptr_t)(elm) + offs));
7813 }
7814
7815 static dtrace_hash_t *
dtrace_hash_create(dtrace_strkey_f func,uintptr_t arg,uintptr_t nextoffs,uintptr_t prevoffs)7816 dtrace_hash_create(dtrace_strkey_f func, uintptr_t arg, uintptr_t nextoffs, uintptr_t prevoffs)
7817 {
7818 dtrace_hash_t *hash = kmem_zalloc(sizeof (dtrace_hash_t), KM_SLEEP);
7819
7820 hash->dth_getstr = func;
7821 hash->dth_stroffs = arg;
7822 hash->dth_nextoffs = nextoffs;
7823 hash->dth_prevoffs = prevoffs;
7824
7825 hash->dth_size = 1;
7826 hash->dth_mask = hash->dth_size - 1;
7827
7828 hash->dth_tab = kmem_zalloc(hash->dth_size *
7829 sizeof (dtrace_hashbucket_t *), KM_SLEEP);
7830
7831 return (hash);
7832 }
7833
7834 /*
7835 * APPLE NOTE: dtrace_hash_destroy is not used.
7836 * It is called by dtrace_detach which is not
7837 * currently implemented. Revisit someday.
7838 */
7839 #if !defined(__APPLE__)
7840 static void
dtrace_hash_destroy(dtrace_hash_t * hash)7841 dtrace_hash_destroy(dtrace_hash_t *hash)
7842 {
7843 #if DEBUG
7844 int i;
7845
7846 for (i = 0; i < hash->dth_size; i++)
7847 ASSERT(hash->dth_tab[i] == NULL);
7848 #endif
7849
7850 kmem_free(hash->dth_tab,
7851 hash->dth_size * sizeof (dtrace_hashbucket_t *));
7852 kmem_free(hash, sizeof (dtrace_hash_t));
7853 }
7854 #endif /* __APPLE__ */
7855
7856 static void
dtrace_hash_resize(dtrace_hash_t * hash)7857 dtrace_hash_resize(dtrace_hash_t *hash)
7858 {
7859 int size = hash->dth_size, i, ndx;
7860 int new_size = hash->dth_size << 1;
7861 int new_mask = new_size - 1;
7862 dtrace_hashbucket_t **new_tab, *bucket, *next;
7863
7864 ASSERT((new_size & new_mask) == 0);
7865
7866 new_tab = kmem_zalloc(new_size * sizeof (void *), KM_SLEEP);
7867
7868 for (i = 0; i < size; i++) {
7869 for (bucket = hash->dth_tab[i]; bucket != NULL; bucket = next) {
7870 void *elm = bucket->dthb_chain;
7871
7872 ASSERT(elm != NULL);
7873 ndx = DTRACE_HASHSTR(hash, elm) & new_mask;
7874
7875 next = bucket->dthb_next;
7876 bucket->dthb_next = new_tab[ndx];
7877 new_tab[ndx] = bucket;
7878 }
7879 }
7880
7881 kmem_free(hash->dth_tab, hash->dth_size * sizeof (void *));
7882 hash->dth_tab = new_tab;
7883 hash->dth_size = new_size;
7884 hash->dth_mask = new_mask;
7885 }
7886
7887 static void
dtrace_hash_add(dtrace_hash_t * hash,void * new)7888 dtrace_hash_add(dtrace_hash_t *hash, void *new)
7889 {
7890 int hashval = DTRACE_HASHSTR(hash, new);
7891 int ndx = hashval & hash->dth_mask;
7892 dtrace_hashbucket_t *bucket = hash->dth_tab[ndx];
7893 void **nextp, **prevp;
7894
7895 for (; bucket != NULL; bucket = bucket->dthb_next) {
7896 if (DTRACE_HASHEQ(hash, bucket->dthb_chain, new))
7897 goto add;
7898 }
7899
7900 if ((hash->dth_nbuckets >> 1) > hash->dth_size) {
7901 dtrace_hash_resize(hash);
7902 dtrace_hash_add(hash, new);
7903 return;
7904 }
7905
7906 bucket = kmem_zalloc(sizeof (dtrace_hashbucket_t), KM_SLEEP);
7907 bucket->dthb_next = hash->dth_tab[ndx];
7908 hash->dth_tab[ndx] = bucket;
7909 hash->dth_nbuckets++;
7910
7911 add:
7912 nextp = DTRACE_HASHNEXT(hash, new);
7913 ASSERT(*nextp == NULL && *(DTRACE_HASHPREV(hash, new)) == NULL);
7914 *nextp = bucket->dthb_chain;
7915
7916 if (bucket->dthb_chain != NULL) {
7917 prevp = DTRACE_HASHPREV(hash, bucket->dthb_chain);
7918 ASSERT(*prevp == NULL);
7919 *prevp = new;
7920 }
7921
7922 bucket->dthb_chain = new;
7923 bucket->dthb_len++;
7924 }
7925
7926 static void *
dtrace_hash_lookup_string(dtrace_hash_t * hash,const char * str)7927 dtrace_hash_lookup_string(dtrace_hash_t *hash, const char *str)
7928 {
7929 int hashval = dtrace_hash_str(str);
7930 int ndx = hashval & hash->dth_mask;
7931 dtrace_hashbucket_t *bucket = hash->dth_tab[ndx];
7932
7933 for (; bucket != NULL; bucket = bucket->dthb_next) {
7934 if (strcmp(str, DTRACE_GETSTR(hash, bucket->dthb_chain)) == 0)
7935 return (bucket->dthb_chain);
7936 }
7937
7938 return (NULL);
7939 }
7940
7941 static dtrace_probe_t *
dtrace_hash_lookup(dtrace_hash_t * hash,void * template)7942 dtrace_hash_lookup(dtrace_hash_t *hash, void *template)
7943 {
7944 return dtrace_hash_lookup_string(hash, DTRACE_GETSTR(hash, template));
7945 }
7946
7947 static int
dtrace_hash_collisions(dtrace_hash_t * hash,void * template)7948 dtrace_hash_collisions(dtrace_hash_t *hash, void *template)
7949 {
7950 int hashval = DTRACE_HASHSTR(hash, template);
7951 int ndx = hashval & hash->dth_mask;
7952 dtrace_hashbucket_t *bucket = hash->dth_tab[ndx];
7953
7954 for (; bucket != NULL; bucket = bucket->dthb_next) {
7955 if (DTRACE_HASHEQ(hash, bucket->dthb_chain, template))
7956 return (bucket->dthb_len);
7957 }
7958
7959 return (0);
7960 }
7961
7962 static void
dtrace_hash_remove(dtrace_hash_t * hash,void * elm)7963 dtrace_hash_remove(dtrace_hash_t *hash, void *elm)
7964 {
7965 int ndx = DTRACE_HASHSTR(hash, elm) & hash->dth_mask;
7966 dtrace_hashbucket_t *bucket = hash->dth_tab[ndx];
7967
7968 void **prevp = DTRACE_HASHPREV(hash, elm);
7969 void **nextp = DTRACE_HASHNEXT(hash, elm);
7970
7971 /*
7972 * Find the bucket that we're removing this elm from.
7973 */
7974 for (; bucket != NULL; bucket = bucket->dthb_next) {
7975 if (DTRACE_HASHEQ(hash, bucket->dthb_chain, elm))
7976 break;
7977 }
7978
7979 ASSERT(bucket != NULL);
7980
7981 if (*prevp == NULL) {
7982 if (*nextp == NULL) {
7983 /*
7984 * The removed element was the only element on this
7985 * bucket; we need to remove the bucket.
7986 */
7987 dtrace_hashbucket_t *b = hash->dth_tab[ndx];
7988
7989 ASSERT(bucket->dthb_chain == elm);
7990 ASSERT(b != NULL);
7991
7992 if (b == bucket) {
7993 hash->dth_tab[ndx] = bucket->dthb_next;
7994 } else {
7995 while (b->dthb_next != bucket)
7996 b = b->dthb_next;
7997 b->dthb_next = bucket->dthb_next;
7998 }
7999
8000 ASSERT(hash->dth_nbuckets > 0);
8001 hash->dth_nbuckets--;
8002 kmem_free(bucket, sizeof (dtrace_hashbucket_t));
8003 return;
8004 }
8005
8006 bucket->dthb_chain = *nextp;
8007 } else {
8008 *(DTRACE_HASHNEXT(hash, *prevp)) = *nextp;
8009 }
8010
8011 if (*nextp != NULL)
8012 *(DTRACE_HASHPREV(hash, *nextp)) = *prevp;
8013 }
8014
8015 /*
8016 * DTrace Utility Functions
8017 *
8018 * These are random utility functions that are _not_ called from probe context.
8019 */
8020 static int
dtrace_badattr(const dtrace_attribute_t * a)8021 dtrace_badattr(const dtrace_attribute_t *a)
8022 {
8023 return (a->dtat_name > DTRACE_STABILITY_MAX ||
8024 a->dtat_data > DTRACE_STABILITY_MAX ||
8025 a->dtat_class > DTRACE_CLASS_MAX);
8026 }
8027
8028 /*
8029 * Returns a dtrace-managed copy of a string, and will
8030 * deduplicate copies of the same string.
8031 * If the specified string is NULL, returns an empty string
8032 */
8033 static char *
dtrace_strref(const char * str)8034 dtrace_strref(const char *str)
8035 {
8036 dtrace_string_t *s = NULL;
8037 size_t bufsize = (str != NULL ? strlen(str) : 0) + 1;
8038
8039 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
8040
8041 if (str == NULL)
8042 str = "";
8043
8044 for (s = dtrace_hash_lookup_string(dtrace_strings, str); s != NULL;
8045 s = *(DTRACE_HASHNEXT(dtrace_strings, s))) {
8046 if (strncmp(str, s->dtst_str, bufsize) != 0) {
8047 continue;
8048 }
8049 ASSERT(s->dtst_refcount != UINT32_MAX);
8050 s->dtst_refcount++;
8051 return s->dtst_str;
8052 }
8053
8054 s = kmem_zalloc(sizeof(dtrace_string_t) + bufsize, KM_SLEEP);
8055 s->dtst_refcount = 1;
8056 (void) strlcpy(s->dtst_str, str, bufsize);
8057
8058 dtrace_hash_add(dtrace_strings, s);
8059
8060 return s->dtst_str;
8061 }
8062
8063 static void
dtrace_strunref(const char * str)8064 dtrace_strunref(const char *str)
8065 {
8066 ASSERT(str != NULL);
8067 dtrace_string_t *s = NULL;
8068 size_t bufsize = strlen(str) + 1;
8069
8070 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
8071
8072 for (s = dtrace_hash_lookup_string(dtrace_strings, str); s != NULL;
8073 s = *(DTRACE_HASHNEXT(dtrace_strings, s))) {
8074 if (strncmp(str, s->dtst_str, bufsize) != 0) {
8075 continue;
8076 }
8077 ASSERT(s->dtst_refcount != 0);
8078 s->dtst_refcount--;
8079 if (s->dtst_refcount == 0) {
8080 dtrace_hash_remove(dtrace_strings, s);
8081 kmem_free(s, sizeof(dtrace_string_t) + bufsize);
8082 }
8083 return;
8084 }
8085 panic("attempt to unref non-existent string %s", str);
8086 }
8087
8088 #define DTRACE_ISALPHA(c) \
8089 (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z'))
8090
8091 static int
dtrace_badname(const char * s)8092 dtrace_badname(const char *s)
8093 {
8094 char c;
8095
8096 if (s == NULL || (c = *s++) == '\0')
8097 return (0);
8098
8099 if (!DTRACE_ISALPHA(c) && c != '-' && c != '_' && c != '.')
8100 return (1);
8101
8102 while ((c = *s++) != '\0') {
8103 if (!DTRACE_ISALPHA(c) && (c < '0' || c > '9') &&
8104 c != '-' && c != '_' && c != '.' && c != '`')
8105 return (1);
8106 }
8107
8108 return (0);
8109 }
8110
8111 static void
dtrace_cred2priv(cred_t * cr,uint32_t * privp,uid_t * uidp,zoneid_t * zoneidp)8112 dtrace_cred2priv(cred_t *cr, uint32_t *privp, uid_t *uidp, zoneid_t *zoneidp)
8113 {
8114 uint32_t priv;
8115
8116 if (cr == NULL || PRIV_POLICY_ONLY(cr, PRIV_ALL, B_FALSE)) {
8117 if (dtrace_is_restricted() && !dtrace_are_restrictions_relaxed()) {
8118 priv = DTRACE_PRIV_USER | DTRACE_PRIV_PROC | DTRACE_PRIV_OWNER;
8119 }
8120 else {
8121 priv = DTRACE_PRIV_ALL;
8122 }
8123 *uidp = 0;
8124 *zoneidp = 0;
8125 } else {
8126 *uidp = crgetuid(cr);
8127 *zoneidp = crgetzoneid(cr);
8128
8129 priv = 0;
8130 if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_KERNEL, B_FALSE))
8131 priv |= DTRACE_PRIV_KERNEL | DTRACE_PRIV_USER;
8132 else if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_USER, B_FALSE))
8133 priv |= DTRACE_PRIV_USER;
8134 if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_PROC, B_FALSE))
8135 priv |= DTRACE_PRIV_PROC;
8136 if (PRIV_POLICY_ONLY(cr, PRIV_PROC_OWNER, B_FALSE))
8137 priv |= DTRACE_PRIV_OWNER;
8138 if (PRIV_POLICY_ONLY(cr, PRIV_PROC_ZONE, B_FALSE))
8139 priv |= DTRACE_PRIV_ZONEOWNER;
8140 }
8141
8142 *privp = priv;
8143 }
8144
8145 #ifdef DTRACE_ERRDEBUG
8146 static void
dtrace_errdebug(const char * str)8147 dtrace_errdebug(const char *str)
8148 {
8149 int hval = dtrace_hash_str(str) % DTRACE_ERRHASHSZ;
8150 int occupied = 0;
8151
8152 lck_mtx_lock(&dtrace_errlock);
8153 dtrace_errlast = str;
8154 dtrace_errthread = (kthread_t *)current_thread();
8155
8156 while (occupied++ < DTRACE_ERRHASHSZ) {
8157 if (dtrace_errhash[hval].dter_msg == str) {
8158 dtrace_errhash[hval].dter_count++;
8159 goto out;
8160 }
8161
8162 if (dtrace_errhash[hval].dter_msg != NULL) {
8163 hval = (hval + 1) % DTRACE_ERRHASHSZ;
8164 continue;
8165 }
8166
8167 dtrace_errhash[hval].dter_msg = str;
8168 dtrace_errhash[hval].dter_count = 1;
8169 goto out;
8170 }
8171
8172 panic("dtrace: undersized error hash");
8173 out:
8174 lck_mtx_unlock(&dtrace_errlock);
8175 }
8176 #endif
8177
8178 /*
8179 * DTrace Matching Functions
8180 *
8181 * These functions are used to match groups of probes, given some elements of
8182 * a probe tuple, or some globbed expressions for elements of a probe tuple.
8183 */
8184 static int
dtrace_match_priv(const dtrace_probe_t * prp,uint32_t priv,uid_t uid,zoneid_t zoneid)8185 dtrace_match_priv(const dtrace_probe_t *prp, uint32_t priv, uid_t uid,
8186 zoneid_t zoneid)
8187 {
8188 if (priv != DTRACE_PRIV_ALL) {
8189 uint32_t ppriv = prp->dtpr_provider->dtpv_priv.dtpp_flags;
8190 uint32_t match = priv & ppriv;
8191
8192 /*
8193 * No PRIV_DTRACE_* privileges...
8194 */
8195 if ((priv & (DTRACE_PRIV_PROC | DTRACE_PRIV_USER |
8196 DTRACE_PRIV_KERNEL)) == 0)
8197 return (0);
8198
8199 /*
8200 * No matching bits, but there were bits to match...
8201 */
8202 if (match == 0 && ppriv != 0)
8203 return (0);
8204
8205 /*
8206 * Need to have permissions to the process, but don't...
8207 */
8208 if (((ppriv & ~match) & DTRACE_PRIV_OWNER) != 0 &&
8209 uid != prp->dtpr_provider->dtpv_priv.dtpp_uid) {
8210 return (0);
8211 }
8212
8213 /*
8214 * Need to be in the same zone unless we possess the
8215 * privilege to examine all zones.
8216 */
8217 if (((ppriv & ~match) & DTRACE_PRIV_ZONEOWNER) != 0 &&
8218 zoneid != prp->dtpr_provider->dtpv_priv.dtpp_zoneid) {
8219 return (0);
8220 }
8221 }
8222
8223 return (1);
8224 }
8225
8226 /*
8227 * dtrace_match_probe compares a dtrace_probe_t to a pre-compiled key, which
8228 * consists of input pattern strings and an ops-vector to evaluate them.
8229 * This function returns >0 for match, 0 for no match, and <0 for error.
8230 */
8231 static int
dtrace_match_probe(const dtrace_probe_t * prp,const dtrace_probekey_t * pkp,uint32_t priv,uid_t uid,zoneid_t zoneid)8232 dtrace_match_probe(const dtrace_probe_t *prp, const dtrace_probekey_t *pkp,
8233 uint32_t priv, uid_t uid, zoneid_t zoneid)
8234 {
8235 dtrace_provider_t *pvp = prp->dtpr_provider;
8236 int rv;
8237
8238 if (pvp->dtpv_defunct)
8239 return (0);
8240
8241 if ((rv = pkp->dtpk_pmatch(pvp->dtpv_name, pkp->dtpk_prov, 0)) <= 0)
8242 return (rv);
8243
8244 if ((rv = pkp->dtpk_mmatch(prp->dtpr_mod, pkp->dtpk_mod, 0)) <= 0)
8245 return (rv);
8246
8247 if ((rv = pkp->dtpk_fmatch(prp->dtpr_func, pkp->dtpk_func, 0)) <= 0)
8248 return (rv);
8249
8250 if ((rv = pkp->dtpk_nmatch(prp->dtpr_name, pkp->dtpk_name, 0)) <= 0)
8251 return (rv);
8252
8253 if (dtrace_match_priv(prp, priv, uid, zoneid) == 0)
8254 return (0);
8255
8256 return (rv);
8257 }
8258
8259 /*
8260 * dtrace_match_glob() is a safe kernel implementation of the gmatch(3GEN)
8261 * interface for matching a glob pattern 'p' to an input string 's'. Unlike
8262 * libc's version, the kernel version only applies to 8-bit ASCII strings.
8263 * In addition, all of the recursion cases except for '*' matching have been
8264 * unwound. For '*', we still implement recursive evaluation, but a depth
8265 * counter is maintained and matching is aborted if we recurse too deep.
8266 * The function returns 0 if no match, >0 if match, and <0 if recursion error.
8267 */
8268 static int
dtrace_match_glob(const char * s,const char * p,int depth)8269 dtrace_match_glob(const char *s, const char *p, int depth)
8270 {
8271 const char *olds;
8272 char s1, c;
8273 int gs;
8274
8275 if (depth > DTRACE_PROBEKEY_MAXDEPTH)
8276 return (-1);
8277
8278 if (s == NULL)
8279 s = ""; /* treat NULL as empty string */
8280
8281 top:
8282 olds = s;
8283 s1 = *s++;
8284
8285 if (p == NULL)
8286 return (0);
8287
8288 if ((c = *p++) == '\0')
8289 return (s1 == '\0');
8290
8291 switch (c) {
8292 case '[': {
8293 int ok = 0, notflag = 0;
8294 char lc = '\0';
8295
8296 if (s1 == '\0')
8297 return (0);
8298
8299 if (*p == '!') {
8300 notflag = 1;
8301 p++;
8302 }
8303
8304 if ((c = *p++) == '\0')
8305 return (0);
8306
8307 do {
8308 if (c == '-' && lc != '\0' && *p != ']') {
8309 if ((c = *p++) == '\0')
8310 return (0);
8311 if (c == '\\' && (c = *p++) == '\0')
8312 return (0);
8313
8314 if (notflag) {
8315 if (s1 < lc || s1 > c)
8316 ok++;
8317 else
8318 return (0);
8319 } else if (lc <= s1 && s1 <= c)
8320 ok++;
8321
8322 } else if (c == '\\' && (c = *p++) == '\0')
8323 return (0);
8324
8325 lc = c; /* save left-hand 'c' for next iteration */
8326
8327 if (notflag) {
8328 if (s1 != c)
8329 ok++;
8330 else
8331 return (0);
8332 } else if (s1 == c)
8333 ok++;
8334
8335 if ((c = *p++) == '\0')
8336 return (0);
8337
8338 } while (c != ']');
8339
8340 if (ok)
8341 goto top;
8342
8343 return (0);
8344 }
8345
8346 case '\\':
8347 if ((c = *p++) == '\0')
8348 return (0);
8349 OS_FALLTHROUGH;
8350
8351 default:
8352 if (c != s1)
8353 return (0);
8354 OS_FALLTHROUGH;
8355
8356 case '?':
8357 if (s1 != '\0')
8358 goto top;
8359 return (0);
8360
8361 case '*':
8362 while (*p == '*')
8363 p++; /* consecutive *'s are identical to a single one */
8364
8365 if (*p == '\0')
8366 return (1);
8367
8368 for (s = olds; *s != '\0'; s++) {
8369 if ((gs = dtrace_match_glob(s, p, depth + 1)) != 0)
8370 return (gs);
8371 }
8372
8373 return (0);
8374 }
8375 }
8376
8377 /*ARGSUSED*/
8378 static int
dtrace_match_string(const char * s,const char * p,int depth)8379 dtrace_match_string(const char *s, const char *p, int depth)
8380 {
8381 #pragma unused(depth) /* __APPLE__ */
8382 return (s != NULL && s == p);
8383 }
8384
8385 /*ARGSUSED*/
8386 static int
dtrace_match_module(const char * s,const char * p,int depth)8387 dtrace_match_module(const char *s, const char *p, int depth)
8388 {
8389 #pragma unused(depth) /* __APPLE__ */
8390 size_t len;
8391 if (s == NULL || p == NULL)
8392 return (0);
8393
8394 len = strlen(p);
8395
8396 if (strncmp(p, s, len) != 0)
8397 return (0);
8398
8399 if (s[len] == '.' || s[len] == '\0')
8400 return (1);
8401
8402 return (0);
8403 }
8404
8405 /*ARGSUSED*/
8406 static int
dtrace_match_nul(const char * s,const char * p,int depth)8407 dtrace_match_nul(const char *s, const char *p, int depth)
8408 {
8409 #pragma unused(s, p, depth) /* __APPLE__ */
8410 return (1); /* always match the empty pattern */
8411 }
8412
8413 /*ARGSUSED*/
8414 static int
dtrace_match_nonzero(const char * s,const char * p,int depth)8415 dtrace_match_nonzero(const char *s, const char *p, int depth)
8416 {
8417 #pragma unused(p, depth) /* __APPLE__ */
8418 return (s != NULL && s[0] != '\0');
8419 }
8420
8421 static int
dtrace_match(const dtrace_probekey_t * pkp,uint32_t priv,uid_t uid,zoneid_t zoneid,int (* matched)(dtrace_probe_t *,void *,void *),void * arg1,void * arg2)8422 dtrace_match(const dtrace_probekey_t *pkp, uint32_t priv, uid_t uid,
8423 zoneid_t zoneid, int (*matched)(dtrace_probe_t *, void *, void *), void *arg1, void *arg2)
8424 {
8425 dtrace_probe_t *probe;
8426 dtrace_provider_t prov_template = {
8427 .dtpv_name = (char *)(uintptr_t)pkp->dtpk_prov
8428 };
8429
8430 dtrace_probe_t template = {
8431 .dtpr_provider = &prov_template,
8432 .dtpr_mod = (char *)(uintptr_t)pkp->dtpk_mod,
8433 .dtpr_func = (char *)(uintptr_t)pkp->dtpk_func,
8434 .dtpr_name = (char *)(uintptr_t)pkp->dtpk_name
8435 };
8436
8437 dtrace_hash_t *hash = NULL;
8438 int len, rc, best = INT_MAX, nmatched = 0;
8439 dtrace_id_t i;
8440
8441 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
8442
8443 /*
8444 * If the probe ID is specified in the key, just lookup by ID and
8445 * invoke the match callback once if a matching probe is found.
8446 */
8447 if (pkp->dtpk_id != DTRACE_IDNONE) {
8448 if ((probe = dtrace_probe_lookup_id(pkp->dtpk_id)) != NULL &&
8449 dtrace_match_probe(probe, pkp, priv, uid, zoneid) > 0) {
8450 if ((*matched)(probe, arg1, arg2) == DTRACE_MATCH_FAIL)
8451 return (DTRACE_MATCH_FAIL);
8452 nmatched++;
8453 }
8454 return (nmatched);
8455 }
8456
8457 /*
8458 * We want to find the most distinct of the provider name, module name,
8459 * function name, and name. So for each one that is not a glob
8460 * pattern or empty string, we perform a lookup in the corresponding
8461 * hash and use the hash table with the fewest collisions to do our
8462 * search.
8463 */
8464 if (pkp->dtpk_pmatch == &dtrace_match_string &&
8465 (len = dtrace_hash_collisions(dtrace_byprov, &template)) < best) {
8466 best = len;
8467 hash = dtrace_byprov;
8468 }
8469
8470 if (pkp->dtpk_mmatch == &dtrace_match_string &&
8471 (len = dtrace_hash_collisions(dtrace_bymod, &template)) < best) {
8472 best = len;
8473 hash = dtrace_bymod;
8474 }
8475
8476 if (pkp->dtpk_fmatch == &dtrace_match_string &&
8477 (len = dtrace_hash_collisions(dtrace_byfunc, &template)) < best) {
8478 best = len;
8479 hash = dtrace_byfunc;
8480 }
8481
8482 if (pkp->dtpk_nmatch == &dtrace_match_string &&
8483 (len = dtrace_hash_collisions(dtrace_byname, &template)) < best) {
8484 best = len;
8485 hash = dtrace_byname;
8486 }
8487
8488 /*
8489 * If we did not select a hash table, iterate over every probe and
8490 * invoke our callback for each one that matches our input probe key.
8491 */
8492 if (hash == NULL) {
8493 for (i = 0; i < (dtrace_id_t)dtrace_nprobes; i++) {
8494 if ((probe = dtrace_probes[i]) == NULL ||
8495 dtrace_match_probe(probe, pkp, priv, uid,
8496 zoneid) <= 0)
8497 continue;
8498
8499 nmatched++;
8500
8501 if ((rc = (*matched)(probe, arg1, arg2)) != DTRACE_MATCH_NEXT) {
8502 if (rc == DTRACE_MATCH_FAIL)
8503 return (DTRACE_MATCH_FAIL);
8504 break;
8505 }
8506 }
8507
8508 return (nmatched);
8509 }
8510
8511 /*
8512 * If we selected a hash table, iterate over each probe of the same key
8513 * name and invoke the callback for every probe that matches the other
8514 * attributes of our input probe key.
8515 */
8516 for (probe = dtrace_hash_lookup(hash, &template); probe != NULL;
8517 probe = *(DTRACE_HASHNEXT(hash, probe))) {
8518
8519 if (dtrace_match_probe(probe, pkp, priv, uid, zoneid) <= 0)
8520 continue;
8521
8522 nmatched++;
8523
8524 if ((rc = (*matched)(probe, arg1, arg2)) != DTRACE_MATCH_NEXT) {
8525 if (rc == DTRACE_MATCH_FAIL)
8526 return (DTRACE_MATCH_FAIL);
8527 break;
8528 }
8529 }
8530
8531 return (nmatched);
8532 }
8533
8534 /*
8535 * Return the function pointer dtrace_probecmp() should use to compare the
8536 * specified pattern with a string. For NULL or empty patterns, we select
8537 * dtrace_match_nul(). For glob pattern strings, we use dtrace_match_glob().
8538 * For non-empty non-glob strings, we use dtrace_match_string().
8539 */
8540 static dtrace_probekey_f *
dtrace_probekey_func(const char * p)8541 dtrace_probekey_func(const char *p)
8542 {
8543 char c;
8544
8545 if (p == NULL || *p == '\0')
8546 return (&dtrace_match_nul);
8547
8548 while ((c = *p++) != '\0') {
8549 if (c == '[' || c == '?' || c == '*' || c == '\\')
8550 return (&dtrace_match_glob);
8551 }
8552
8553 return (&dtrace_match_string);
8554 }
8555
8556 static dtrace_probekey_f *
dtrace_probekey_module_func(const char * p)8557 dtrace_probekey_module_func(const char *p)
8558 {
8559 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
8560
8561 dtrace_probekey_f *f = dtrace_probekey_func(p);
8562 if (f == &dtrace_match_string) {
8563 dtrace_probe_t template = {
8564 .dtpr_mod = (char *)(uintptr_t)p,
8565 };
8566 if (dtrace_hash_lookup(dtrace_bymod, &template) == NULL) {
8567 return (&dtrace_match_module);
8568 }
8569 return (&dtrace_match_string);
8570 }
8571 return f;
8572 }
8573
8574 /*
8575 * Build a probe comparison key for use with dtrace_match_probe() from the
8576 * given probe description. By convention, a null key only matches anchored
8577 * probes: if each field is the empty string, reset dtpk_fmatch to
8578 * dtrace_match_nonzero().
8579 */
8580 static void
dtrace_probekey(const dtrace_probedesc_t * pdp,dtrace_probekey_t * pkp)8581 dtrace_probekey(const dtrace_probedesc_t *pdp, dtrace_probekey_t *pkp)
8582 {
8583
8584 pkp->dtpk_prov = dtrace_strref(pdp->dtpd_provider);
8585 pkp->dtpk_pmatch = dtrace_probekey_func(pdp->dtpd_provider);
8586
8587 pkp->dtpk_mod = dtrace_strref(pdp->dtpd_mod);
8588 pkp->dtpk_mmatch = dtrace_probekey_module_func(pdp->dtpd_mod);
8589
8590 pkp->dtpk_func = dtrace_strref(pdp->dtpd_func);
8591 pkp->dtpk_fmatch = dtrace_probekey_func(pdp->dtpd_func);
8592
8593 pkp->dtpk_name = dtrace_strref(pdp->dtpd_name);
8594 pkp->dtpk_nmatch = dtrace_probekey_func(pdp->dtpd_name);
8595
8596 pkp->dtpk_id = pdp->dtpd_id;
8597
8598 if (pkp->dtpk_id == DTRACE_IDNONE &&
8599 pkp->dtpk_pmatch == &dtrace_match_nul &&
8600 pkp->dtpk_mmatch == &dtrace_match_nul &&
8601 pkp->dtpk_fmatch == &dtrace_match_nul &&
8602 pkp->dtpk_nmatch == &dtrace_match_nul)
8603 pkp->dtpk_fmatch = &dtrace_match_nonzero;
8604 }
8605
8606 static void
dtrace_probekey_release(dtrace_probekey_t * pkp)8607 dtrace_probekey_release(dtrace_probekey_t *pkp)
8608 {
8609 dtrace_strunref(pkp->dtpk_prov);
8610 dtrace_strunref(pkp->dtpk_mod);
8611 dtrace_strunref(pkp->dtpk_func);
8612 dtrace_strunref(pkp->dtpk_name);
8613 }
8614
8615 static int
dtrace_cond_provider_match(dtrace_probedesc_t * desc,void * data)8616 dtrace_cond_provider_match(dtrace_probedesc_t *desc, void *data)
8617 {
8618 if (desc == NULL)
8619 return 1;
8620
8621 dtrace_probekey_f *func = dtrace_probekey_func(desc->dtpd_provider);
8622
8623 return func((char*)data, desc->dtpd_provider, 0);
8624 }
8625
8626 /*
8627 * DTrace Provider-to-Framework API Functions
8628 *
8629 * These functions implement much of the Provider-to-Framework API, as
8630 * described in <sys/dtrace.h>. The parts of the API not in this section are
8631 * the functions in the API for probe management (found below), and
8632 * dtrace_probe() itself (found above).
8633 */
8634
8635 /*
8636 * Register the calling provider with the DTrace framework. This should
8637 * generally be called by DTrace providers in their attach(9E) entry point.
8638 */
8639 int
dtrace_register(const char * name,const dtrace_pattr_t * pap,uint32_t priv,cred_t * cr,const dtrace_pops_t * pops,void * arg,dtrace_provider_id_t * idp)8640 dtrace_register(const char *name, const dtrace_pattr_t *pap, uint32_t priv,
8641 cred_t *cr, const dtrace_pops_t *pops, void *arg, dtrace_provider_id_t *idp)
8642 {
8643 dtrace_provider_t *provider;
8644
8645 if (name == NULL || pap == NULL || pops == NULL || idp == NULL) {
8646 cmn_err(CE_WARN, "failed to register provider '%s': invalid "
8647 "arguments", name ? name : "<NULL>");
8648 return (EINVAL);
8649 }
8650
8651 if (name[0] == '\0' || dtrace_badname(name)) {
8652 cmn_err(CE_WARN, "failed to register provider '%s': invalid "
8653 "provider name", name);
8654 return (EINVAL);
8655 }
8656
8657 if ((pops->dtps_provide == NULL && pops->dtps_provide_module == NULL) ||
8658 pops->dtps_enable == NULL || pops->dtps_disable == NULL ||
8659 pops->dtps_destroy == NULL ||
8660 ((pops->dtps_resume == NULL) != (pops->dtps_suspend == NULL))) {
8661 cmn_err(CE_WARN, "failed to register provider '%s': invalid "
8662 "provider ops", name);
8663 return (EINVAL);
8664 }
8665
8666 if (dtrace_badattr(&pap->dtpa_provider) ||
8667 dtrace_badattr(&pap->dtpa_mod) ||
8668 dtrace_badattr(&pap->dtpa_func) ||
8669 dtrace_badattr(&pap->dtpa_name) ||
8670 dtrace_badattr(&pap->dtpa_args)) {
8671 cmn_err(CE_WARN, "failed to register provider '%s': invalid "
8672 "provider attributes", name);
8673 return (EINVAL);
8674 }
8675
8676 if (priv & ~DTRACE_PRIV_ALL) {
8677 cmn_err(CE_WARN, "failed to register provider '%s': invalid "
8678 "privilege attributes", name);
8679 return (EINVAL);
8680 }
8681
8682 if ((priv & DTRACE_PRIV_KERNEL) &&
8683 (priv & (DTRACE_PRIV_USER | DTRACE_PRIV_OWNER)) &&
8684 pops->dtps_usermode == NULL) {
8685 cmn_err(CE_WARN, "failed to register provider '%s': need "
8686 "dtps_usermode() op for given privilege attributes", name);
8687 return (EINVAL);
8688 }
8689
8690 provider = kmem_zalloc(sizeof (dtrace_provider_t), KM_SLEEP);
8691
8692 provider->dtpv_attr = *pap;
8693 provider->dtpv_priv.dtpp_flags = priv;
8694 if (cr != NULL) {
8695 provider->dtpv_priv.dtpp_uid = crgetuid(cr);
8696 provider->dtpv_priv.dtpp_zoneid = crgetzoneid(cr);
8697 }
8698 provider->dtpv_pops = *pops;
8699
8700 if (pops->dtps_provide == NULL) {
8701 ASSERT(pops->dtps_provide_module != NULL);
8702 provider->dtpv_pops.dtps_provide = dtrace_provide_nullop;
8703 }
8704
8705 if (pops->dtps_provide_module == NULL) {
8706 ASSERT(pops->dtps_provide != NULL);
8707 provider->dtpv_pops.dtps_provide_module =
8708 dtrace_provide_module_nullop;
8709 }
8710
8711 if (pops->dtps_suspend == NULL) {
8712 ASSERT(pops->dtps_resume == NULL);
8713 provider->dtpv_pops.dtps_suspend = dtrace_suspend_nullop;
8714 provider->dtpv_pops.dtps_resume = dtrace_resume_nullop;
8715 }
8716
8717 provider->dtpv_arg = arg;
8718 *idp = (dtrace_provider_id_t)provider;
8719
8720 if (pops == &dtrace_provider_ops) {
8721 LCK_MTX_ASSERT(&dtrace_provider_lock, LCK_MTX_ASSERT_OWNED);
8722 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
8723
8724 provider->dtpv_name = dtrace_strref(name);
8725
8726 ASSERT(dtrace_anon.dta_enabling == NULL);
8727
8728 /*
8729 * We make sure that the DTrace provider is at the head of
8730 * the provider chain.
8731 */
8732 provider->dtpv_next = dtrace_provider;
8733 dtrace_provider = provider;
8734 return (0);
8735 }
8736
8737 lck_mtx_lock(&dtrace_provider_lock);
8738 lck_mtx_lock(&dtrace_lock);
8739
8740 provider->dtpv_name = dtrace_strref(name);
8741
8742 /*
8743 * If there is at least one provider registered, we'll add this
8744 * provider after the first provider.
8745 */
8746 if (dtrace_provider != NULL) {
8747 provider->dtpv_next = dtrace_provider->dtpv_next;
8748 dtrace_provider->dtpv_next = provider;
8749 } else {
8750 dtrace_provider = provider;
8751 }
8752
8753 if (dtrace_retained != NULL) {
8754 dtrace_enabling_provide(provider);
8755
8756 /*
8757 * Now we need to call dtrace_enabling_matchall_with_cond() --
8758 * with a condition matching the provider name we just added,
8759 * which will acquire cpu_lock and dtrace_lock. We therefore need
8760 * to drop all of our locks before calling into it...
8761 */
8762 lck_mtx_unlock(&dtrace_lock);
8763 lck_mtx_unlock(&dtrace_provider_lock);
8764
8765 dtrace_match_cond_t cond = {dtrace_cond_provider_match, provider->dtpv_name};
8766 dtrace_enabling_matchall_with_cond(&cond);
8767
8768 return (0);
8769 }
8770
8771 lck_mtx_unlock(&dtrace_lock);
8772 lck_mtx_unlock(&dtrace_provider_lock);
8773
8774 return (0);
8775 }
8776
8777 /*
8778 * Unregister the specified provider from the DTrace framework. This should
8779 * generally be called by DTrace providers in their detach(9E) entry point.
8780 */
8781 int
dtrace_unregister(dtrace_provider_id_t id)8782 dtrace_unregister(dtrace_provider_id_t id)
8783 {
8784 dtrace_provider_t *old = (dtrace_provider_t *)id;
8785 dtrace_provider_t *prev = NULL;
8786 int self = 0;
8787 dtrace_probe_t *probe, *first = NULL, *next = NULL;
8788 dtrace_probe_t template = {
8789 .dtpr_provider = old
8790 };
8791
8792 if (old->dtpv_pops.dtps_enable ==
8793 (int (*)(void *, dtrace_id_t, void *))dtrace_enable_nullop) {
8794 /*
8795 * If DTrace itself is the provider, we're called with locks
8796 * already held.
8797 */
8798 ASSERT(old == dtrace_provider);
8799 ASSERT(dtrace_devi != NULL);
8800 LCK_MTX_ASSERT(&dtrace_provider_lock, LCK_MTX_ASSERT_OWNED);
8801 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
8802 self = 1;
8803
8804 if (dtrace_provider->dtpv_next != NULL) {
8805 /*
8806 * There's another provider here; return failure.
8807 */
8808 return (EBUSY);
8809 }
8810 } else {
8811 lck_mtx_lock(&dtrace_provider_lock);
8812 lck_mtx_lock(&mod_lock);
8813 lck_mtx_lock(&dtrace_lock);
8814 }
8815
8816 /*
8817 * If anyone has /dev/dtrace open, or if there are anonymous enabled
8818 * probes, we refuse to let providers slither away, unless this
8819 * provider has already been explicitly invalidated.
8820 */
8821 if (!old->dtpv_defunct &&
8822 (dtrace_opens || (dtrace_anon.dta_state != NULL &&
8823 dtrace_anon.dta_state->dts_necbs > 0))) {
8824 if (!self) {
8825 lck_mtx_unlock(&dtrace_lock);
8826 lck_mtx_unlock(&mod_lock);
8827 lck_mtx_unlock(&dtrace_provider_lock);
8828 }
8829 return (EBUSY);
8830 }
8831
8832 /*
8833 * Attempt to destroy the probes associated with this provider.
8834 */
8835 if (old->dtpv_ecb_count!=0) {
8836 /*
8837 * We have at least one ECB; we can't remove this provider.
8838 */
8839 if (!self) {
8840 lck_mtx_unlock(&dtrace_lock);
8841 lck_mtx_unlock(&mod_lock);
8842 lck_mtx_unlock(&dtrace_provider_lock);
8843 }
8844 return (EBUSY);
8845 }
8846
8847 /*
8848 * All of the probes for this provider are disabled; we can safely
8849 * remove all of them from their hash chains and from the probe array.
8850 */
8851 for (probe = dtrace_hash_lookup(dtrace_byprov, &template); probe != NULL;
8852 probe = *(DTRACE_HASHNEXT(dtrace_byprov, probe))) {
8853 if (probe->dtpr_provider != old)
8854 continue;
8855
8856 dtrace_probes[probe->dtpr_id - 1] = NULL;
8857 old->dtpv_probe_count--;
8858
8859 dtrace_hash_remove(dtrace_bymod, probe);
8860 dtrace_hash_remove(dtrace_byfunc, probe);
8861 dtrace_hash_remove(dtrace_byname, probe);
8862
8863 if (first == NULL) {
8864 first = probe;
8865 probe->dtpr_nextmod = NULL;
8866 } else {
8867 /*
8868 * Use nextmod as the chain of probes to remove
8869 */
8870 probe->dtpr_nextmod = first;
8871 first = probe;
8872 }
8873 }
8874
8875 for (probe = first; probe != NULL; probe = next) {
8876 next = probe->dtpr_nextmod;
8877 dtrace_hash_remove(dtrace_byprov, probe);
8878 }
8879
8880 /*
8881 * The provider's probes have been removed from the hash chains and
8882 * from the probe array. Now issue a dtrace_sync() to be sure that
8883 * everyone has cleared out from any probe array processing.
8884 */
8885 dtrace_sync();
8886
8887 for (probe = first; probe != NULL; probe = next) {
8888 next = probe->dtpr_nextmod;
8889
8890 old->dtpv_pops.dtps_destroy(old->dtpv_arg, probe->dtpr_id,
8891 probe->dtpr_arg);
8892 dtrace_strunref(probe->dtpr_mod);
8893 dtrace_strunref(probe->dtpr_func);
8894 dtrace_strunref(probe->dtpr_name);
8895 vmem_free(dtrace_arena, (void *)(uintptr_t)(probe->dtpr_id), 1);
8896 zfree(dtrace_probe_t_zone, probe);
8897 }
8898
8899 if ((prev = dtrace_provider) == old) {
8900 ASSERT(self || dtrace_devi == NULL);
8901 ASSERT(old->dtpv_next == NULL || dtrace_devi == NULL);
8902 dtrace_provider = old->dtpv_next;
8903 } else {
8904 while (prev != NULL && prev->dtpv_next != old)
8905 prev = prev->dtpv_next;
8906
8907 if (prev == NULL) {
8908 panic("attempt to unregister non-existent "
8909 "dtrace provider %p\n", (void *)id);
8910 }
8911
8912 prev->dtpv_next = old->dtpv_next;
8913 }
8914
8915 dtrace_strunref(old->dtpv_name);
8916
8917 if (!self) {
8918 lck_mtx_unlock(&dtrace_lock);
8919 lck_mtx_unlock(&mod_lock);
8920 lck_mtx_unlock(&dtrace_provider_lock);
8921 }
8922
8923 kmem_free(old, sizeof (dtrace_provider_t));
8924
8925 return (0);
8926 }
8927
8928 /*
8929 * Invalidate the specified provider. All subsequent probe lookups for the
8930 * specified provider will fail, but its probes will not be removed.
8931 */
8932 void
dtrace_invalidate(dtrace_provider_id_t id)8933 dtrace_invalidate(dtrace_provider_id_t id)
8934 {
8935 dtrace_provider_t *pvp = (dtrace_provider_t *)id;
8936
8937 ASSERT(pvp->dtpv_pops.dtps_enable !=
8938 (int (*)(void *, dtrace_id_t, void *))dtrace_enable_nullop);
8939
8940 lck_mtx_lock(&dtrace_provider_lock);
8941 lck_mtx_lock(&dtrace_lock);
8942
8943 pvp->dtpv_defunct = 1;
8944
8945 lck_mtx_unlock(&dtrace_lock);
8946 lck_mtx_unlock(&dtrace_provider_lock);
8947 }
8948
8949 /*
8950 * Indicate whether or not DTrace has attached.
8951 */
8952 int
dtrace_attached(void)8953 dtrace_attached(void)
8954 {
8955 /*
8956 * dtrace_provider will be non-NULL iff the DTrace driver has
8957 * attached. (It's non-NULL because DTrace is always itself a
8958 * provider.)
8959 */
8960 return (dtrace_provider != NULL);
8961 }
8962
8963 /*
8964 * Remove all the unenabled probes for the given provider. This function is
8965 * not unlike dtrace_unregister(), except that it doesn't remove the provider
8966 * -- just as many of its associated probes as it can.
8967 */
8968 int
dtrace_condense(dtrace_provider_id_t id)8969 dtrace_condense(dtrace_provider_id_t id)
8970 {
8971 dtrace_provider_t *prov = (dtrace_provider_t *)id;
8972 dtrace_probe_t *probe, *first = NULL;
8973 dtrace_probe_t template = {
8974 .dtpr_provider = prov
8975 };
8976
8977 /*
8978 * Make sure this isn't the dtrace provider itself.
8979 */
8980 ASSERT(prov->dtpv_pops.dtps_enable !=
8981 (int (*)(void *, dtrace_id_t, void *))dtrace_enable_nullop);
8982
8983 lck_mtx_lock(&dtrace_provider_lock);
8984 lck_mtx_lock(&dtrace_lock);
8985
8986 /*
8987 * Attempt to destroy the probes associated with this provider.
8988 */
8989 for (probe = dtrace_hash_lookup(dtrace_byprov, &template); probe != NULL;
8990 probe = *(DTRACE_HASHNEXT(dtrace_byprov, probe))) {
8991
8992 if (probe->dtpr_provider != prov)
8993 continue;
8994
8995 if (probe->dtpr_ecb != NULL)
8996 continue;
8997
8998 dtrace_probes[probe->dtpr_id - 1] = NULL;
8999 prov->dtpv_probe_count--;
9000
9001 dtrace_hash_remove(dtrace_bymod, probe);
9002 dtrace_hash_remove(dtrace_byfunc, probe);
9003 dtrace_hash_remove(dtrace_byname, probe);
9004
9005 prov->dtpv_pops.dtps_destroy(prov->dtpv_arg, probe->dtpr_id,
9006 probe->dtpr_arg);
9007 dtrace_strunref(probe->dtpr_mod);
9008 dtrace_strunref(probe->dtpr_func);
9009 dtrace_strunref(probe->dtpr_name);
9010 if (first == NULL) {
9011 first = probe;
9012 probe->dtpr_nextmod = NULL;
9013 } else {
9014 /*
9015 * Use nextmod as the chain of probes to remove
9016 */
9017 probe->dtpr_nextmod = first;
9018 first = probe;
9019 }
9020 }
9021
9022 for (probe = first; probe != NULL; probe = first) {
9023 first = probe->dtpr_nextmod;
9024 dtrace_hash_remove(dtrace_byprov, probe);
9025 vmem_free(dtrace_arena, (void *)((uintptr_t)probe->dtpr_id), 1);
9026 zfree(dtrace_probe_t_zone, probe);
9027 }
9028
9029 lck_mtx_unlock(&dtrace_lock);
9030 lck_mtx_unlock(&dtrace_provider_lock);
9031
9032 return (0);
9033 }
9034
9035 /*
9036 * DTrace Probe Management Functions
9037 *
9038 * The functions in this section perform the DTrace probe management,
9039 * including functions to create probes, look-up probes, and call into the
9040 * providers to request that probes be provided. Some of these functions are
9041 * in the Provider-to-Framework API; these functions can be identified by the
9042 * fact that they are not declared "static".
9043 */
9044
9045 /*
9046 * Create a probe with the specified module name, function name, and name.
9047 */
9048 dtrace_id_t
dtrace_probe_create(dtrace_provider_id_t prov,const char * mod,const char * func,const char * name,int aframes,void * arg)9049 dtrace_probe_create(dtrace_provider_id_t prov, const char *mod,
9050 const char *func, const char *name, int aframes, void *arg)
9051 {
9052 dtrace_probe_t *probe, **probes;
9053 dtrace_provider_t *provider = (dtrace_provider_t *)prov;
9054 dtrace_id_t id;
9055
9056 if (provider == dtrace_provider) {
9057 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
9058 } else {
9059 lck_mtx_lock(&dtrace_lock);
9060 }
9061
9062 id = (dtrace_id_t)(uintptr_t)vmem_alloc(dtrace_arena, 1,
9063 VM_BESTFIT | VM_SLEEP);
9064
9065 probe = zalloc_flags(dtrace_probe_t_zone, Z_WAITOK | Z_ZERO);
9066
9067 probe->dtpr_id = id;
9068 probe->dtpr_gen = dtrace_probegen++;
9069 probe->dtpr_mod = dtrace_strref(mod);
9070 probe->dtpr_func = dtrace_strref(func);
9071 probe->dtpr_name = dtrace_strref(name);
9072 probe->dtpr_arg = arg;
9073 probe->dtpr_aframes = aframes;
9074 probe->dtpr_provider = provider;
9075
9076 dtrace_hash_add(dtrace_byprov, probe);
9077 dtrace_hash_add(dtrace_bymod, probe);
9078 dtrace_hash_add(dtrace_byfunc, probe);
9079 dtrace_hash_add(dtrace_byname, probe);
9080
9081 if (id - 1 >= (dtrace_id_t)dtrace_nprobes) {
9082 size_t osize = dtrace_nprobes * sizeof (dtrace_probe_t *);
9083 size_t nsize = osize * 2;
9084
9085 probes = kmem_zalloc(nsize, KM_SLEEP);
9086
9087 dtrace_probe_t **oprobes = dtrace_probes;
9088
9089 bcopy(oprobes, probes, osize);
9090 dtrace_membar_producer();
9091 dtrace_probes = probes;
9092
9093 dtrace_sync();
9094
9095 /*
9096 * All CPUs are now seeing the new probes array; we can
9097 * safely free the old array.
9098 */
9099 kmem_free(oprobes, osize);
9100 dtrace_nprobes *= 2;
9101
9102 ASSERT(id - 1 < (dtrace_id_t)dtrace_nprobes);
9103 }
9104
9105 ASSERT(dtrace_probes[id - 1] == NULL);
9106 dtrace_probes[id - 1] = probe;
9107 provider->dtpv_probe_count++;
9108
9109 if (provider != dtrace_provider)
9110 lck_mtx_unlock(&dtrace_lock);
9111
9112 return (id);
9113 }
9114
9115 static dtrace_probe_t *
dtrace_probe_lookup_id(dtrace_id_t id)9116 dtrace_probe_lookup_id(dtrace_id_t id)
9117 {
9118 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
9119
9120 if (id == 0 || id > (dtrace_id_t)dtrace_nprobes)
9121 return (NULL);
9122
9123 return (dtrace_probes[id - 1]);
9124 }
9125
9126 static int
dtrace_probe_lookup_match(dtrace_probe_t * probe,void * arg1,void * arg2)9127 dtrace_probe_lookup_match(dtrace_probe_t *probe, void *arg1, void *arg2)
9128 {
9129 #pragma unused(arg2)
9130 *((dtrace_id_t *)arg1) = probe->dtpr_id;
9131
9132 return (DTRACE_MATCH_DONE);
9133 }
9134
9135 /*
9136 * Look up a probe based on provider and one or more of module name, function
9137 * name and probe name.
9138 */
9139 dtrace_id_t
dtrace_probe_lookup(dtrace_provider_id_t prid,const char * mod,const char * func,const char * name)9140 dtrace_probe_lookup(dtrace_provider_id_t prid, const char *mod,
9141 const char *func, const char *name)
9142 {
9143 dtrace_probekey_t pkey;
9144 dtrace_id_t id;
9145 int match;
9146
9147 lck_mtx_lock(&dtrace_lock);
9148
9149 pkey.dtpk_prov = dtrace_strref(((dtrace_provider_t *)prid)->dtpv_name);
9150 pkey.dtpk_pmatch = &dtrace_match_string;
9151 pkey.dtpk_mod = dtrace_strref(mod);
9152 pkey.dtpk_mmatch = mod ? &dtrace_match_string : &dtrace_match_nul;
9153 pkey.dtpk_func = dtrace_strref(func);
9154 pkey.dtpk_fmatch = func ? &dtrace_match_string : &dtrace_match_nul;
9155 pkey.dtpk_name = dtrace_strref(name);
9156 pkey.dtpk_nmatch = name ? &dtrace_match_string : &dtrace_match_nul;
9157 pkey.dtpk_id = DTRACE_IDNONE;
9158
9159 match = dtrace_match(&pkey, DTRACE_PRIV_ALL, 0, 0,
9160 dtrace_probe_lookup_match, &id, NULL);
9161
9162 dtrace_probekey_release(&pkey);
9163
9164 lck_mtx_unlock(&dtrace_lock);
9165
9166 ASSERT(match == 1 || match == 0);
9167 return (match ? id : 0);
9168 }
9169
9170 /*
9171 * Returns the probe argument associated with the specified probe.
9172 */
9173 void *
dtrace_probe_arg(dtrace_provider_id_t id,dtrace_id_t pid)9174 dtrace_probe_arg(dtrace_provider_id_t id, dtrace_id_t pid)
9175 {
9176 dtrace_probe_t *probe;
9177 void *rval = NULL;
9178
9179 lck_mtx_lock(&dtrace_lock);
9180
9181 if ((probe = dtrace_probe_lookup_id(pid)) != NULL &&
9182 probe->dtpr_provider == (dtrace_provider_t *)id)
9183 rval = probe->dtpr_arg;
9184
9185 lck_mtx_unlock(&dtrace_lock);
9186
9187 return (rval);
9188 }
9189
9190 /*
9191 * Copy a probe into a probe description.
9192 */
9193 static void
dtrace_probe_description(const dtrace_probe_t * prp,dtrace_probedesc_t * pdp)9194 dtrace_probe_description(const dtrace_probe_t *prp, dtrace_probedesc_t *pdp)
9195 {
9196 bzero(pdp, sizeof (dtrace_probedesc_t));
9197 pdp->dtpd_id = prp->dtpr_id;
9198
9199 /* APPLE NOTE: Darwin employs size bounded string operation. */
9200 (void) strlcpy(pdp->dtpd_provider,
9201 prp->dtpr_provider->dtpv_name, DTRACE_PROVNAMELEN);
9202
9203 (void) strlcpy(pdp->dtpd_mod, prp->dtpr_mod, DTRACE_MODNAMELEN);
9204 (void) strlcpy(pdp->dtpd_func, prp->dtpr_func, DTRACE_FUNCNAMELEN);
9205 (void) strlcpy(pdp->dtpd_name, prp->dtpr_name, DTRACE_NAMELEN);
9206 }
9207
9208 /*
9209 * Called to indicate that a probe -- or probes -- should be provided by a
9210 * specfied provider. If the specified description is NULL, the provider will
9211 * be told to provide all of its probes. (This is done whenever a new
9212 * consumer comes along, or whenever a retained enabling is to be matched.) If
9213 * the specified description is non-NULL, the provider is given the
9214 * opportunity to dynamically provide the specified probe, allowing providers
9215 * to support the creation of probes on-the-fly. (So-called _autocreated_
9216 * probes.) If the provider is NULL, the operations will be applied to all
9217 * providers; if the provider is non-NULL the operations will only be applied
9218 * to the specified provider. The dtrace_provider_lock must be held, and the
9219 * dtrace_lock must _not_ be held -- the provider's dtps_provide() operation
9220 * will need to grab the dtrace_lock when it reenters the framework through
9221 * dtrace_probe_lookup(), dtrace_probe_create(), etc.
9222 */
9223 static void
dtrace_probe_provide(dtrace_probedesc_t * desc,dtrace_provider_t * prv)9224 dtrace_probe_provide(dtrace_probedesc_t *desc, dtrace_provider_t *prv)
9225 {
9226 struct modctl *ctl;
9227 int all = 0;
9228
9229 LCK_MTX_ASSERT(&dtrace_provider_lock, LCK_MTX_ASSERT_OWNED);
9230
9231 if (prv == NULL) {
9232 all = 1;
9233 prv = dtrace_provider;
9234 }
9235
9236 do {
9237 /*
9238 * First, call the blanket provide operation.
9239 */
9240 prv->dtpv_pops.dtps_provide(prv->dtpv_arg, desc);
9241
9242 /*
9243 * Now call the per-module provide operation. We will grab
9244 * mod_lock to prevent the list from being modified. Note
9245 * that this also prevents the mod_busy bits from changing.
9246 * (mod_busy can only be changed with mod_lock held.)
9247 */
9248 lck_mtx_lock(&mod_lock);
9249
9250 ctl = dtrace_modctl_list;
9251 while (ctl) {
9252 prv->dtpv_pops.dtps_provide_module(prv->dtpv_arg, ctl);
9253 ctl = ctl->mod_next;
9254 }
9255
9256 lck_mtx_unlock(&mod_lock);
9257 } while (all && (prv = prv->dtpv_next) != NULL);
9258 }
9259
9260 /*
9261 * Iterate over each probe, and call the Framework-to-Provider API function
9262 * denoted by offs.
9263 */
9264 static void
dtrace_probe_foreach(uintptr_t offs)9265 dtrace_probe_foreach(uintptr_t offs)
9266 {
9267 dtrace_provider_t *prov;
9268 void (*func)(void *, dtrace_id_t, void *);
9269 dtrace_probe_t *probe;
9270 dtrace_icookie_t cookie;
9271 int i;
9272
9273 /*
9274 * We disable interrupts to walk through the probe array. This is
9275 * safe -- the dtrace_sync() in dtrace_unregister() assures that we
9276 * won't see stale data.
9277 */
9278 cookie = dtrace_interrupt_disable();
9279
9280 for (i = 0; i < dtrace_nprobes; i++) {
9281 if ((probe = dtrace_probes[i]) == NULL)
9282 continue;
9283
9284 if (probe->dtpr_ecb == NULL) {
9285 /*
9286 * This probe isn't enabled -- don't call the function.
9287 */
9288 continue;
9289 }
9290
9291 prov = probe->dtpr_provider;
9292 func = *((void(**)(void *, dtrace_id_t, void *))
9293 ((uintptr_t)&prov->dtpv_pops + offs));
9294
9295 func(prov->dtpv_arg, i + 1, probe->dtpr_arg);
9296 }
9297
9298 dtrace_interrupt_enable(cookie);
9299 }
9300
9301 static int
dtrace_probe_enable(const dtrace_probedesc_t * desc,dtrace_enabling_t * enab,dtrace_ecbdesc_t * ep)9302 dtrace_probe_enable(const dtrace_probedesc_t *desc, dtrace_enabling_t *enab, dtrace_ecbdesc_t *ep)
9303 {
9304 dtrace_probekey_t pkey;
9305 uint32_t priv;
9306 uid_t uid;
9307 zoneid_t zoneid;
9308 int err;
9309
9310 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
9311
9312 dtrace_ecb_create_cache = NULL;
9313
9314 if (desc == NULL) {
9315 /*
9316 * If we're passed a NULL description, we're being asked to
9317 * create an ECB with a NULL probe.
9318 */
9319 (void) dtrace_ecb_create_enable(NULL, enab, ep);
9320 return (0);
9321 }
9322
9323 dtrace_probekey(desc, &pkey);
9324 dtrace_cred2priv(enab->dten_vstate->dtvs_state->dts_cred.dcr_cred,
9325 &priv, &uid, &zoneid);
9326
9327 err = dtrace_match(&pkey, priv, uid, zoneid, dtrace_ecb_create_enable, enab, ep);
9328
9329 dtrace_probekey_release(&pkey);
9330
9331 return err;
9332 }
9333
9334 /*
9335 * DTrace Helper Provider Functions
9336 */
9337 static void
dtrace_dofattr2attr(dtrace_attribute_t * attr,const dof_attr_t dofattr)9338 dtrace_dofattr2attr(dtrace_attribute_t *attr, const dof_attr_t dofattr)
9339 {
9340 attr->dtat_name = DOF_ATTR_NAME(dofattr);
9341 attr->dtat_data = DOF_ATTR_DATA(dofattr);
9342 attr->dtat_class = DOF_ATTR_CLASS(dofattr);
9343 }
9344
9345 static void
dtrace_dofprov2hprov(dtrace_helper_provdesc_t * hprov,const dof_provider_t * dofprov,char * strtab)9346 dtrace_dofprov2hprov(dtrace_helper_provdesc_t *hprov,
9347 const dof_provider_t *dofprov, char *strtab)
9348 {
9349 hprov->dthpv_provname = strtab + dofprov->dofpv_name;
9350 dtrace_dofattr2attr(&hprov->dthpv_pattr.dtpa_provider,
9351 dofprov->dofpv_provattr);
9352 dtrace_dofattr2attr(&hprov->dthpv_pattr.dtpa_mod,
9353 dofprov->dofpv_modattr);
9354 dtrace_dofattr2attr(&hprov->dthpv_pattr.dtpa_func,
9355 dofprov->dofpv_funcattr);
9356 dtrace_dofattr2attr(&hprov->dthpv_pattr.dtpa_name,
9357 dofprov->dofpv_nameattr);
9358 dtrace_dofattr2attr(&hprov->dthpv_pattr.dtpa_args,
9359 dofprov->dofpv_argsattr);
9360 }
9361
9362 static void
dtrace_helper_provide_one(dof_helper_t * dhp,dof_sec_t * sec,proc_t * p)9363 dtrace_helper_provide_one(dof_helper_t *dhp, dof_sec_t *sec, proc_t *p)
9364 {
9365 uintptr_t daddr = (uintptr_t)dhp->dofhp_dof;
9366 dof_hdr_t *dof = (dof_hdr_t *)daddr;
9367 dof_sec_t *str_sec, *prb_sec, *arg_sec, *off_sec, *enoff_sec;
9368 dof_provider_t *provider;
9369 dof_probe_t *probe;
9370 uint32_t *off, *enoff;
9371 uint8_t *arg;
9372 char *strtab;
9373 uint_t i, nprobes;
9374 dtrace_helper_provdesc_t dhpv;
9375 dtrace_helper_probedesc_t dhpb;
9376 dtrace_meta_t *meta = dtrace_meta_pid;
9377 dtrace_mops_t *mops = &meta->dtm_mops;
9378 void *parg;
9379
9380 provider = (dof_provider_t *)(uintptr_t)(daddr + sec->dofs_offset);
9381 str_sec = (dof_sec_t *)(uintptr_t)(daddr + dof->dofh_secoff +
9382 provider->dofpv_strtab * dof->dofh_secsize);
9383 prb_sec = (dof_sec_t *)(uintptr_t)(daddr + dof->dofh_secoff +
9384 provider->dofpv_probes * dof->dofh_secsize);
9385 arg_sec = (dof_sec_t *)(uintptr_t)(daddr + dof->dofh_secoff +
9386 provider->dofpv_prargs * dof->dofh_secsize);
9387 off_sec = (dof_sec_t *)(uintptr_t)(daddr + dof->dofh_secoff +
9388 provider->dofpv_proffs * dof->dofh_secsize);
9389
9390 strtab = (char *)(uintptr_t)(daddr + str_sec->dofs_offset);
9391 off = (uint32_t *)(uintptr_t)(daddr + off_sec->dofs_offset);
9392 arg = (uint8_t *)(uintptr_t)(daddr + arg_sec->dofs_offset);
9393 enoff = NULL;
9394
9395 /*
9396 * See dtrace_helper_provider_validate().
9397 */
9398 if (dof->dofh_ident[DOF_ID_VERSION] != DOF_VERSION_1 &&
9399 provider->dofpv_prenoffs != DOF_SECT_NONE) {
9400 enoff_sec = (dof_sec_t *)(uintptr_t)(daddr + dof->dofh_secoff +
9401 provider->dofpv_prenoffs * dof->dofh_secsize);
9402 enoff = (uint32_t *)(uintptr_t)(daddr + enoff_sec->dofs_offset);
9403 }
9404
9405 nprobes = prb_sec->dofs_size / prb_sec->dofs_entsize;
9406
9407 /*
9408 * Create the provider.
9409 */
9410 dtrace_dofprov2hprov(&dhpv, provider, strtab);
9411
9412 if ((parg = mops->dtms_provide_proc(meta->dtm_arg, &dhpv, p)) == NULL)
9413 return;
9414
9415 meta->dtm_count++;
9416
9417 /*
9418 * Create the probes.
9419 */
9420 for (i = 0; i < nprobes; i++) {
9421 probe = (dof_probe_t *)(uintptr_t)(daddr +
9422 prb_sec->dofs_offset + i * prb_sec->dofs_entsize);
9423
9424 dhpb.dthpb_mod = dhp->dofhp_mod;
9425 dhpb.dthpb_func = strtab + probe->dofpr_func;
9426 dhpb.dthpb_name = strtab + probe->dofpr_name;
9427 #if !defined(__APPLE__)
9428 dhpb.dthpb_base = probe->dofpr_addr;
9429 #else
9430 dhpb.dthpb_base = dhp->dofhp_addr; /* FIXME: James, why? */
9431 #endif
9432 dhpb.dthpb_offs = (int32_t *)(off + probe->dofpr_offidx);
9433 dhpb.dthpb_noffs = probe->dofpr_noffs;
9434 if (enoff != NULL) {
9435 dhpb.dthpb_enoffs = (int32_t *)(enoff + probe->dofpr_enoffidx);
9436 dhpb.dthpb_nenoffs = probe->dofpr_nenoffs;
9437 } else {
9438 dhpb.dthpb_enoffs = NULL;
9439 dhpb.dthpb_nenoffs = 0;
9440 }
9441 dhpb.dthpb_args = arg + probe->dofpr_argidx;
9442 dhpb.dthpb_nargc = probe->dofpr_nargc;
9443 dhpb.dthpb_xargc = probe->dofpr_xargc;
9444 dhpb.dthpb_ntypes = strtab + probe->dofpr_nargv;
9445 dhpb.dthpb_xtypes = strtab + probe->dofpr_xargv;
9446
9447 mops->dtms_create_probe(meta->dtm_arg, parg, &dhpb);
9448 }
9449
9450 /*
9451 * Since we just created probes, we need to match our enablings
9452 * against those, with a precondition knowing that we have only
9453 * added probes from this provider
9454 */
9455 char *prov_name = mops->dtms_provider_name(parg);
9456 ASSERT(prov_name != NULL);
9457 dtrace_match_cond_t cond = {dtrace_cond_provider_match, (void*)prov_name};
9458
9459 dtrace_enabling_matchall_with_cond(&cond);
9460 }
9461
9462 static void
dtrace_helper_provide(dof_helper_t * dhp,proc_t * p)9463 dtrace_helper_provide(dof_helper_t *dhp, proc_t *p)
9464 {
9465 uintptr_t daddr = (uintptr_t)dhp->dofhp_dof;
9466 dof_hdr_t *dof = (dof_hdr_t *)daddr;
9467 uint32_t i;
9468
9469 LCK_MTX_ASSERT(&dtrace_meta_lock, LCK_MTX_ASSERT_OWNED);
9470
9471 for (i = 0; i < dof->dofh_secnum; i++) {
9472 dof_sec_t *sec = (dof_sec_t *)(uintptr_t)(daddr +
9473 dof->dofh_secoff + i * dof->dofh_secsize);
9474
9475 if (sec->dofs_type != DOF_SECT_PROVIDER)
9476 continue;
9477
9478 dtrace_helper_provide_one(dhp, sec, p);
9479 }
9480 }
9481
9482 static void
dtrace_helper_provider_remove_one(dof_helper_t * dhp,dof_sec_t * sec,proc_t * p)9483 dtrace_helper_provider_remove_one(dof_helper_t *dhp, dof_sec_t *sec, proc_t *p)
9484 {
9485 uintptr_t daddr = (uintptr_t)dhp->dofhp_dof;
9486 dof_hdr_t *dof = (dof_hdr_t *)daddr;
9487 dof_sec_t *str_sec;
9488 dof_provider_t *provider;
9489 char *strtab;
9490 dtrace_helper_provdesc_t dhpv;
9491 dtrace_meta_t *meta = dtrace_meta_pid;
9492 dtrace_mops_t *mops = &meta->dtm_mops;
9493
9494 provider = (dof_provider_t *)(uintptr_t)(daddr + sec->dofs_offset);
9495 str_sec = (dof_sec_t *)(uintptr_t)(daddr + dof->dofh_secoff +
9496 provider->dofpv_strtab * dof->dofh_secsize);
9497
9498 strtab = (char *)(uintptr_t)(daddr + str_sec->dofs_offset);
9499
9500 /*
9501 * Create the provider.
9502 */
9503 dtrace_dofprov2hprov(&dhpv, provider, strtab);
9504
9505 mops->dtms_remove_proc(meta->dtm_arg, &dhpv, p);
9506
9507 meta->dtm_count--;
9508 }
9509
9510 static void
dtrace_helper_provider_remove(dof_helper_t * dhp,proc_t * p)9511 dtrace_helper_provider_remove(dof_helper_t *dhp, proc_t *p)
9512 {
9513 uintptr_t daddr = (uintptr_t)dhp->dofhp_dof;
9514 dof_hdr_t *dof = (dof_hdr_t *)daddr;
9515 uint32_t i;
9516
9517 LCK_MTX_ASSERT(&dtrace_meta_lock, LCK_MTX_ASSERT_OWNED);
9518
9519 for (i = 0; i < dof->dofh_secnum; i++) {
9520 dof_sec_t *sec = (dof_sec_t *)(uintptr_t)(daddr +
9521 dof->dofh_secoff + i * dof->dofh_secsize);
9522
9523 if (sec->dofs_type != DOF_SECT_PROVIDER)
9524 continue;
9525
9526 dtrace_helper_provider_remove_one(dhp, sec, p);
9527 }
9528 }
9529
9530 /*
9531 * DTrace Meta Provider-to-Framework API Functions
9532 *
9533 * These functions implement the Meta Provider-to-Framework API, as described
9534 * in <sys/dtrace.h>.
9535 */
9536 int
dtrace_meta_register(const char * name,const dtrace_mops_t * mops,void * arg,dtrace_meta_provider_id_t * idp)9537 dtrace_meta_register(const char *name, const dtrace_mops_t *mops, void *arg,
9538 dtrace_meta_provider_id_t *idp)
9539 {
9540 dtrace_meta_t *meta;
9541 dtrace_helpers_t *help, *next;
9542 uint_t i;
9543
9544 *idp = DTRACE_METAPROVNONE;
9545
9546 /*
9547 * We strictly don't need the name, but we hold onto it for
9548 * debuggability. All hail error queues!
9549 */
9550 if (name == NULL) {
9551 cmn_err(CE_WARN, "failed to register meta-provider: "
9552 "invalid name");
9553 return (EINVAL);
9554 }
9555
9556 if (mops == NULL ||
9557 mops->dtms_create_probe == NULL ||
9558 mops->dtms_provide_proc == NULL ||
9559 mops->dtms_remove_proc == NULL) {
9560 cmn_err(CE_WARN, "failed to register meta-register %s: "
9561 "invalid ops", name);
9562 return (EINVAL);
9563 }
9564
9565 meta = kmem_zalloc(sizeof (dtrace_meta_t), KM_SLEEP);
9566 meta->dtm_mops = *mops;
9567 meta->dtm_arg = arg;
9568
9569 lck_mtx_lock(&dtrace_meta_lock);
9570 lck_mtx_lock(&dtrace_lock);
9571
9572 if (dtrace_meta_pid != NULL) {
9573 lck_mtx_unlock(&dtrace_lock);
9574 lck_mtx_unlock(&dtrace_meta_lock);
9575 cmn_err(CE_WARN, "failed to register meta-register %s: "
9576 "user-land meta-provider exists", name);
9577 kmem_free(meta, sizeof (dtrace_meta_t));
9578 return (EINVAL);
9579 }
9580
9581 meta->dtm_name = dtrace_strref(name);
9582
9583 dtrace_meta_pid = meta;
9584 *idp = (dtrace_meta_provider_id_t)meta;
9585
9586 /*
9587 * If there are providers and probes ready to go, pass them
9588 * off to the new meta provider now.
9589 */
9590
9591 help = dtrace_deferred_pid;
9592 dtrace_deferred_pid = NULL;
9593
9594 lck_mtx_unlock(&dtrace_lock);
9595
9596 while (help != NULL) {
9597 for (i = 0; i < help->dthps_nprovs; i++) {
9598 proc_t *p = proc_find(help->dthps_pid);
9599 if (p == PROC_NULL)
9600 continue;
9601 dtrace_helper_provide(&help->dthps_provs[i]->dthp_prov,
9602 p);
9603 proc_rele(p);
9604 }
9605
9606 next = help->dthps_next;
9607 help->dthps_next = NULL;
9608 help->dthps_prev = NULL;
9609 help->dthps_deferred = 0;
9610 help = next;
9611 }
9612
9613 lck_mtx_unlock(&dtrace_meta_lock);
9614
9615 return (0);
9616 }
9617
9618 int
dtrace_meta_unregister(dtrace_meta_provider_id_t id)9619 dtrace_meta_unregister(dtrace_meta_provider_id_t id)
9620 {
9621 dtrace_meta_t **pp, *old = (dtrace_meta_t *)id;
9622
9623 lck_mtx_lock(&dtrace_meta_lock);
9624 lck_mtx_lock(&dtrace_lock);
9625
9626 if (old == dtrace_meta_pid) {
9627 pp = &dtrace_meta_pid;
9628 } else {
9629 panic("attempt to unregister non-existent "
9630 "dtrace meta-provider %p\n", (void *)old);
9631 }
9632
9633 if (old->dtm_count != 0) {
9634 lck_mtx_unlock(&dtrace_lock);
9635 lck_mtx_unlock(&dtrace_meta_lock);
9636 return (EBUSY);
9637 }
9638
9639 *pp = NULL;
9640
9641 dtrace_strunref(old->dtm_name);
9642
9643 lck_mtx_unlock(&dtrace_lock);
9644 lck_mtx_unlock(&dtrace_meta_lock);
9645
9646 kmem_free(old, sizeof (dtrace_meta_t));
9647
9648 return (0);
9649 }
9650
9651
9652 /*
9653 * DTrace DIF Object Functions
9654 */
9655 static int
dtrace_difo_err(uint_t pc,const char * format,...)9656 dtrace_difo_err(uint_t pc, const char *format, ...)
9657 {
9658 if (dtrace_err_verbose) {
9659 va_list alist;
9660
9661 (void) uprintf("dtrace DIF object error: [%u]: ", pc);
9662 va_start(alist, format);
9663 (void) vuprintf(format, alist);
9664 va_end(alist);
9665 }
9666
9667 #ifdef DTRACE_ERRDEBUG
9668 dtrace_errdebug(format);
9669 #endif
9670 return (1);
9671 }
9672
9673 /*
9674 * Validate a DTrace DIF object by checking the IR instructions. The following
9675 * rules are currently enforced by dtrace_difo_validate():
9676 *
9677 * 1. Each instruction must have a valid opcode
9678 * 2. Each register, string, variable, or subroutine reference must be valid
9679 * 3. No instruction can modify register %r0 (must be zero)
9680 * 4. All instruction reserved bits must be set to zero
9681 * 5. The last instruction must be a "ret" instruction
9682 * 6. All branch targets must reference a valid instruction _after_ the branch
9683 */
9684 static int
dtrace_difo_validate(dtrace_difo_t * dp,dtrace_vstate_t * vstate,uint_t nregs,cred_t * cr)9685 dtrace_difo_validate(dtrace_difo_t *dp, dtrace_vstate_t *vstate, uint_t nregs,
9686 cred_t *cr)
9687 {
9688 int err = 0;
9689 uint_t i;
9690
9691 int (*efunc)(uint_t pc, const char *, ...) = dtrace_difo_err;
9692 int kcheckload;
9693 uint_t pc;
9694 int maxglobal = -1, maxlocal = -1, maxtlocal = -1;
9695
9696 kcheckload = cr == NULL ||
9697 (vstate->dtvs_state->dts_cred.dcr_visible & DTRACE_CRV_KERNEL) == 0;
9698
9699 dp->dtdo_destructive = 0;
9700
9701 for (pc = 0; pc < dp->dtdo_len && err == 0; pc++) {
9702 dif_instr_t instr = dp->dtdo_buf[pc];
9703
9704 uint_t r1 = DIF_INSTR_R1(instr);
9705 uint_t r2 = DIF_INSTR_R2(instr);
9706 uint_t rd = DIF_INSTR_RD(instr);
9707 uint_t rs = DIF_INSTR_RS(instr);
9708 uint_t label = DIF_INSTR_LABEL(instr);
9709 uint_t v = DIF_INSTR_VAR(instr);
9710 uint_t subr = DIF_INSTR_SUBR(instr);
9711 uint_t type = DIF_INSTR_TYPE(instr);
9712 uint_t op = DIF_INSTR_OP(instr);
9713
9714 switch (op) {
9715 case DIF_OP_OR:
9716 case DIF_OP_XOR:
9717 case DIF_OP_AND:
9718 case DIF_OP_SLL:
9719 case DIF_OP_SRL:
9720 case DIF_OP_SRA:
9721 case DIF_OP_SUB:
9722 case DIF_OP_ADD:
9723 case DIF_OP_MUL:
9724 case DIF_OP_SDIV:
9725 case DIF_OP_UDIV:
9726 case DIF_OP_SREM:
9727 case DIF_OP_UREM:
9728 case DIF_OP_COPYS:
9729 if (r1 >= nregs)
9730 err += efunc(pc, "invalid register %u\n", r1);
9731 if (r2 >= nregs)
9732 err += efunc(pc, "invalid register %u\n", r2);
9733 if (rd >= nregs)
9734 err += efunc(pc, "invalid register %u\n", rd);
9735 if (rd == 0)
9736 err += efunc(pc, "cannot write to %%r0\n");
9737 break;
9738 case DIF_OP_NOT:
9739 case DIF_OP_MOV:
9740 case DIF_OP_ALLOCS:
9741 if (r1 >= nregs)
9742 err += efunc(pc, "invalid register %u\n", r1);
9743 if (r2 != 0)
9744 err += efunc(pc, "non-zero reserved bits\n");
9745 if (rd >= nregs)
9746 err += efunc(pc, "invalid register %u\n", rd);
9747 if (rd == 0)
9748 err += efunc(pc, "cannot write to %%r0\n");
9749 break;
9750 case DIF_OP_LDSB:
9751 case DIF_OP_LDSH:
9752 case DIF_OP_LDSW:
9753 case DIF_OP_LDUB:
9754 case DIF_OP_LDUH:
9755 case DIF_OP_LDUW:
9756 case DIF_OP_LDX:
9757 if (r1 >= nregs)
9758 err += efunc(pc, "invalid register %u\n", r1);
9759 if (r2 != 0)
9760 err += efunc(pc, "non-zero reserved bits\n");
9761 if (rd >= nregs)
9762 err += efunc(pc, "invalid register %u\n", rd);
9763 if (rd == 0)
9764 err += efunc(pc, "cannot write to %%r0\n");
9765 if (kcheckload)
9766 dp->dtdo_buf[pc] = DIF_INSTR_LOAD(op +
9767 DIF_OP_RLDSB - DIF_OP_LDSB, r1, rd);
9768 break;
9769 case DIF_OP_RLDSB:
9770 case DIF_OP_RLDSH:
9771 case DIF_OP_RLDSW:
9772 case DIF_OP_RLDUB:
9773 case DIF_OP_RLDUH:
9774 case DIF_OP_RLDUW:
9775 case DIF_OP_RLDX:
9776 if (r1 >= nregs)
9777 err += efunc(pc, "invalid register %u\n", r1);
9778 if (r2 != 0)
9779 err += efunc(pc, "non-zero reserved bits\n");
9780 if (rd >= nregs)
9781 err += efunc(pc, "invalid register %u\n", rd);
9782 if (rd == 0)
9783 err += efunc(pc, "cannot write to %%r0\n");
9784 break;
9785 case DIF_OP_ULDSB:
9786 case DIF_OP_ULDSH:
9787 case DIF_OP_ULDSW:
9788 case DIF_OP_ULDUB:
9789 case DIF_OP_ULDUH:
9790 case DIF_OP_ULDUW:
9791 case DIF_OP_ULDX:
9792 if (r1 >= nregs)
9793 err += efunc(pc, "invalid register %u\n", r1);
9794 if (r2 != 0)
9795 err += efunc(pc, "non-zero reserved bits\n");
9796 if (rd >= nregs)
9797 err += efunc(pc, "invalid register %u\n", rd);
9798 if (rd == 0)
9799 err += efunc(pc, "cannot write to %%r0\n");
9800 break;
9801 case DIF_OP_STB:
9802 case DIF_OP_STH:
9803 case DIF_OP_STW:
9804 case DIF_OP_STX:
9805 if (r1 >= nregs)
9806 err += efunc(pc, "invalid register %u\n", r1);
9807 if (r2 != 0)
9808 err += efunc(pc, "non-zero reserved bits\n");
9809 if (rd >= nregs)
9810 err += efunc(pc, "invalid register %u\n", rd);
9811 if (rd == 0)
9812 err += efunc(pc, "cannot write to 0 address\n");
9813 break;
9814 case DIF_OP_CMP:
9815 case DIF_OP_SCMP:
9816 if (r1 >= nregs)
9817 err += efunc(pc, "invalid register %u\n", r1);
9818 if (r2 >= nregs)
9819 err += efunc(pc, "invalid register %u\n", r2);
9820 if (rd != 0)
9821 err += efunc(pc, "non-zero reserved bits\n");
9822 break;
9823 case DIF_OP_TST:
9824 if (r1 >= nregs)
9825 err += efunc(pc, "invalid register %u\n", r1);
9826 if (r2 != 0 || rd != 0)
9827 err += efunc(pc, "non-zero reserved bits\n");
9828 break;
9829 case DIF_OP_BA:
9830 case DIF_OP_BE:
9831 case DIF_OP_BNE:
9832 case DIF_OP_BG:
9833 case DIF_OP_BGU:
9834 case DIF_OP_BGE:
9835 case DIF_OP_BGEU:
9836 case DIF_OP_BL:
9837 case DIF_OP_BLU:
9838 case DIF_OP_BLE:
9839 case DIF_OP_BLEU:
9840 if (label >= dp->dtdo_len) {
9841 err += efunc(pc, "invalid branch target %u\n",
9842 label);
9843 }
9844 if (label <= pc) {
9845 err += efunc(pc, "backward branch to %u\n",
9846 label);
9847 }
9848 break;
9849 case DIF_OP_RET:
9850 if (r1 != 0 || r2 != 0)
9851 err += efunc(pc, "non-zero reserved bits\n");
9852 if (rd >= nregs)
9853 err += efunc(pc, "invalid register %u\n", rd);
9854 break;
9855 case DIF_OP_NOP:
9856 case DIF_OP_POPTS:
9857 case DIF_OP_FLUSHTS:
9858 if (r1 != 0 || r2 != 0 || rd != 0)
9859 err += efunc(pc, "non-zero reserved bits\n");
9860 break;
9861 case DIF_OP_SETX:
9862 if (DIF_INSTR_INTEGER(instr) >= dp->dtdo_intlen) {
9863 err += efunc(pc, "invalid integer ref %u\n",
9864 DIF_INSTR_INTEGER(instr));
9865 }
9866 if (rd >= nregs)
9867 err += efunc(pc, "invalid register %u\n", rd);
9868 if (rd == 0)
9869 err += efunc(pc, "cannot write to %%r0\n");
9870 break;
9871 case DIF_OP_SETS:
9872 if (DIF_INSTR_STRING(instr) >= dp->dtdo_strlen) {
9873 err += efunc(pc, "invalid string ref %u\n",
9874 DIF_INSTR_STRING(instr));
9875 }
9876 if (rd >= nregs)
9877 err += efunc(pc, "invalid register %u\n", rd);
9878 if (rd == 0)
9879 err += efunc(pc, "cannot write to %%r0\n");
9880 break;
9881 case DIF_OP_LDGA:
9882 case DIF_OP_LDTA:
9883 if (r1 > DIF_VAR_ARRAY_MAX)
9884 err += efunc(pc, "invalid array %u\n", r1);
9885 if (r2 >= nregs)
9886 err += efunc(pc, "invalid register %u\n", r2);
9887 if (rd >= nregs)
9888 err += efunc(pc, "invalid register %u\n", rd);
9889 if (rd == 0)
9890 err += efunc(pc, "cannot write to %%r0\n");
9891 break;
9892 case DIF_OP_LDGS:
9893 case DIF_OP_LDTS:
9894 case DIF_OP_LDLS:
9895 case DIF_OP_LDGAA:
9896 case DIF_OP_LDTAA:
9897 if (v < DIF_VAR_OTHER_MIN || v > DIF_VAR_OTHER_MAX)
9898 err += efunc(pc, "invalid variable %u\n", v);
9899 if (rd >= nregs)
9900 err += efunc(pc, "invalid register %u\n", rd);
9901 if (rd == 0)
9902 err += efunc(pc, "cannot write to %%r0\n");
9903 break;
9904 case DIF_OP_STGS:
9905 case DIF_OP_STTS:
9906 case DIF_OP_STLS:
9907 case DIF_OP_STGAA:
9908 case DIF_OP_STTAA:
9909 if (v < DIF_VAR_OTHER_UBASE || v > DIF_VAR_OTHER_MAX)
9910 err += efunc(pc, "invalid variable %u\n", v);
9911 if (rs >= nregs)
9912 err += efunc(pc, "invalid register %u\n", rd);
9913 break;
9914 case DIF_OP_CALL:
9915 if (subr > DIF_SUBR_MAX &&
9916 !(subr >= DIF_SUBR_APPLE_MIN && subr <= DIF_SUBR_APPLE_MAX))
9917 err += efunc(pc, "invalid subr %u\n", subr);
9918 if (rd >= nregs)
9919 err += efunc(pc, "invalid register %u\n", rd);
9920 if (rd == 0)
9921 err += efunc(pc, "cannot write to %%r0\n");
9922
9923 switch (subr) {
9924 case DIF_SUBR_COPYOUT:
9925 case DIF_SUBR_COPYOUTSTR:
9926 case DIF_SUBR_KDEBUG_TRACE:
9927 case DIF_SUBR_KDEBUG_TRACE_STRING:
9928 case DIF_SUBR_PHYSMEM_READ:
9929 case DIF_SUBR_PHYSMEM_WRITE:
9930 case DIF_SUBR_LIVEDUMP:
9931 dp->dtdo_destructive = 1;
9932 break;
9933 default:
9934 break;
9935 }
9936 break;
9937 case DIF_OP_PUSHTR:
9938 if (type != DIF_TYPE_STRING && type != DIF_TYPE_CTF)
9939 err += efunc(pc, "invalid ref type %u\n", type);
9940 if (r2 >= nregs)
9941 err += efunc(pc, "invalid register %u\n", r2);
9942 if (rs >= nregs)
9943 err += efunc(pc, "invalid register %u\n", rs);
9944 break;
9945 case DIF_OP_PUSHTV:
9946 if (type != DIF_TYPE_CTF)
9947 err += efunc(pc, "invalid val type %u\n", type);
9948 if (r2 >= nregs)
9949 err += efunc(pc, "invalid register %u\n", r2);
9950 if (rs >= nregs)
9951 err += efunc(pc, "invalid register %u\n", rs);
9952 break;
9953 case DIF_OP_STRIP:
9954 if (r1 >= nregs)
9955 err += efunc(pc, "invalid register %u\n", r1);
9956 if (!dtrace_is_valid_ptrauth_key(r2))
9957 err += efunc(pc, "invalid key\n");
9958 if (rd >= nregs)
9959 err += efunc(pc, "invalid register %u\n", rd);
9960 if (rd == 0)
9961 err += efunc(pc, "cannot write to %%r0\n");
9962 break;
9963 default:
9964 err += efunc(pc, "invalid opcode %u\n",
9965 DIF_INSTR_OP(instr));
9966 }
9967 }
9968
9969 if (dp->dtdo_len != 0 &&
9970 DIF_INSTR_OP(dp->dtdo_buf[dp->dtdo_len - 1]) != DIF_OP_RET) {
9971 err += efunc(dp->dtdo_len - 1,
9972 "expected 'ret' as last DIF instruction\n");
9973 }
9974
9975 if (!(dp->dtdo_rtype.dtdt_flags & (DIF_TF_BYREF | DIF_TF_BYUREF))) {
9976 /*
9977 * If we're not returning by reference, the size must be either
9978 * 0 or the size of one of the base types.
9979 */
9980 switch (dp->dtdo_rtype.dtdt_size) {
9981 case 0:
9982 case sizeof (uint8_t):
9983 case sizeof (uint16_t):
9984 case sizeof (uint32_t):
9985 case sizeof (uint64_t):
9986 break;
9987
9988 default:
9989 err += efunc(dp->dtdo_len - 1, "bad return size\n");
9990 }
9991 }
9992
9993 for (i = 0; i < dp->dtdo_varlen && err == 0; i++) {
9994 dtrace_difv_t *v = &dp->dtdo_vartab[i], *existing = NULL;
9995 dtrace_diftype_t *vt, *et;
9996 uint_t id;
9997 int ndx;
9998
9999 if (v->dtdv_scope != DIFV_SCOPE_GLOBAL &&
10000 v->dtdv_scope != DIFV_SCOPE_THREAD &&
10001 v->dtdv_scope != DIFV_SCOPE_LOCAL) {
10002 err += efunc(i, "unrecognized variable scope %d\n",
10003 v->dtdv_scope);
10004 break;
10005 }
10006
10007 if (v->dtdv_kind != DIFV_KIND_ARRAY &&
10008 v->dtdv_kind != DIFV_KIND_SCALAR) {
10009 err += efunc(i, "unrecognized variable type %d\n",
10010 v->dtdv_kind);
10011 break;
10012 }
10013
10014 if ((id = v->dtdv_id) > DIF_VARIABLE_MAX) {
10015 err += efunc(i, "%d exceeds variable id limit\n", id);
10016 break;
10017 }
10018
10019 if (id < DIF_VAR_OTHER_UBASE)
10020 continue;
10021
10022 /*
10023 * For user-defined variables, we need to check that this
10024 * definition is identical to any previous definition that we
10025 * encountered.
10026 */
10027 ndx = id - DIF_VAR_OTHER_UBASE;
10028
10029 switch (v->dtdv_scope) {
10030 case DIFV_SCOPE_GLOBAL:
10031 if (maxglobal == -1 || ndx > maxglobal)
10032 maxglobal = ndx;
10033
10034 if (ndx < vstate->dtvs_nglobals) {
10035 dtrace_statvar_t *svar;
10036
10037 if ((svar = vstate->dtvs_globals[ndx]) != NULL)
10038 existing = &svar->dtsv_var;
10039 }
10040
10041 break;
10042
10043 case DIFV_SCOPE_THREAD:
10044 if (maxtlocal == -1 || ndx > maxtlocal)
10045 maxtlocal = ndx;
10046
10047 if (ndx < vstate->dtvs_ntlocals)
10048 existing = &vstate->dtvs_tlocals[ndx];
10049 break;
10050
10051 case DIFV_SCOPE_LOCAL:
10052 if (maxlocal == -1 || ndx > maxlocal)
10053 maxlocal = ndx;
10054 if (ndx < vstate->dtvs_nlocals) {
10055 dtrace_statvar_t *svar;
10056
10057 if ((svar = vstate->dtvs_locals[ndx]) != NULL)
10058 existing = &svar->dtsv_var;
10059 }
10060
10061 break;
10062 }
10063
10064 vt = &v->dtdv_type;
10065
10066 if (vt->dtdt_flags & DIF_TF_BYREF) {
10067 if (vt->dtdt_size == 0) {
10068 err += efunc(i, "zero-sized variable\n");
10069 break;
10070 }
10071
10072 if ((v->dtdv_scope == DIFV_SCOPE_GLOBAL ||
10073 v->dtdv_scope == DIFV_SCOPE_LOCAL) &&
10074 vt->dtdt_size > dtrace_statvar_maxsize) {
10075 err += efunc(i, "oversized by-ref static\n");
10076 break;
10077 }
10078 }
10079
10080 if (existing == NULL || existing->dtdv_id == 0)
10081 continue;
10082
10083 ASSERT(existing->dtdv_id == v->dtdv_id);
10084 ASSERT(existing->dtdv_scope == v->dtdv_scope);
10085
10086 if (existing->dtdv_kind != v->dtdv_kind)
10087 err += efunc(i, "%d changed variable kind\n", id);
10088
10089 et = &existing->dtdv_type;
10090
10091 if (vt->dtdt_flags != et->dtdt_flags) {
10092 err += efunc(i, "%d changed variable type flags\n", id);
10093 break;
10094 }
10095
10096 if (vt->dtdt_size != 0 && vt->dtdt_size != et->dtdt_size) {
10097 err += efunc(i, "%d changed variable type size\n", id);
10098 break;
10099 }
10100 }
10101
10102 for (pc = 0; pc < dp->dtdo_len && err == 0; pc++) {
10103 dif_instr_t instr = dp->dtdo_buf[pc];
10104
10105 uint_t v = DIF_INSTR_VAR(instr);
10106 uint_t op = DIF_INSTR_OP(instr);
10107
10108 switch (op) {
10109 case DIF_OP_LDGS:
10110 case DIF_OP_LDGAA:
10111 case DIF_OP_STGS:
10112 case DIF_OP_STGAA:
10113 if (v > (uint_t)(DIF_VAR_OTHER_UBASE + maxglobal))
10114 err += efunc(pc, "invalid variable %u\n", v);
10115 break;
10116 case DIF_OP_LDTS:
10117 case DIF_OP_LDTAA:
10118 case DIF_OP_STTS:
10119 case DIF_OP_STTAA:
10120 if (v > (uint_t)(DIF_VAR_OTHER_UBASE + maxtlocal))
10121 err += efunc(pc, "invalid variable %u\n", v);
10122 break;
10123 case DIF_OP_LDLS:
10124 case DIF_OP_STLS:
10125 if (v > (uint_t)(DIF_VAR_OTHER_UBASE + maxlocal))
10126 err += efunc(pc, "invalid variable %u\n", v);
10127 break;
10128 default:
10129 break;
10130 }
10131 }
10132
10133 return (err);
10134 }
10135
10136 /*
10137 * Validate a DTrace DIF object that it is to be used as a helper. Helpers
10138 * are much more constrained than normal DIFOs. Specifically, they may
10139 * not:
10140 *
10141 * 1. Make calls to subroutines other than copyin(), copyinstr() or
10142 * miscellaneous string routines
10143 * 2. Access DTrace variables other than the args[] array, and the
10144 * curthread, pid, ppid, tid, execname, zonename, uid and gid variables.
10145 * 3. Have thread-local variables.
10146 * 4. Have dynamic variables.
10147 */
10148 static int
dtrace_difo_validate_helper(dtrace_difo_t * dp)10149 dtrace_difo_validate_helper(dtrace_difo_t *dp)
10150 {
10151 int (*efunc)(uint_t pc, const char *, ...) = dtrace_difo_err;
10152 int err = 0;
10153 uint_t pc;
10154
10155 for (pc = 0; pc < dp->dtdo_len; pc++) {
10156 dif_instr_t instr = dp->dtdo_buf[pc];
10157
10158 uint_t v = DIF_INSTR_VAR(instr);
10159 uint_t subr = DIF_INSTR_SUBR(instr);
10160 uint_t op = DIF_INSTR_OP(instr);
10161
10162 switch (op) {
10163 case DIF_OP_OR:
10164 case DIF_OP_XOR:
10165 case DIF_OP_AND:
10166 case DIF_OP_SLL:
10167 case DIF_OP_SRL:
10168 case DIF_OP_SRA:
10169 case DIF_OP_SUB:
10170 case DIF_OP_ADD:
10171 case DIF_OP_MUL:
10172 case DIF_OP_SDIV:
10173 case DIF_OP_UDIV:
10174 case DIF_OP_SREM:
10175 case DIF_OP_UREM:
10176 case DIF_OP_COPYS:
10177 case DIF_OP_NOT:
10178 case DIF_OP_MOV:
10179 case DIF_OP_RLDSB:
10180 case DIF_OP_RLDSH:
10181 case DIF_OP_RLDSW:
10182 case DIF_OP_RLDUB:
10183 case DIF_OP_RLDUH:
10184 case DIF_OP_RLDUW:
10185 case DIF_OP_RLDX:
10186 case DIF_OP_ULDSB:
10187 case DIF_OP_ULDSH:
10188 case DIF_OP_ULDSW:
10189 case DIF_OP_ULDUB:
10190 case DIF_OP_ULDUH:
10191 case DIF_OP_ULDUW:
10192 case DIF_OP_ULDX:
10193 case DIF_OP_STB:
10194 case DIF_OP_STH:
10195 case DIF_OP_STW:
10196 case DIF_OP_STX:
10197 case DIF_OP_ALLOCS:
10198 case DIF_OP_CMP:
10199 case DIF_OP_SCMP:
10200 case DIF_OP_TST:
10201 case DIF_OP_BA:
10202 case DIF_OP_BE:
10203 case DIF_OP_BNE:
10204 case DIF_OP_BG:
10205 case DIF_OP_BGU:
10206 case DIF_OP_BGE:
10207 case DIF_OP_BGEU:
10208 case DIF_OP_BL:
10209 case DIF_OP_BLU:
10210 case DIF_OP_BLE:
10211 case DIF_OP_BLEU:
10212 case DIF_OP_RET:
10213 case DIF_OP_NOP:
10214 case DIF_OP_POPTS:
10215 case DIF_OP_FLUSHTS:
10216 case DIF_OP_SETX:
10217 case DIF_OP_SETS:
10218 case DIF_OP_LDGA:
10219 case DIF_OP_LDLS:
10220 case DIF_OP_STGS:
10221 case DIF_OP_STLS:
10222 case DIF_OP_PUSHTR:
10223 case DIF_OP_PUSHTV:
10224 break;
10225
10226 case DIF_OP_LDGS:
10227 if (v >= DIF_VAR_OTHER_UBASE)
10228 break;
10229
10230 if (v >= DIF_VAR_ARG0 && v <= DIF_VAR_ARG9)
10231 break;
10232
10233 if (v == DIF_VAR_CURTHREAD || v == DIF_VAR_PID ||
10234 v == DIF_VAR_PPID || v == DIF_VAR_TID ||
10235 v == DIF_VAR_EXECNAME || v == DIF_VAR_ZONENAME ||
10236 v == DIF_VAR_UID || v == DIF_VAR_GID)
10237 break;
10238
10239 err += efunc(pc, "illegal variable %u\n", v);
10240 break;
10241
10242 case DIF_OP_LDTA:
10243 case DIF_OP_LDTS:
10244 case DIF_OP_LDGAA:
10245 case DIF_OP_LDTAA:
10246 err += efunc(pc, "illegal dynamic variable load\n");
10247 break;
10248
10249 case DIF_OP_STTS:
10250 case DIF_OP_STGAA:
10251 case DIF_OP_STTAA:
10252 err += efunc(pc, "illegal dynamic variable store\n");
10253 break;
10254
10255 case DIF_OP_CALL:
10256 switch (subr) {
10257 case DIF_SUBR_ALLOCA:
10258 case DIF_SUBR_BCOPY:
10259 case DIF_SUBR_COPYIN:
10260 case DIF_SUBR_COPYINTO:
10261 case DIF_SUBR_COPYINSTR:
10262 case DIF_SUBR_HTONS:
10263 case DIF_SUBR_HTONL:
10264 case DIF_SUBR_HTONLL:
10265 case DIF_SUBR_INDEX:
10266 case DIF_SUBR_INET_NTOA:
10267 case DIF_SUBR_INET_NTOA6:
10268 case DIF_SUBR_INET_NTOP:
10269 case DIF_SUBR_JSON:
10270 case DIF_SUBR_LLTOSTR:
10271 case DIF_SUBR_NTOHS:
10272 case DIF_SUBR_NTOHL:
10273 case DIF_SUBR_NTOHLL:
10274 case DIF_SUBR_RINDEX:
10275 case DIF_SUBR_STRCHR:
10276 case DIF_SUBR_STRTOLL:
10277 case DIF_SUBR_STRJOIN:
10278 case DIF_SUBR_STRRCHR:
10279 case DIF_SUBR_STRSTR:
10280 break;
10281 default:
10282 err += efunc(pc, "invalid subr %u\n", subr);
10283 }
10284 break;
10285
10286 default:
10287 err += efunc(pc, "invalid opcode %u\n",
10288 DIF_INSTR_OP(instr));
10289 }
10290 }
10291
10292 return (err);
10293 }
10294
10295 /*
10296 * Returns 1 if the expression in the DIF object can be cached on a per-thread
10297 * basis; 0 if not.
10298 */
10299 static int
dtrace_difo_cacheable(dtrace_difo_t * dp)10300 dtrace_difo_cacheable(dtrace_difo_t *dp)
10301 {
10302 uint_t i;
10303
10304 if (dp == NULL)
10305 return (0);
10306
10307 for (i = 0; i < dp->dtdo_varlen; i++) {
10308 dtrace_difv_t *v = &dp->dtdo_vartab[i];
10309
10310 if (v->dtdv_scope != DIFV_SCOPE_GLOBAL)
10311 continue;
10312
10313 switch (v->dtdv_id) {
10314 case DIF_VAR_CURTHREAD:
10315 case DIF_VAR_PID:
10316 case DIF_VAR_TID:
10317 case DIF_VAR_EXECNAME:
10318 case DIF_VAR_ZONENAME:
10319 break;
10320
10321 default:
10322 return (0);
10323 }
10324 }
10325
10326 /*
10327 * This DIF object may be cacheable. Now we need to look for any
10328 * array loading instructions, any memory loading instructions, or
10329 * any stores to thread-local variables.
10330 */
10331 for (i = 0; i < dp->dtdo_len; i++) {
10332 uint_t op = DIF_INSTR_OP(dp->dtdo_buf[i]);
10333
10334 if ((op >= DIF_OP_LDSB && op <= DIF_OP_LDX) ||
10335 (op >= DIF_OP_ULDSB && op <= DIF_OP_ULDX) ||
10336 (op >= DIF_OP_RLDSB && op <= DIF_OP_RLDX) ||
10337 op == DIF_OP_LDGA || op == DIF_OP_STTS)
10338 return (0);
10339 }
10340
10341 return (1);
10342 }
10343
10344 static void
dtrace_difo_hold(dtrace_difo_t * dp)10345 dtrace_difo_hold(dtrace_difo_t *dp)
10346 {
10347 uint_t i;
10348
10349 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
10350
10351 dp->dtdo_refcnt++;
10352 ASSERT(dp->dtdo_refcnt != 0);
10353
10354 /*
10355 * We need to check this DIF object for references to the variable
10356 * DIF_VAR_VTIMESTAMP.
10357 */
10358 for (i = 0; i < dp->dtdo_varlen; i++) {
10359 dtrace_difv_t *v = &dp->dtdo_vartab[i];
10360
10361 if (v->dtdv_id != DIF_VAR_VTIMESTAMP)
10362 continue;
10363
10364 if (dtrace_vtime_references++ == 0)
10365 dtrace_vtime_enable();
10366 }
10367 }
10368
10369 /*
10370 * This routine calculates the dynamic variable chunksize for a given DIF
10371 * object. The calculation is not fool-proof, and can probably be tricked by
10372 * malicious DIF -- but it works for all compiler-generated DIF. Because this
10373 * calculation is likely imperfect, dtrace_dynvar() is able to gracefully fail
10374 * if a dynamic variable size exceeds the chunksize.
10375 */
10376 static void
dtrace_difo_chunksize(dtrace_difo_t * dp,dtrace_vstate_t * vstate)10377 dtrace_difo_chunksize(dtrace_difo_t *dp, dtrace_vstate_t *vstate)
10378 {
10379 uint64_t sval = 0;
10380 dtrace_key_t tupregs[DIF_DTR_NREGS + 2]; /* +2 for thread and id */
10381 const dif_instr_t *text = dp->dtdo_buf;
10382 uint_t pc, srd = 0;
10383 uint_t ttop = 0;
10384 size_t size, ksize;
10385 uint_t id, i;
10386
10387 for (pc = 0; pc < dp->dtdo_len; pc++) {
10388 dif_instr_t instr = text[pc];
10389 uint_t op = DIF_INSTR_OP(instr);
10390 uint_t rd = DIF_INSTR_RD(instr);
10391 uint_t r1 = DIF_INSTR_R1(instr);
10392 uint_t nkeys = 0;
10393 uchar_t scope;
10394
10395 dtrace_key_t *key = tupregs;
10396
10397 switch (op) {
10398 case DIF_OP_SETX:
10399 sval = dp->dtdo_inttab[DIF_INSTR_INTEGER(instr)];
10400 srd = rd;
10401 continue;
10402
10403 case DIF_OP_STTS:
10404 key = &tupregs[DIF_DTR_NREGS];
10405 key[0].dttk_size = 0;
10406 key[1].dttk_size = 0;
10407 nkeys = 2;
10408 scope = DIFV_SCOPE_THREAD;
10409 break;
10410
10411 case DIF_OP_STGAA:
10412 case DIF_OP_STTAA:
10413 nkeys = ttop;
10414
10415 if (DIF_INSTR_OP(instr) == DIF_OP_STTAA)
10416 key[nkeys++].dttk_size = 0;
10417
10418 key[nkeys++].dttk_size = 0;
10419
10420 if (op == DIF_OP_STTAA) {
10421 scope = DIFV_SCOPE_THREAD;
10422 } else {
10423 scope = DIFV_SCOPE_GLOBAL;
10424 }
10425
10426 break;
10427
10428 case DIF_OP_PUSHTR:
10429 if (ttop == DIF_DTR_NREGS)
10430 return;
10431
10432 if ((srd == 0 || sval == 0) && r1 == DIF_TYPE_STRING) {
10433 /*
10434 * If the register for the size of the "pushtr"
10435 * is %r0 (or the value is 0) and the type is
10436 * a string, we'll use the system-wide default
10437 * string size.
10438 */
10439 tupregs[ttop++].dttk_size =
10440 dtrace_strsize_default;
10441 } else {
10442 if (srd == 0)
10443 return;
10444
10445 if (sval > LONG_MAX)
10446 return;
10447
10448 tupregs[ttop++].dttk_size = sval;
10449 }
10450
10451 break;
10452
10453 case DIF_OP_PUSHTV:
10454 if (ttop == DIF_DTR_NREGS)
10455 return;
10456
10457 tupregs[ttop++].dttk_size = 0;
10458 break;
10459
10460 case DIF_OP_FLUSHTS:
10461 ttop = 0;
10462 break;
10463
10464 case DIF_OP_POPTS:
10465 if (ttop != 0)
10466 ttop--;
10467 break;
10468 }
10469
10470 sval = 0;
10471 srd = 0;
10472
10473 if (nkeys == 0)
10474 continue;
10475
10476 /*
10477 * We have a dynamic variable allocation; calculate its size.
10478 */
10479 for (ksize = 0, i = 0; i < nkeys; i++)
10480 ksize += P2ROUNDUP(key[i].dttk_size, sizeof (uint64_t));
10481
10482 size = sizeof (dtrace_dynvar_t);
10483 size += sizeof (dtrace_key_t) * (nkeys - 1);
10484 size += ksize;
10485
10486 /*
10487 * Now we need to determine the size of the stored data.
10488 */
10489 id = DIF_INSTR_VAR(instr);
10490
10491 for (i = 0; i < dp->dtdo_varlen; i++) {
10492 dtrace_difv_t *v = &dp->dtdo_vartab[i];
10493
10494 if (v->dtdv_id == id && v->dtdv_scope == scope) {
10495 size += v->dtdv_type.dtdt_size;
10496 break;
10497 }
10498 }
10499
10500 if (i == dp->dtdo_varlen)
10501 return;
10502
10503 /*
10504 * We have the size. If this is larger than the chunk size
10505 * for our dynamic variable state, reset the chunk size.
10506 */
10507 size = P2ROUNDUP(size, sizeof (uint64_t));
10508
10509 /*
10510 * Before setting the chunk size, check that we're not going
10511 * to set it to a negative value...
10512 */
10513 if (size > LONG_MAX)
10514 return;
10515
10516 /*
10517 * ...and make certain that we didn't badly overflow.
10518 */
10519 if (size < ksize || size < sizeof (dtrace_dynvar_t))
10520 return;
10521
10522 if (size > vstate->dtvs_dynvars.dtds_chunksize)
10523 vstate->dtvs_dynvars.dtds_chunksize = size;
10524 }
10525 }
10526
10527 static void
dtrace_difo_init(dtrace_difo_t * dp,dtrace_vstate_t * vstate)10528 dtrace_difo_init(dtrace_difo_t *dp, dtrace_vstate_t *vstate)
10529 {
10530 int oldsvars, osz, nsz, otlocals, ntlocals;
10531 uint_t i, id;
10532
10533 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
10534 ASSERT(dp->dtdo_buf != NULL && dp->dtdo_len != 0);
10535
10536 for (i = 0; i < dp->dtdo_varlen; i++) {
10537 dtrace_difv_t *v = &dp->dtdo_vartab[i];
10538 dtrace_statvar_t *svar;
10539 dtrace_statvar_t ***svarp = NULL;
10540 size_t dsize = 0;
10541 uint8_t scope = v->dtdv_scope;
10542 int *np = (int *)NULL;
10543
10544 if ((id = v->dtdv_id) < DIF_VAR_OTHER_UBASE)
10545 continue;
10546
10547 id -= DIF_VAR_OTHER_UBASE;
10548
10549 switch (scope) {
10550 case DIFV_SCOPE_THREAD:
10551 while (id >= (uint_t)(otlocals = vstate->dtvs_ntlocals)) {
10552 dtrace_difv_t *tlocals;
10553
10554 if ((ntlocals = (otlocals << 1)) == 0)
10555 ntlocals = 1;
10556
10557 osz = otlocals * sizeof (dtrace_difv_t);
10558 nsz = ntlocals * sizeof (dtrace_difv_t);
10559
10560 tlocals = kmem_zalloc(nsz, KM_SLEEP);
10561
10562 if (osz != 0) {
10563 bcopy(vstate->dtvs_tlocals,
10564 tlocals, osz);
10565 kmem_free(vstate->dtvs_tlocals, osz);
10566 }
10567
10568 vstate->dtvs_tlocals = tlocals;
10569 vstate->dtvs_ntlocals = ntlocals;
10570 }
10571
10572 vstate->dtvs_tlocals[id] = *v;
10573 continue;
10574
10575 case DIFV_SCOPE_LOCAL:
10576 np = &vstate->dtvs_nlocals;
10577 svarp = &vstate->dtvs_locals;
10578
10579 if (v->dtdv_type.dtdt_flags & DIF_TF_BYREF)
10580 dsize = (int)NCPU * (v->dtdv_type.dtdt_size +
10581 sizeof (uint64_t));
10582 else
10583 dsize = (int)NCPU * sizeof (uint64_t);
10584
10585 break;
10586
10587 case DIFV_SCOPE_GLOBAL:
10588 np = &vstate->dtvs_nglobals;
10589 svarp = &vstate->dtvs_globals;
10590
10591 if (v->dtdv_type.dtdt_flags & DIF_TF_BYREF)
10592 dsize = v->dtdv_type.dtdt_size +
10593 sizeof (uint64_t);
10594
10595 break;
10596
10597 default:
10598 ASSERT(0);
10599 }
10600
10601 while (id >= (uint_t)(oldsvars = *np)) {
10602 dtrace_statvar_t **statics;
10603 int newsvars, oldsize, newsize;
10604
10605 if ((newsvars = (oldsvars << 1)) == 0)
10606 newsvars = 1;
10607
10608 oldsize = oldsvars * sizeof (dtrace_statvar_t *);
10609 newsize = newsvars * sizeof (dtrace_statvar_t *);
10610
10611 statics = kmem_zalloc(newsize, KM_SLEEP);
10612
10613 if (oldsize != 0) {
10614 bcopy(*svarp, statics, oldsize);
10615 kmem_free(*svarp, oldsize);
10616 }
10617
10618 *svarp = statics;
10619 *np = newsvars;
10620 }
10621
10622 if ((svar = (*svarp)[id]) == NULL) {
10623 svar = kmem_zalloc(sizeof (dtrace_statvar_t), KM_SLEEP);
10624 svar->dtsv_var = *v;
10625
10626 if ((svar->dtsv_size = dsize) != 0) {
10627 svar->dtsv_data = (uint64_t)(uintptr_t)
10628 kmem_zalloc(dsize, KM_SLEEP);
10629 }
10630
10631 (*svarp)[id] = svar;
10632 }
10633
10634 svar->dtsv_refcnt++;
10635 }
10636
10637 dtrace_difo_chunksize(dp, vstate);
10638 dtrace_difo_hold(dp);
10639 }
10640
10641 static dtrace_difo_t *
dtrace_difo_duplicate(dtrace_difo_t * dp,dtrace_vstate_t * vstate)10642 dtrace_difo_duplicate(dtrace_difo_t *dp, dtrace_vstate_t *vstate)
10643 {
10644 dtrace_difo_t *new;
10645 size_t sz;
10646
10647 ASSERT(dp->dtdo_buf != NULL);
10648 ASSERT(dp->dtdo_refcnt != 0);
10649
10650 new = kmem_zalloc(sizeof (dtrace_difo_t), KM_SLEEP);
10651
10652 ASSERT(dp->dtdo_buf != NULL);
10653 sz = dp->dtdo_len * sizeof (dif_instr_t);
10654 new->dtdo_buf = kmem_alloc(sz, KM_SLEEP);
10655 bcopy(dp->dtdo_buf, new->dtdo_buf, sz);
10656 new->dtdo_len = dp->dtdo_len;
10657
10658 if (dp->dtdo_strtab != NULL) {
10659 ASSERT(dp->dtdo_strlen != 0);
10660 new->dtdo_strtab = kmem_alloc(dp->dtdo_strlen, KM_SLEEP);
10661 bcopy(dp->dtdo_strtab, new->dtdo_strtab, dp->dtdo_strlen);
10662 new->dtdo_strlen = dp->dtdo_strlen;
10663 }
10664
10665 if (dp->dtdo_inttab != NULL) {
10666 ASSERT(dp->dtdo_intlen != 0);
10667 sz = dp->dtdo_intlen * sizeof (uint64_t);
10668 new->dtdo_inttab = kmem_alloc(sz, KM_SLEEP);
10669 bcopy(dp->dtdo_inttab, new->dtdo_inttab, sz);
10670 new->dtdo_intlen = dp->dtdo_intlen;
10671 }
10672
10673 if (dp->dtdo_vartab != NULL) {
10674 ASSERT(dp->dtdo_varlen != 0);
10675 sz = dp->dtdo_varlen * sizeof (dtrace_difv_t);
10676 new->dtdo_vartab = kmem_alloc(sz, KM_SLEEP);
10677 bcopy(dp->dtdo_vartab, new->dtdo_vartab, sz);
10678 new->dtdo_varlen = dp->dtdo_varlen;
10679 }
10680
10681 dtrace_difo_init(new, vstate);
10682 return (new);
10683 }
10684
10685 static void
dtrace_difo_destroy(dtrace_difo_t * dp,dtrace_vstate_t * vstate)10686 dtrace_difo_destroy(dtrace_difo_t *dp, dtrace_vstate_t *vstate)
10687 {
10688 uint_t i;
10689
10690 ASSERT(dp->dtdo_refcnt == 0);
10691
10692 for (i = 0; i < dp->dtdo_varlen; i++) {
10693 dtrace_difv_t *v = &dp->dtdo_vartab[i];
10694 dtrace_statvar_t *svar;
10695 dtrace_statvar_t **svarp = NULL;
10696 uint_t id;
10697 uint8_t scope = v->dtdv_scope;
10698 int *np = NULL;
10699
10700 switch (scope) {
10701 case DIFV_SCOPE_THREAD:
10702 continue;
10703
10704 case DIFV_SCOPE_LOCAL:
10705 np = &vstate->dtvs_nlocals;
10706 svarp = vstate->dtvs_locals;
10707 break;
10708
10709 case DIFV_SCOPE_GLOBAL:
10710 np = &vstate->dtvs_nglobals;
10711 svarp = vstate->dtvs_globals;
10712 break;
10713
10714 default:
10715 ASSERT(0);
10716 }
10717
10718 if ((id = v->dtdv_id) < DIF_VAR_OTHER_UBASE)
10719 continue;
10720
10721 id -= DIF_VAR_OTHER_UBASE;
10722
10723 ASSERT(id < (uint_t)*np);
10724
10725 svar = svarp[id];
10726 ASSERT(svar != NULL);
10727 ASSERT(svar->dtsv_refcnt > 0);
10728
10729 if (--svar->dtsv_refcnt > 0)
10730 continue;
10731
10732 if (svar->dtsv_size != 0) {
10733 ASSERT(svar->dtsv_data != 0);
10734 kmem_free((void *)(uintptr_t)svar->dtsv_data,
10735 svar->dtsv_size);
10736 }
10737
10738 kmem_free(svar, sizeof (dtrace_statvar_t));
10739 svarp[id] = NULL;
10740 }
10741
10742 kmem_free(dp->dtdo_buf, dp->dtdo_len * sizeof (dif_instr_t));
10743 kmem_free(dp->dtdo_inttab, dp->dtdo_intlen * sizeof (uint64_t));
10744 kmem_free(dp->dtdo_strtab, dp->dtdo_strlen);
10745 kmem_free(dp->dtdo_vartab, dp->dtdo_varlen * sizeof (dtrace_difv_t));
10746
10747 kmem_free(dp, sizeof (dtrace_difo_t));
10748 }
10749
10750 static void
dtrace_difo_release(dtrace_difo_t * dp,dtrace_vstate_t * vstate)10751 dtrace_difo_release(dtrace_difo_t *dp, dtrace_vstate_t *vstate)
10752 {
10753 uint_t i;
10754
10755 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
10756 ASSERT(dp->dtdo_refcnt != 0);
10757
10758 for (i = 0; i < dp->dtdo_varlen; i++) {
10759 dtrace_difv_t *v = &dp->dtdo_vartab[i];
10760
10761 if (v->dtdv_id != DIF_VAR_VTIMESTAMP)
10762 continue;
10763
10764 ASSERT(dtrace_vtime_references > 0);
10765 if (--dtrace_vtime_references == 0)
10766 dtrace_vtime_disable();
10767 }
10768
10769 if (--dp->dtdo_refcnt == 0)
10770 dtrace_difo_destroy(dp, vstate);
10771 }
10772
10773 /*
10774 * DTrace Format Functions
10775 */
10776
10777 static dtrace_format_t*
dtrace_format_new(char * str)10778 dtrace_format_new(char *str)
10779 {
10780 dtrace_format_t *fmt = NULL;
10781 size_t bufsize = strlen(str) + 1;
10782
10783 fmt = kmem_zalloc(sizeof(*fmt) + bufsize, KM_SLEEP);
10784
10785 fmt->dtf_refcount = 1;
10786 (void) strlcpy(fmt->dtf_str, str, bufsize);
10787
10788 return fmt;
10789 }
10790
10791 static uint16_t
dtrace_format_add(dtrace_state_t * state,char * str)10792 dtrace_format_add(dtrace_state_t *state, char *str)
10793 {
10794 dtrace_format_t **new;
10795 uint16_t ndx;
10796
10797 for (ndx = 0; ndx < state->dts_nformats; ndx++) {
10798 if (state->dts_formats[ndx] == NULL) {
10799 state->dts_formats[ndx] = dtrace_format_new(str);
10800 return (ndx + 1);
10801 }
10802 else if (strcmp(state->dts_formats[ndx]->dtf_str, str) == 0) {
10803 VERIFY(state->dts_formats[ndx]->dtf_refcount < UINT64_MAX);
10804 state->dts_formats[ndx]->dtf_refcount++;
10805 return (ndx + 1);
10806 }
10807 }
10808
10809 if (state->dts_nformats == USHRT_MAX) {
10810 /*
10811 * This is only likely if a denial-of-service attack is being
10812 * attempted. As such, it's okay to fail silently here.
10813 */
10814 return (0);
10815 }
10816
10817 /*
10818 * For simplicity, we always resize the formats array to be exactly the
10819 * number of formats.
10820 */
10821 ndx = state->dts_nformats++;
10822 new = kmem_alloc((ndx + 1) * sizeof (*state->dts_formats), KM_SLEEP);
10823
10824 if (state->dts_formats != NULL) {
10825 ASSERT(ndx != 0);
10826 bcopy(state->dts_formats, new, ndx * sizeof (*state->dts_formats));
10827 kmem_free(state->dts_formats, ndx * sizeof (*state->dts_formats));
10828 }
10829
10830 state->dts_formats = new;
10831 state->dts_formats[ndx] = dtrace_format_new(str);
10832
10833 return (ndx + 1);
10834 }
10835
10836 static void
dtrace_format_remove(dtrace_state_t * state,uint16_t format)10837 dtrace_format_remove(dtrace_state_t *state, uint16_t format)
10838 {
10839 dtrace_format_t *fmt;
10840
10841 ASSERT(state->dts_formats != NULL);
10842 ASSERT(format <= state->dts_nformats);
10843
10844 fmt = state->dts_formats[format - 1];
10845
10846 ASSERT(fmt != NULL);
10847 VERIFY(fmt->dtf_refcount > 0);
10848
10849 fmt->dtf_refcount--;
10850
10851 if (fmt->dtf_refcount == 0) {
10852 kmem_free(fmt, DTRACE_FORMAT_SIZE(fmt));
10853 state->dts_formats[format - 1] = NULL;
10854 }
10855 }
10856
10857 static void
dtrace_format_destroy(dtrace_state_t * state)10858 dtrace_format_destroy(dtrace_state_t *state)
10859 {
10860 int i;
10861
10862 if (state->dts_nformats == 0) {
10863 ASSERT(state->dts_formats == NULL);
10864 return;
10865 }
10866
10867 ASSERT(state->dts_formats != NULL);
10868
10869 for (i = 0; i < state->dts_nformats; i++) {
10870 dtrace_format_t *fmt = state->dts_formats[i];
10871
10872 if (fmt == NULL)
10873 continue;
10874
10875 kmem_free(fmt, DTRACE_FORMAT_SIZE(fmt));
10876 }
10877
10878 kmem_free(state->dts_formats, state->dts_nformats * sizeof (*state->dts_formats));
10879 state->dts_nformats = 0;
10880 state->dts_formats = NULL;
10881 }
10882
10883 /*
10884 * DTrace Predicate Functions
10885 */
10886 static dtrace_predicate_t *
dtrace_predicate_create(dtrace_difo_t * dp)10887 dtrace_predicate_create(dtrace_difo_t *dp)
10888 {
10889 dtrace_predicate_t *pred;
10890
10891 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
10892 ASSERT(dp->dtdo_refcnt != 0);
10893
10894 pred = kmem_zalloc(sizeof (dtrace_predicate_t), KM_SLEEP);
10895 pred->dtp_difo = dp;
10896 pred->dtp_refcnt = 1;
10897
10898 if (!dtrace_difo_cacheable(dp))
10899 return (pred);
10900
10901 if (dtrace_predcache_id == DTRACE_CACHEIDNONE) {
10902 /*
10903 * This is only theoretically possible -- we have had 2^32
10904 * cacheable predicates on this machine. We cannot allow any
10905 * more predicates to become cacheable: as unlikely as it is,
10906 * there may be a thread caching a (now stale) predicate cache
10907 * ID. (N.B.: the temptation is being successfully resisted to
10908 * have this cmn_err() "Holy shit -- we executed this code!")
10909 */
10910 return (pred);
10911 }
10912
10913 pred->dtp_cacheid = dtrace_predcache_id++;
10914
10915 return (pred);
10916 }
10917
10918 static void
dtrace_predicate_hold(dtrace_predicate_t * pred)10919 dtrace_predicate_hold(dtrace_predicate_t *pred)
10920 {
10921 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
10922 ASSERT(pred->dtp_difo != NULL && pred->dtp_difo->dtdo_refcnt != 0);
10923 ASSERT(pred->dtp_refcnt > 0);
10924
10925 pred->dtp_refcnt++;
10926 }
10927
10928 static void
dtrace_predicate_release(dtrace_predicate_t * pred,dtrace_vstate_t * vstate)10929 dtrace_predicate_release(dtrace_predicate_t *pred, dtrace_vstate_t *vstate)
10930 {
10931 dtrace_difo_t *dp = pred->dtp_difo;
10932 #pragma unused(dp) /* __APPLE__ */
10933
10934 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
10935 ASSERT(dp != NULL && dp->dtdo_refcnt != 0);
10936 ASSERT(pred->dtp_refcnt > 0);
10937
10938 if (--pred->dtp_refcnt == 0) {
10939 dtrace_difo_release(pred->dtp_difo, vstate);
10940 kmem_free(pred, sizeof (dtrace_predicate_t));
10941 }
10942 }
10943
10944 /*
10945 * DTrace Action Description Functions
10946 */
10947 static dtrace_actdesc_t *
dtrace_actdesc_create(dtrace_actkind_t kind,uint32_t ntuple,uint64_t uarg,uint64_t arg)10948 dtrace_actdesc_create(dtrace_actkind_t kind, uint32_t ntuple,
10949 uint64_t uarg, uint64_t arg)
10950 {
10951 dtrace_actdesc_t *act;
10952
10953 ASSERT(!DTRACEACT_ISPRINTFLIKE(kind) || (arg != 0 &&
10954 arg >= KERNELBASE) || (arg == 0 && kind == DTRACEACT_PRINTA));
10955
10956 act = kmem_zalloc(sizeof (dtrace_actdesc_t), KM_SLEEP);
10957 act->dtad_kind = kind;
10958 act->dtad_ntuple = ntuple;
10959 act->dtad_uarg = uarg;
10960 act->dtad_arg = arg;
10961 act->dtad_refcnt = 1;
10962
10963 return (act);
10964 }
10965
10966 static void
dtrace_actdesc_hold(dtrace_actdesc_t * act)10967 dtrace_actdesc_hold(dtrace_actdesc_t *act)
10968 {
10969 ASSERT(act->dtad_refcnt >= 1);
10970 act->dtad_refcnt++;
10971 }
10972
10973 static void
dtrace_actdesc_release(dtrace_actdesc_t * act,dtrace_vstate_t * vstate)10974 dtrace_actdesc_release(dtrace_actdesc_t *act, dtrace_vstate_t *vstate)
10975 {
10976 dtrace_actkind_t kind = act->dtad_kind;
10977 dtrace_difo_t *dp;
10978
10979 ASSERT(act->dtad_refcnt >= 1);
10980
10981 if (--act->dtad_refcnt != 0)
10982 return;
10983
10984 if ((dp = act->dtad_difo) != NULL)
10985 dtrace_difo_release(dp, vstate);
10986
10987 if (DTRACEACT_ISPRINTFLIKE(kind)) {
10988 char *str = (char *)(uintptr_t)act->dtad_arg;
10989
10990 ASSERT((str != NULL && (uintptr_t)str >= KERNELBASE) ||
10991 (str == NULL && act->dtad_kind == DTRACEACT_PRINTA));
10992
10993 if (str != NULL)
10994 kmem_free(str, strlen(str) + 1);
10995 }
10996
10997 kmem_free(act, sizeof (dtrace_actdesc_t));
10998 }
10999
11000 /*
11001 * DTrace ECB Functions
11002 */
11003 static dtrace_ecb_t *
dtrace_ecb_add(dtrace_state_t * state,dtrace_probe_t * probe)11004 dtrace_ecb_add(dtrace_state_t *state, dtrace_probe_t *probe)
11005 {
11006 dtrace_ecb_t *ecb;
11007 dtrace_epid_t epid;
11008
11009 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
11010
11011 ecb = kmem_zalloc(sizeof (dtrace_ecb_t), KM_SLEEP);
11012 ecb->dte_predicate = NULL;
11013 ecb->dte_probe = probe;
11014
11015 /*
11016 * The default size is the size of the default action: recording
11017 * the header.
11018 */
11019 ecb->dte_size = ecb->dte_needed = sizeof (dtrace_rechdr_t);
11020 ecb->dte_alignment = sizeof (dtrace_epid_t);
11021
11022 epid = state->dts_epid++;
11023
11024 if (epid - 1 >= (dtrace_epid_t)state->dts_necbs) {
11025 dtrace_ecb_t **oecbs = state->dts_ecbs, **ecbs;
11026 int necbs = state->dts_necbs << 1;
11027
11028 ASSERT(epid == (dtrace_epid_t)state->dts_necbs + 1);
11029
11030 if (necbs == 0) {
11031 ASSERT(oecbs == NULL);
11032 necbs = 1;
11033 }
11034
11035 ecbs = kmem_zalloc(necbs * sizeof (*ecbs), KM_SLEEP);
11036
11037 if (oecbs != NULL)
11038 bcopy(oecbs, ecbs, state->dts_necbs * sizeof (*ecbs));
11039
11040 dtrace_membar_producer();
11041 state->dts_ecbs = ecbs;
11042
11043 if (oecbs != NULL) {
11044 /*
11045 * If this state is active, we must dtrace_sync()
11046 * before we can free the old dts_ecbs array: we're
11047 * coming in hot, and there may be active ring
11048 * buffer processing (which indexes into the dts_ecbs
11049 * array) on another CPU.
11050 */
11051 if (state->dts_activity != DTRACE_ACTIVITY_INACTIVE)
11052 dtrace_sync();
11053
11054 kmem_free(oecbs, state->dts_necbs * sizeof (*ecbs));
11055 }
11056
11057 dtrace_membar_producer();
11058 state->dts_necbs = necbs;
11059 }
11060
11061 ecb->dte_state = state;
11062
11063 ASSERT(state->dts_ecbs[epid - 1] == NULL);
11064 dtrace_membar_producer();
11065 state->dts_ecbs[(ecb->dte_epid = epid) - 1] = ecb;
11066
11067 return (ecb);
11068 }
11069
11070 static int
dtrace_ecb_enable(dtrace_ecb_t * ecb)11071 dtrace_ecb_enable(dtrace_ecb_t *ecb)
11072 {
11073 dtrace_probe_t *probe = ecb->dte_probe;
11074
11075 LCK_MTX_ASSERT(&cpu_lock, LCK_MTX_ASSERT_OWNED);
11076 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
11077 ASSERT(ecb->dte_next == NULL);
11078
11079 if (probe == NULL) {
11080 /*
11081 * This is the NULL probe -- there's nothing to do.
11082 */
11083 return(0);
11084 }
11085
11086 probe->dtpr_provider->dtpv_ecb_count++;
11087 if (probe->dtpr_ecb == NULL) {
11088 dtrace_provider_t *prov = probe->dtpr_provider;
11089
11090 /*
11091 * We're the first ECB on this probe.
11092 */
11093 probe->dtpr_ecb = probe->dtpr_ecb_last = ecb;
11094
11095 if (ecb->dte_predicate != NULL)
11096 probe->dtpr_predcache = ecb->dte_predicate->dtp_cacheid;
11097
11098 return (prov->dtpv_pops.dtps_enable(prov->dtpv_arg,
11099 probe->dtpr_id, probe->dtpr_arg));
11100 } else {
11101 /*
11102 * This probe is already active. Swing the last pointer to
11103 * point to the new ECB, and issue a dtrace_sync() to assure
11104 * that all CPUs have seen the change.
11105 */
11106 ASSERT(probe->dtpr_ecb_last != NULL);
11107 probe->dtpr_ecb_last->dte_next = ecb;
11108 probe->dtpr_ecb_last = ecb;
11109 probe->dtpr_predcache = 0;
11110
11111 dtrace_sync();
11112 return(0);
11113 }
11114 }
11115
11116 static int
dtrace_ecb_resize(dtrace_ecb_t * ecb)11117 dtrace_ecb_resize(dtrace_ecb_t *ecb)
11118 {
11119 dtrace_action_t *act;
11120 uint32_t curneeded = UINT32_MAX;
11121 uint32_t aggbase = UINT32_MAX;
11122
11123 /*
11124 * If we record anything, we always record the dtrace_rechdr_t. (And
11125 * we always record it first.)
11126 */
11127 ecb->dte_size = sizeof (dtrace_rechdr_t);
11128 ecb->dte_alignment = sizeof (dtrace_epid_t);
11129
11130 for (act = ecb->dte_action; act != NULL; act = act->dta_next) {
11131 dtrace_recdesc_t *rec = &act->dta_rec;
11132 ASSERT(rec->dtrd_size > 0 || rec->dtrd_alignment == 1);
11133
11134 ecb->dte_alignment = MAX(ecb->dte_alignment, rec->dtrd_alignment);
11135
11136 if (DTRACEACT_ISAGG(act->dta_kind)) {
11137 dtrace_aggregation_t *agg = (dtrace_aggregation_t *)act;
11138
11139 ASSERT(rec->dtrd_size != 0);
11140 ASSERT(agg->dtag_first != NULL);
11141 ASSERT(act->dta_prev->dta_intuple);
11142 ASSERT(aggbase != UINT32_MAX);
11143 ASSERT(curneeded != UINT32_MAX);
11144
11145 agg->dtag_base = aggbase;
11146 curneeded = P2ROUNDUP(curneeded, rec->dtrd_alignment);
11147 rec->dtrd_offset = curneeded;
11148 if (curneeded + rec->dtrd_size < curneeded)
11149 return (EINVAL);
11150 curneeded += rec->dtrd_size;
11151 ecb->dte_needed = MAX(ecb->dte_needed, curneeded);
11152
11153 aggbase = UINT32_MAX;
11154 curneeded = UINT32_MAX;
11155 } else if (act->dta_intuple) {
11156 if (curneeded == UINT32_MAX) {
11157 /*
11158 * This is the first record in a tuple. Align
11159 * curneeded to be at offset 4 in an 8-byte
11160 * aligned block.
11161 */
11162 ASSERT(act->dta_prev == NULL || !act->dta_prev->dta_intuple);
11163 ASSERT(aggbase == UINT32_MAX);
11164
11165 curneeded = P2PHASEUP(ecb->dte_size,
11166 sizeof (uint64_t), sizeof (dtrace_aggid_t));
11167
11168 aggbase = curneeded - sizeof (dtrace_aggid_t);
11169 ASSERT(IS_P2ALIGNED(aggbase,
11170 sizeof (uint64_t)));
11171 }
11172
11173 curneeded = P2ROUNDUP(curneeded, rec->dtrd_alignment);
11174 rec->dtrd_offset = curneeded;
11175 curneeded += rec->dtrd_size;
11176 if (curneeded + rec->dtrd_size < curneeded)
11177 return (EINVAL);
11178 } else {
11179 /* tuples must be followed by an aggregation */
11180 ASSERT(act->dta_prev == NULL || !act->dta_prev->dta_intuple);
11181 ecb->dte_size = P2ROUNDUP(ecb->dte_size, rec->dtrd_alignment);
11182 rec->dtrd_offset = ecb->dte_size;
11183 if (ecb->dte_size + rec->dtrd_size < ecb->dte_size)
11184 return (EINVAL);
11185 ecb->dte_size += rec->dtrd_size;
11186 ecb->dte_needed = MAX(ecb->dte_needed, ecb->dte_size);
11187 }
11188 }
11189
11190 if ((act = ecb->dte_action) != NULL &&
11191 !(act->dta_kind == DTRACEACT_SPECULATE && act->dta_next == NULL) &&
11192 ecb->dte_size == sizeof (dtrace_rechdr_t)) {
11193 /*
11194 * If the size is still sizeof (dtrace_rechdr_t), then all
11195 * actions store no data; set the size to 0.
11196 */
11197 ecb->dte_size = 0;
11198 }
11199
11200 ecb->dte_size = P2ROUNDUP(ecb->dte_size, sizeof (dtrace_epid_t));
11201 ecb->dte_needed = P2ROUNDUP(ecb->dte_needed, (sizeof (dtrace_epid_t)));
11202 ecb->dte_state->dts_needed = MAX(ecb->dte_state->dts_needed, ecb->dte_needed);
11203 return (0);
11204 }
11205
11206 static dtrace_action_t *
dtrace_ecb_aggregation_create(dtrace_ecb_t * ecb,dtrace_actdesc_t * desc)11207 dtrace_ecb_aggregation_create(dtrace_ecb_t *ecb, dtrace_actdesc_t *desc)
11208 {
11209 dtrace_aggregation_t *agg;
11210 size_t size = sizeof (uint64_t);
11211 int ntuple = desc->dtad_ntuple;
11212 dtrace_action_t *act;
11213 dtrace_recdesc_t *frec;
11214 dtrace_aggid_t aggid;
11215 dtrace_state_t *state = ecb->dte_state;
11216
11217 agg = kmem_zalloc(sizeof (dtrace_aggregation_t), KM_SLEEP);
11218 agg->dtag_ecb = ecb;
11219
11220 ASSERT(DTRACEACT_ISAGG(desc->dtad_kind));
11221
11222 switch (desc->dtad_kind) {
11223 case DTRACEAGG_MIN:
11224 agg->dtag_initial = INT64_MAX;
11225 agg->dtag_aggregate = dtrace_aggregate_min;
11226 break;
11227
11228 case DTRACEAGG_MAX:
11229 agg->dtag_initial = INT64_MIN;
11230 agg->dtag_aggregate = dtrace_aggregate_max;
11231 break;
11232
11233 case DTRACEAGG_COUNT:
11234 agg->dtag_aggregate = dtrace_aggregate_count;
11235 break;
11236
11237 case DTRACEAGG_QUANTIZE:
11238 agg->dtag_aggregate = dtrace_aggregate_quantize;
11239 size = (((sizeof (uint64_t) * NBBY) - 1) * 2 + 1) *
11240 sizeof (uint64_t);
11241 break;
11242
11243 case DTRACEAGG_LQUANTIZE: {
11244 uint16_t step = DTRACE_LQUANTIZE_STEP(desc->dtad_arg);
11245 uint16_t levels = DTRACE_LQUANTIZE_LEVELS(desc->dtad_arg);
11246
11247 agg->dtag_initial = desc->dtad_arg;
11248 agg->dtag_aggregate = dtrace_aggregate_lquantize;
11249
11250 if (step == 0 || levels == 0)
11251 goto err;
11252
11253 size = levels * sizeof (uint64_t) + 3 * sizeof (uint64_t);
11254 break;
11255 }
11256
11257 case DTRACEAGG_LLQUANTIZE: {
11258 uint16_t factor = DTRACE_LLQUANTIZE_FACTOR(desc->dtad_arg);
11259 uint16_t low = DTRACE_LLQUANTIZE_LOW(desc->dtad_arg);
11260 uint16_t high = DTRACE_LLQUANTIZE_HIGH(desc->dtad_arg);
11261 uint16_t nsteps = DTRACE_LLQUANTIZE_NSTEP(desc->dtad_arg);
11262 int64_t v;
11263
11264 agg->dtag_initial = desc->dtad_arg;
11265 agg->dtag_aggregate = dtrace_aggregate_llquantize;
11266
11267 if (factor < 2 || low >= high || nsteps < factor)
11268 goto err;
11269
11270 /*
11271 * Now check that the number of steps evenly divides a power
11272 * of the factor. (This assures both integer bucket size and
11273 * linearity within each magnitude.)
11274 */
11275 for (v = factor; v < nsteps; v *= factor)
11276 continue;
11277
11278 if ((v % nsteps) || (nsteps % factor))
11279 goto err;
11280
11281 size = (dtrace_aggregate_llquantize_bucket(factor, low, high, nsteps, INT64_MAX) + 2) * sizeof (uint64_t);
11282 break;
11283 }
11284
11285 case DTRACEAGG_AVG:
11286 agg->dtag_aggregate = dtrace_aggregate_avg;
11287 size = sizeof (uint64_t) * 2;
11288 break;
11289
11290 case DTRACEAGG_STDDEV:
11291 agg->dtag_aggregate = dtrace_aggregate_stddev;
11292 size = sizeof (uint64_t) * 4;
11293 break;
11294
11295 case DTRACEAGG_SUM:
11296 agg->dtag_aggregate = dtrace_aggregate_sum;
11297 break;
11298
11299 default:
11300 goto err;
11301 }
11302
11303 agg->dtag_action.dta_rec.dtrd_size = size;
11304
11305 if (ntuple == 0)
11306 goto err;
11307
11308 /*
11309 * We must make sure that we have enough actions for the n-tuple.
11310 */
11311 for (act = ecb->dte_action_last; act != NULL; act = act->dta_prev) {
11312 if (DTRACEACT_ISAGG(act->dta_kind))
11313 break;
11314
11315 if (--ntuple == 0) {
11316 /*
11317 * This is the action with which our n-tuple begins.
11318 */
11319 agg->dtag_first = act;
11320 goto success;
11321 }
11322 }
11323
11324 /*
11325 * This n-tuple is short by ntuple elements. Return failure.
11326 */
11327 ASSERT(ntuple != 0);
11328 err:
11329 kmem_free(agg, sizeof (dtrace_aggregation_t));
11330 return (NULL);
11331
11332 success:
11333 /*
11334 * If the last action in the tuple has a size of zero, it's actually
11335 * an expression argument for the aggregating action.
11336 */
11337 ASSERT(ecb->dte_action_last != NULL);
11338 act = ecb->dte_action_last;
11339
11340 if (act->dta_kind == DTRACEACT_DIFEXPR) {
11341 ASSERT(act->dta_difo != NULL);
11342
11343 if (act->dta_difo->dtdo_rtype.dtdt_size == 0)
11344 agg->dtag_hasarg = 1;
11345 }
11346
11347 /*
11348 * We need to allocate an id for this aggregation.
11349 */
11350 aggid = (dtrace_aggid_t)(uintptr_t)vmem_alloc(state->dts_aggid_arena, 1,
11351 VM_BESTFIT | VM_SLEEP);
11352
11353 if (aggid - 1 >= (dtrace_aggid_t)state->dts_naggregations) {
11354 dtrace_aggregation_t **oaggs = state->dts_aggregations;
11355 dtrace_aggregation_t **aggs;
11356 int naggs = state->dts_naggregations << 1;
11357 int onaggs = state->dts_naggregations;
11358
11359 ASSERT(aggid == (dtrace_aggid_t)state->dts_naggregations + 1);
11360
11361 if (naggs == 0) {
11362 ASSERT(oaggs == NULL);
11363 naggs = 1;
11364 }
11365
11366 aggs = kmem_zalloc(naggs * sizeof (*aggs), KM_SLEEP);
11367
11368 if (oaggs != NULL) {
11369 bcopy(oaggs, aggs, onaggs * sizeof (*aggs));
11370 kmem_free(oaggs, onaggs * sizeof (*aggs));
11371 }
11372
11373 state->dts_aggregations = aggs;
11374 state->dts_naggregations = naggs;
11375 }
11376
11377 ASSERT(state->dts_aggregations[aggid - 1] == NULL);
11378 state->dts_aggregations[(agg->dtag_id = aggid) - 1] = agg;
11379
11380 frec = &agg->dtag_first->dta_rec;
11381 if (frec->dtrd_alignment < sizeof (dtrace_aggid_t))
11382 frec->dtrd_alignment = sizeof (dtrace_aggid_t);
11383
11384 for (act = agg->dtag_first; act != NULL; act = act->dta_next) {
11385 ASSERT(!act->dta_intuple);
11386 act->dta_intuple = 1;
11387 }
11388
11389 return (&agg->dtag_action);
11390 }
11391
11392 static void
dtrace_ecb_aggregation_destroy(dtrace_ecb_t * ecb,dtrace_action_t * act)11393 dtrace_ecb_aggregation_destroy(dtrace_ecb_t *ecb, dtrace_action_t *act)
11394 {
11395 dtrace_aggregation_t *agg = (dtrace_aggregation_t *)act;
11396 dtrace_state_t *state = ecb->dte_state;
11397 dtrace_aggid_t aggid = agg->dtag_id;
11398
11399 ASSERT(DTRACEACT_ISAGG(act->dta_kind));
11400 vmem_free(state->dts_aggid_arena, (void *)(uintptr_t)aggid, 1);
11401
11402 ASSERT(state->dts_aggregations[aggid - 1] == agg);
11403 state->dts_aggregations[aggid - 1] = NULL;
11404
11405 kmem_free(agg, sizeof (dtrace_aggregation_t));
11406 }
11407
11408 static int
dtrace_ecb_action_add(dtrace_ecb_t * ecb,dtrace_actdesc_t * desc)11409 dtrace_ecb_action_add(dtrace_ecb_t *ecb, dtrace_actdesc_t *desc)
11410 {
11411 dtrace_action_t *action, *last;
11412 dtrace_difo_t *dp = desc->dtad_difo;
11413 uint32_t size = 0, align = sizeof (uint8_t), mask;
11414 uint16_t format = 0;
11415 dtrace_recdesc_t *rec;
11416 dtrace_state_t *state = ecb->dte_state;
11417 dtrace_optval_t *opt = state->dts_options;
11418 dtrace_optval_t nframes=0, strsize;
11419 uint64_t arg = desc->dtad_arg;
11420
11421 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
11422 ASSERT(ecb->dte_action == NULL || ecb->dte_action->dta_refcnt == 1);
11423
11424 if (DTRACEACT_ISAGG(desc->dtad_kind)) {
11425 /*
11426 * If this is an aggregating action, there must be neither
11427 * a speculate nor a commit on the action chain.
11428 */
11429 dtrace_action_t *act;
11430
11431 for (act = ecb->dte_action; act != NULL; act = act->dta_next) {
11432 if (act->dta_kind == DTRACEACT_COMMIT)
11433 return (EINVAL);
11434
11435 if (act->dta_kind == DTRACEACT_SPECULATE)
11436 return (EINVAL);
11437 }
11438
11439 action = dtrace_ecb_aggregation_create(ecb, desc);
11440
11441 if (action == NULL)
11442 return (EINVAL);
11443 } else {
11444 if (DTRACEACT_ISDESTRUCTIVE(desc->dtad_kind) ||
11445 (desc->dtad_kind == DTRACEACT_DIFEXPR &&
11446 dp != NULL && dp->dtdo_destructive)) {
11447 state->dts_destructive = 1;
11448 }
11449
11450 switch (desc->dtad_kind) {
11451 case DTRACEACT_PRINTF:
11452 case DTRACEACT_PRINTA:
11453 case DTRACEACT_SYSTEM:
11454 case DTRACEACT_FREOPEN:
11455 case DTRACEACT_DIFEXPR:
11456 /*
11457 * We know that our arg is a string -- turn it into a
11458 * format.
11459 */
11460 if (arg == 0) {
11461 ASSERT(desc->dtad_kind == DTRACEACT_PRINTA ||
11462 desc->dtad_kind == DTRACEACT_DIFEXPR);
11463 format = 0;
11464 } else {
11465 ASSERT(arg != 0);
11466 ASSERT(arg > KERNELBASE);
11467 format = dtrace_format_add(state,
11468 (char *)(uintptr_t)arg);
11469 }
11470
11471 OS_FALLTHROUGH;
11472 case DTRACEACT_LIBACT:
11473 case DTRACEACT_TRACEMEM:
11474 case DTRACEACT_TRACEMEM_DYNSIZE:
11475 case DTRACEACT_APPLEBINARY: /* __APPLE__ */
11476 if (dp == NULL)
11477 return (EINVAL);
11478
11479 if ((size = dp->dtdo_rtype.dtdt_size) != 0)
11480 break;
11481
11482 if (dp->dtdo_rtype.dtdt_kind == DIF_TYPE_STRING) {
11483 if (!(dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF))
11484 return (EINVAL);
11485
11486 size = opt[DTRACEOPT_STRSIZE];
11487 }
11488
11489 break;
11490
11491 case DTRACEACT_STACK:
11492 if ((nframes = arg) == 0) {
11493 nframes = opt[DTRACEOPT_STACKFRAMES];
11494 ASSERT(nframes > 0);
11495 arg = nframes;
11496 }
11497
11498 size = nframes * sizeof (pc_t);
11499 break;
11500
11501 case DTRACEACT_JSTACK:
11502 if ((strsize = DTRACE_USTACK_STRSIZE(arg)) == 0)
11503 strsize = opt[DTRACEOPT_JSTACKSTRSIZE];
11504
11505 if ((nframes = DTRACE_USTACK_NFRAMES(arg)) == 0)
11506 nframes = opt[DTRACEOPT_JSTACKFRAMES];
11507
11508 arg = DTRACE_USTACK_ARG(nframes, strsize);
11509
11510 OS_FALLTHROUGH;
11511 case DTRACEACT_USTACK:
11512 if (desc->dtad_kind != DTRACEACT_JSTACK &&
11513 (nframes = DTRACE_USTACK_NFRAMES(arg)) == 0) {
11514 strsize = DTRACE_USTACK_STRSIZE(arg);
11515 nframes = opt[DTRACEOPT_USTACKFRAMES];
11516 ASSERT(nframes > 0);
11517 arg = DTRACE_USTACK_ARG(nframes, strsize);
11518 }
11519
11520 /*
11521 * Save a slot for the pid.
11522 */
11523 size = (nframes + 1) * sizeof (uint64_t);
11524 size += DTRACE_USTACK_STRSIZE(arg);
11525 size = P2ROUNDUP(size, (uint32_t)(sizeof (uintptr_t)));
11526
11527 break;
11528
11529 case DTRACEACT_SYM:
11530 case DTRACEACT_MOD:
11531 if (dp == NULL || ((size = dp->dtdo_rtype.dtdt_size) !=
11532 sizeof (uint64_t)) ||
11533 (dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF))
11534 return (EINVAL);
11535 break;
11536
11537 case DTRACEACT_USYM:
11538 case DTRACEACT_UMOD:
11539 case DTRACEACT_UADDR:
11540 if (dp == NULL ||
11541 (dp->dtdo_rtype.dtdt_size != sizeof (uint64_t)) ||
11542 (dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF))
11543 return (EINVAL);
11544
11545 /*
11546 * We have a slot for the pid, plus a slot for the
11547 * argument. To keep things simple (aligned with
11548 * bitness-neutral sizing), we store each as a 64-bit
11549 * quantity.
11550 */
11551 size = 2 * sizeof (uint64_t);
11552 break;
11553
11554 case DTRACEACT_STOP:
11555 case DTRACEACT_BREAKPOINT:
11556 case DTRACEACT_PANIC:
11557 break;
11558
11559 case DTRACEACT_CHILL:
11560 case DTRACEACT_DISCARD:
11561 case DTRACEACT_RAISE:
11562 case DTRACEACT_PIDRESUME: /* __APPLE__ */
11563 if (dp == NULL)
11564 return (EINVAL);
11565 break;
11566
11567 case DTRACEACT_EXIT:
11568 if (dp == NULL ||
11569 (size = dp->dtdo_rtype.dtdt_size) != sizeof (int) ||
11570 (dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF))
11571 return (EINVAL);
11572 break;
11573
11574 case DTRACEACT_SPECULATE:
11575 if (ecb->dte_size > sizeof (dtrace_rechdr_t))
11576 return (EINVAL);
11577
11578 if (dp == NULL)
11579 return (EINVAL);
11580
11581 state->dts_speculates = 1;
11582 break;
11583
11584 case DTRACEACT_COMMIT: {
11585 dtrace_action_t *act = ecb->dte_action;
11586
11587 for (; act != NULL; act = act->dta_next) {
11588 if (act->dta_kind == DTRACEACT_COMMIT)
11589 return (EINVAL);
11590 }
11591
11592 if (dp == NULL)
11593 return (EINVAL);
11594 break;
11595 }
11596
11597 default:
11598 return (EINVAL);
11599 }
11600
11601 if (size != 0 || desc->dtad_kind == DTRACEACT_SPECULATE) {
11602 /*
11603 * If this is a data-storing action or a speculate,
11604 * we must be sure that there isn't a commit on the
11605 * action chain.
11606 */
11607 dtrace_action_t *act = ecb->dte_action;
11608
11609 for (; act != NULL; act = act->dta_next) {
11610 if (act->dta_kind == DTRACEACT_COMMIT)
11611 return (EINVAL);
11612 }
11613 }
11614
11615 action = kmem_zalloc(sizeof (dtrace_action_t), KM_SLEEP);
11616 action->dta_rec.dtrd_size = size;
11617 }
11618
11619 action->dta_refcnt = 1;
11620 rec = &action->dta_rec;
11621 size = rec->dtrd_size;
11622
11623 for (mask = sizeof (uint64_t) - 1; size != 0 && mask > 0; mask >>= 1) {
11624 if (!(size & mask)) {
11625 align = mask + 1;
11626 break;
11627 }
11628 }
11629
11630 action->dta_kind = desc->dtad_kind;
11631
11632 if ((action->dta_difo = dp) != NULL)
11633 dtrace_difo_hold(dp);
11634
11635 rec->dtrd_action = action->dta_kind;
11636 rec->dtrd_arg = arg;
11637 rec->dtrd_uarg = desc->dtad_uarg;
11638 rec->dtrd_alignment = (uint16_t)align;
11639 rec->dtrd_format = format;
11640
11641 if ((last = ecb->dte_action_last) != NULL) {
11642 ASSERT(ecb->dte_action != NULL);
11643 action->dta_prev = last;
11644 last->dta_next = action;
11645 } else {
11646 ASSERT(ecb->dte_action == NULL);
11647 ecb->dte_action = action;
11648 }
11649
11650 ecb->dte_action_last = action;
11651
11652 return (0);
11653 }
11654
11655 static void
dtrace_ecb_action_remove(dtrace_ecb_t * ecb)11656 dtrace_ecb_action_remove(dtrace_ecb_t *ecb)
11657 {
11658 dtrace_action_t *act = ecb->dte_action, *next;
11659 dtrace_vstate_t *vstate = &ecb->dte_state->dts_vstate;
11660 dtrace_difo_t *dp;
11661 uint16_t format;
11662
11663 if (act != NULL && act->dta_refcnt > 1) {
11664 ASSERT(act->dta_next == NULL || act->dta_next->dta_refcnt == 1);
11665 act->dta_refcnt--;
11666 } else {
11667 for (; act != NULL; act = next) {
11668 next = act->dta_next;
11669 ASSERT(next != NULL || act == ecb->dte_action_last);
11670 ASSERT(act->dta_refcnt == 1);
11671
11672 if ((format = act->dta_rec.dtrd_format) != 0)
11673 dtrace_format_remove(ecb->dte_state, format);
11674
11675 if ((dp = act->dta_difo) != NULL)
11676 dtrace_difo_release(dp, vstate);
11677
11678 if (DTRACEACT_ISAGG(act->dta_kind)) {
11679 dtrace_ecb_aggregation_destroy(ecb, act);
11680 } else {
11681 kmem_free(act, sizeof (dtrace_action_t));
11682 }
11683 }
11684 }
11685
11686 ecb->dte_action = NULL;
11687 ecb->dte_action_last = NULL;
11688 ecb->dte_size = 0;
11689 }
11690
11691 static void
dtrace_ecb_disable(dtrace_ecb_t * ecb)11692 dtrace_ecb_disable(dtrace_ecb_t *ecb)
11693 {
11694 /*
11695 * We disable the ECB by removing it from its probe.
11696 */
11697 dtrace_ecb_t *pecb, *prev = NULL;
11698 dtrace_probe_t *probe = ecb->dte_probe;
11699
11700 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
11701
11702 if (probe == NULL) {
11703 /*
11704 * This is the NULL probe; there is nothing to disable.
11705 */
11706 return;
11707 }
11708
11709 for (pecb = probe->dtpr_ecb; pecb != NULL; pecb = pecb->dte_next) {
11710 if (pecb == ecb)
11711 break;
11712 prev = pecb;
11713 }
11714
11715 ASSERT(pecb != NULL);
11716
11717 if (prev == NULL) {
11718 probe->dtpr_ecb = ecb->dte_next;
11719 } else {
11720 prev->dte_next = ecb->dte_next;
11721 }
11722
11723 if (ecb == probe->dtpr_ecb_last) {
11724 ASSERT(ecb->dte_next == NULL);
11725 probe->dtpr_ecb_last = prev;
11726 }
11727
11728 probe->dtpr_provider->dtpv_ecb_count--;
11729 /*
11730 * The ECB has been disconnected from the probe; now sync to assure
11731 * that all CPUs have seen the change before returning.
11732 */
11733 dtrace_sync();
11734
11735 if (probe->dtpr_ecb == NULL) {
11736 /*
11737 * That was the last ECB on the probe; clear the predicate
11738 * cache ID for the probe, disable it and sync one more time
11739 * to assure that we'll never hit it again.
11740 */
11741 dtrace_provider_t *prov = probe->dtpr_provider;
11742
11743 ASSERT(ecb->dte_next == NULL);
11744 ASSERT(probe->dtpr_ecb_last == NULL);
11745 probe->dtpr_predcache = DTRACE_CACHEIDNONE;
11746 prov->dtpv_pops.dtps_disable(prov->dtpv_arg,
11747 probe->dtpr_id, probe->dtpr_arg);
11748 dtrace_sync();
11749 } else {
11750 /*
11751 * There is at least one ECB remaining on the probe. If there
11752 * is _exactly_ one, set the probe's predicate cache ID to be
11753 * the predicate cache ID of the remaining ECB.
11754 */
11755 ASSERT(probe->dtpr_ecb_last != NULL);
11756 ASSERT(probe->dtpr_predcache == DTRACE_CACHEIDNONE);
11757
11758 if (probe->dtpr_ecb == probe->dtpr_ecb_last) {
11759 dtrace_predicate_t *p = probe->dtpr_ecb->dte_predicate;
11760
11761 ASSERT(probe->dtpr_ecb->dte_next == NULL);
11762
11763 if (p != NULL)
11764 probe->dtpr_predcache = p->dtp_cacheid;
11765 }
11766
11767 ecb->dte_next = NULL;
11768 }
11769 }
11770
11771 static void
dtrace_ecb_destroy(dtrace_ecb_t * ecb)11772 dtrace_ecb_destroy(dtrace_ecb_t *ecb)
11773 {
11774 dtrace_state_t *state = ecb->dte_state;
11775 dtrace_vstate_t *vstate = &state->dts_vstate;
11776 dtrace_predicate_t *pred;
11777 dtrace_epid_t epid = ecb->dte_epid;
11778
11779 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
11780 ASSERT(ecb->dte_next == NULL);
11781 ASSERT(ecb->dte_probe == NULL || ecb->dte_probe->dtpr_ecb != ecb);
11782
11783 if ((pred = ecb->dte_predicate) != NULL)
11784 dtrace_predicate_release(pred, vstate);
11785
11786 dtrace_ecb_action_remove(ecb);
11787
11788 ASSERT(state->dts_ecbs[epid - 1] == ecb);
11789 state->dts_ecbs[epid - 1] = NULL;
11790
11791 kmem_free(ecb, sizeof (dtrace_ecb_t));
11792 }
11793
11794 static dtrace_ecb_t *
dtrace_ecb_create(dtrace_state_t * state,dtrace_probe_t * probe,dtrace_enabling_t * enab)11795 dtrace_ecb_create(dtrace_state_t *state, dtrace_probe_t *probe,
11796 dtrace_enabling_t *enab)
11797 {
11798 dtrace_ecb_t *ecb;
11799 dtrace_predicate_t *pred;
11800 dtrace_actdesc_t *act;
11801 dtrace_provider_t *prov;
11802 dtrace_ecbdesc_t *desc = enab->dten_current;
11803
11804 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
11805 ASSERT(state != NULL);
11806
11807 ecb = dtrace_ecb_add(state, probe);
11808 ecb->dte_uarg = desc->dted_uarg;
11809
11810 if ((pred = desc->dted_pred.dtpdd_predicate) != NULL) {
11811 dtrace_predicate_hold(pred);
11812 ecb->dte_predicate = pred;
11813 }
11814
11815 if (probe != NULL) {
11816 /*
11817 * If the provider shows more leg than the consumer is old
11818 * enough to see, we need to enable the appropriate implicit
11819 * predicate bits to prevent the ecb from activating at
11820 * revealing times.
11821 *
11822 * Providers specifying DTRACE_PRIV_USER at register time
11823 * are stating that they need the /proc-style privilege
11824 * model to be enforced, and this is what DTRACE_COND_OWNER
11825 * and DTRACE_COND_ZONEOWNER will then do at probe time.
11826 */
11827 prov = probe->dtpr_provider;
11828 if (!(state->dts_cred.dcr_visible & DTRACE_CRV_ALLPROC) &&
11829 (prov->dtpv_priv.dtpp_flags & DTRACE_PRIV_USER))
11830 ecb->dte_cond |= DTRACE_COND_OWNER;
11831
11832 if (!(state->dts_cred.dcr_visible & DTRACE_CRV_ALLZONE) &&
11833 (prov->dtpv_priv.dtpp_flags & DTRACE_PRIV_USER))
11834 ecb->dte_cond |= DTRACE_COND_ZONEOWNER;
11835
11836 /*
11837 * If the provider shows us kernel innards and the user
11838 * is lacking sufficient privilege, enable the
11839 * DTRACE_COND_USERMODE implicit predicate.
11840 */
11841 if (!(state->dts_cred.dcr_visible & DTRACE_CRV_KERNEL) &&
11842 (prov->dtpv_priv.dtpp_flags & DTRACE_PRIV_KERNEL))
11843 ecb->dte_cond |= DTRACE_COND_USERMODE;
11844 }
11845
11846 if (dtrace_ecb_create_cache != NULL) {
11847 /*
11848 * If we have a cached ecb, we'll use its action list instead
11849 * of creating our own (saving both time and space).
11850 */
11851 dtrace_ecb_t *cached = dtrace_ecb_create_cache;
11852 dtrace_action_t *act_if = cached->dte_action;
11853
11854 if (act_if != NULL) {
11855 ASSERT(act_if->dta_refcnt > 0);
11856 act_if->dta_refcnt++;
11857 ecb->dte_action = act_if;
11858 ecb->dte_action_last = cached->dte_action_last;
11859 ecb->dte_needed = cached->dte_needed;
11860 ecb->dte_size = cached->dte_size;
11861 ecb->dte_alignment = cached->dte_alignment;
11862 }
11863
11864 return (ecb);
11865 }
11866
11867 for (act = desc->dted_action; act != NULL; act = act->dtad_next) {
11868 if ((enab->dten_error = dtrace_ecb_action_add(ecb, act)) != 0) {
11869 dtrace_ecb_destroy(ecb);
11870 return (NULL);
11871 }
11872 }
11873
11874 if ((enab->dten_error = dtrace_ecb_resize(ecb)) != 0) {
11875 dtrace_ecb_destroy(ecb);
11876 return (NULL);
11877 }
11878
11879 return (dtrace_ecb_create_cache = ecb);
11880 }
11881
11882 static int
dtrace_ecb_create_enable(dtrace_probe_t * probe,void * arg1,void * arg2)11883 dtrace_ecb_create_enable(dtrace_probe_t *probe, void *arg1, void *arg2)
11884 {
11885 dtrace_ecb_t *ecb;
11886 dtrace_enabling_t *enab = arg1;
11887 dtrace_ecbdesc_t *ep = arg2;
11888 dtrace_state_t *state = enab->dten_vstate->dtvs_state;
11889
11890 ASSERT(state != NULL);
11891
11892 if (probe != NULL && ep != NULL && probe->dtpr_gen < ep->dted_probegen) {
11893 /*
11894 * This probe was created in a generation for which this
11895 * enabling has previously created ECBs; we don't want to
11896 * enable it again, so just kick out.
11897 */
11898 return (DTRACE_MATCH_NEXT);
11899 }
11900
11901 if ((ecb = dtrace_ecb_create(state, probe, enab)) == NULL)
11902 return (DTRACE_MATCH_DONE);
11903
11904 if (dtrace_ecb_enable(ecb) < 0)
11905 return (DTRACE_MATCH_FAIL);
11906
11907 return (DTRACE_MATCH_NEXT);
11908 }
11909
11910 static dtrace_ecb_t *
dtrace_epid2ecb(dtrace_state_t * state,dtrace_epid_t id)11911 dtrace_epid2ecb(dtrace_state_t *state, dtrace_epid_t id)
11912 {
11913 dtrace_ecb_t *ecb;
11914 #pragma unused(ecb) /* __APPLE__ */
11915
11916 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
11917
11918 if (id == 0 || id > (dtrace_epid_t)state->dts_necbs)
11919 return (NULL);
11920
11921 ASSERT(state->dts_necbs > 0 && state->dts_ecbs != NULL);
11922 ASSERT((ecb = state->dts_ecbs[id - 1]) == NULL || ecb->dte_epid == id);
11923
11924 return (state->dts_ecbs[id - 1]);
11925 }
11926
11927 static dtrace_aggregation_t *
dtrace_aggid2agg(dtrace_state_t * state,dtrace_aggid_t id)11928 dtrace_aggid2agg(dtrace_state_t *state, dtrace_aggid_t id)
11929 {
11930 dtrace_aggregation_t *agg;
11931 #pragma unused(agg) /* __APPLE__ */
11932
11933 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
11934
11935 if (id == 0 || id > (dtrace_aggid_t)state->dts_naggregations)
11936 return (NULL);
11937
11938 ASSERT(state->dts_naggregations > 0 && state->dts_aggregations != NULL);
11939 ASSERT((agg = state->dts_aggregations[id - 1]) == NULL ||
11940 agg->dtag_id == id);
11941
11942 return (state->dts_aggregations[id - 1]);
11943 }
11944
11945 /*
11946 * DTrace Buffer Functions
11947 *
11948 * The following functions manipulate DTrace buffers. Most of these functions
11949 * are called in the context of establishing or processing consumer state;
11950 * exceptions are explicitly noted.
11951 */
11952
11953 /*
11954 * Note: called from cross call context. This function switches the two
11955 * buffers on a given CPU. The atomicity of this operation is assured by
11956 * disabling interrupts while the actual switch takes place; the disabling of
11957 * interrupts serializes the execution with any execution of dtrace_probe() on
11958 * the same CPU.
11959 */
11960 static void
dtrace_buffer_switch(dtrace_buffer_t * buf)11961 dtrace_buffer_switch(dtrace_buffer_t *buf)
11962 {
11963 caddr_t tomax = buf->dtb_tomax;
11964 caddr_t xamot = buf->dtb_xamot;
11965 dtrace_icookie_t cookie;
11966 hrtime_t now;
11967
11968 ASSERT(!(buf->dtb_flags & DTRACEBUF_NOSWITCH));
11969 ASSERT(!(buf->dtb_flags & DTRACEBUF_RING));
11970
11971 cookie = dtrace_interrupt_disable();
11972 now = dtrace_gethrtime();
11973 buf->dtb_tomax = xamot;
11974 buf->dtb_xamot = tomax;
11975 buf->dtb_xamot_drops = buf->dtb_drops;
11976 buf->dtb_xamot_offset = buf->dtb_offset;
11977 buf->dtb_xamot_errors = buf->dtb_errors;
11978 buf->dtb_xamot_flags = buf->dtb_flags;
11979 buf->dtb_offset = 0;
11980 buf->dtb_drops = 0;
11981 buf->dtb_errors = 0;
11982 buf->dtb_flags &= ~(DTRACEBUF_ERROR | DTRACEBUF_DROPPED);
11983 buf->dtb_interval = now - buf->dtb_switched;
11984 buf->dtb_switched = now;
11985 buf->dtb_cur_limit = buf->dtb_limit;
11986
11987 dtrace_interrupt_enable(cookie);
11988 }
11989
11990 /*
11991 * Note: called from cross call context. This function activates a buffer
11992 * on a CPU. As with dtrace_buffer_switch(), the atomicity of the operation
11993 * is guaranteed by the disabling of interrupts.
11994 */
11995 static void
dtrace_buffer_activate(dtrace_state_t * state)11996 dtrace_buffer_activate(dtrace_state_t *state)
11997 {
11998 dtrace_buffer_t *buf;
11999 dtrace_icookie_t cookie = dtrace_interrupt_disable();
12000
12001 buf = &state->dts_buffer[CPU->cpu_id];
12002
12003 if (buf->dtb_tomax != NULL) {
12004 /*
12005 * We might like to assert that the buffer is marked inactive,
12006 * but this isn't necessarily true: the buffer for the CPU
12007 * that processes the BEGIN probe has its buffer activated
12008 * manually. In this case, we take the (harmless) action
12009 * re-clearing the bit INACTIVE bit.
12010 */
12011 buf->dtb_flags &= ~DTRACEBUF_INACTIVE;
12012 }
12013
12014 dtrace_interrupt_enable(cookie);
12015 }
12016
12017 static int
dtrace_buffer_canalloc(size_t size)12018 dtrace_buffer_canalloc(size_t size)
12019 {
12020 if (size > (UINT64_MAX - dtrace_buffer_memory_inuse))
12021 return (B_FALSE);
12022 if ((size + dtrace_buffer_memory_inuse) > dtrace_buffer_memory_maxsize)
12023 return (B_FALSE);
12024
12025 return (B_TRUE);
12026 }
12027
12028 static int
dtrace_buffer_alloc(dtrace_buffer_t * bufs,size_t limit,size_t size,int flags,processorid_t cpu)12029 dtrace_buffer_alloc(dtrace_buffer_t *bufs, size_t limit, size_t size, int flags,
12030 processorid_t cpu)
12031 {
12032 dtrace_cpu_t *cp;
12033 dtrace_buffer_t *buf;
12034 size_t size_before_alloc = dtrace_buffer_memory_inuse;
12035
12036 LCK_MTX_ASSERT(&cpu_lock, LCK_MTX_ASSERT_OWNED);
12037 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
12038
12039 if (size > (size_t)dtrace_nonroot_maxsize &&
12040 !PRIV_POLICY_CHOICE(CRED(), PRIV_ALL, B_FALSE))
12041 return (EFBIG);
12042
12043 cp = cpu_list;
12044
12045 do {
12046 if (cpu != DTRACE_CPUALL && cpu != cp->cpu_id)
12047 continue;
12048
12049 buf = &bufs[cp->cpu_id];
12050
12051 /*
12052 * If there is already a buffer allocated for this CPU, it
12053 * is only possible that this is a DR event. In this case,
12054 * the buffer size must match our specified size.
12055 */
12056 if (buf->dtb_tomax != NULL) {
12057 ASSERT(buf->dtb_size == size);
12058 continue;
12059 }
12060
12061 ASSERT(buf->dtb_xamot == NULL);
12062
12063 /* DTrace, please do not eat all the memory. */
12064 if (dtrace_buffer_canalloc(size) == B_FALSE)
12065 goto err;
12066 if ((buf->dtb_tomax = kmem_zalloc(size, KM_NOSLEEP)) == NULL)
12067 goto err;
12068 dtrace_buffer_memory_inuse += size;
12069
12070 /* Unsure that limit is always lower than size */
12071 limit = limit == size ? limit - 1 : limit;
12072 buf->dtb_cur_limit = limit;
12073 buf->dtb_limit = limit;
12074 buf->dtb_size = size;
12075 buf->dtb_flags = flags;
12076 buf->dtb_offset = 0;
12077 buf->dtb_drops = 0;
12078
12079 if (flags & DTRACEBUF_NOSWITCH)
12080 continue;
12081
12082 /* DTrace, please do not eat all the memory. */
12083 if (dtrace_buffer_canalloc(size) == B_FALSE)
12084 goto err;
12085 if ((buf->dtb_xamot = kmem_zalloc(size, KM_NOSLEEP)) == NULL)
12086 goto err;
12087 dtrace_buffer_memory_inuse += size;
12088 } while ((cp = cp->cpu_next) != cpu_list);
12089
12090 ASSERT(dtrace_buffer_memory_inuse <= dtrace_buffer_memory_maxsize);
12091
12092 return (0);
12093
12094 err:
12095 cp = cpu_list;
12096
12097 do {
12098 if (cpu != DTRACE_CPUALL && cpu != cp->cpu_id)
12099 continue;
12100
12101 buf = &bufs[cp->cpu_id];
12102
12103 if (buf->dtb_xamot != NULL) {
12104 ASSERT(buf->dtb_tomax != NULL);
12105 ASSERT(buf->dtb_size == size);
12106 kmem_free(buf->dtb_xamot, size);
12107 }
12108
12109 if (buf->dtb_tomax != NULL) {
12110 ASSERT(buf->dtb_size == size);
12111 kmem_free(buf->dtb_tomax, size);
12112 }
12113
12114 buf->dtb_tomax = NULL;
12115 buf->dtb_xamot = NULL;
12116 buf->dtb_size = 0;
12117 } while ((cp = cp->cpu_next) != cpu_list);
12118
12119 /* Restore the size saved before allocating memory */
12120 dtrace_buffer_memory_inuse = size_before_alloc;
12121
12122 return (ENOMEM);
12123 }
12124
12125 /*
12126 * Note: called from probe context. This function just increments the drop
12127 * count on a buffer. It has been made a function to allow for the
12128 * possibility of understanding the source of mysterious drop counts. (A
12129 * problem for which one may be particularly disappointed that DTrace cannot
12130 * be used to understand DTrace.)
12131 */
12132 static void
dtrace_buffer_drop(dtrace_buffer_t * buf)12133 dtrace_buffer_drop(dtrace_buffer_t *buf)
12134 {
12135 buf->dtb_drops++;
12136 }
12137
12138 /*
12139 * Note: called from probe context. This function is called to reserve space
12140 * in a buffer. If mstate is non-NULL, sets the scratch base and size in the
12141 * mstate. Returns the new offset in the buffer, or a negative value if an
12142 * error has occurred.
12143 */
12144 static intptr_t
dtrace_buffer_reserve(dtrace_buffer_t * buf,size_t needed,size_t align,dtrace_state_t * state,dtrace_mstate_t * mstate)12145 dtrace_buffer_reserve(dtrace_buffer_t *buf, size_t needed, size_t align,
12146 dtrace_state_t *state, dtrace_mstate_t *mstate)
12147 {
12148 intptr_t offs = buf->dtb_offset, soffs;
12149 intptr_t woffs;
12150 caddr_t tomax;
12151 size_t total_off;
12152
12153 if (buf->dtb_flags & DTRACEBUF_INACTIVE)
12154 return (-1);
12155
12156 if ((tomax = buf->dtb_tomax) == NULL) {
12157 dtrace_buffer_drop(buf);
12158 return (-1);
12159 }
12160
12161 if (!(buf->dtb_flags & (DTRACEBUF_RING | DTRACEBUF_FILL))) {
12162 while (offs & (align - 1)) {
12163 /*
12164 * Assert that our alignment is off by a number which
12165 * is itself sizeof (uint32_t) aligned.
12166 */
12167 ASSERT(!((align - (offs & (align - 1))) &
12168 (sizeof (uint32_t) - 1)));
12169 DTRACE_STORE(uint32_t, tomax, offs, DTRACE_EPIDNONE);
12170 offs += sizeof (uint32_t);
12171 }
12172
12173 if ((uint64_t)(soffs = offs + needed) > buf->dtb_cur_limit) {
12174 if (buf->dtb_cur_limit == buf->dtb_limit) {
12175 buf->dtb_cur_limit = buf->dtb_size;
12176
12177 os_atomic_inc(&state->dts_buf_over_limit, relaxed);
12178 /**
12179 * Set an AST on the current processor
12180 * so that we can wake up the process
12181 * outside of probe context, when we know
12182 * it is safe to do so
12183 */
12184 minor_t minor = getminor(state->dts_dev);
12185 ASSERT(minor < 32);
12186
12187 os_atomic_or(&dtrace_wake_clients, 1 << minor, relaxed);
12188 ast_dtrace_on();
12189 }
12190 if ((uint64_t)soffs > buf->dtb_size) {
12191 dtrace_buffer_drop(buf);
12192 return (-1);
12193 }
12194 }
12195
12196 if (mstate == NULL)
12197 return (offs);
12198
12199 mstate->dtms_scratch_base = (uintptr_t)tomax + soffs;
12200 mstate->dtms_scratch_size = buf->dtb_size - soffs;
12201 mstate->dtms_scratch_ptr = mstate->dtms_scratch_base;
12202
12203 return (offs);
12204 }
12205
12206 if (buf->dtb_flags & DTRACEBUF_FILL) {
12207 if (state->dts_activity != DTRACE_ACTIVITY_COOLDOWN &&
12208 (buf->dtb_flags & DTRACEBUF_FULL))
12209 return (-1);
12210 goto out;
12211 }
12212
12213 total_off = needed + (offs & (align - 1));
12214
12215 /*
12216 * For a ring buffer, life is quite a bit more complicated. Before
12217 * we can store any padding, we need to adjust our wrapping offset.
12218 * (If we've never before wrapped or we're not about to, no adjustment
12219 * is required.)
12220 */
12221 if ((buf->dtb_flags & DTRACEBUF_WRAPPED) ||
12222 offs + total_off > buf->dtb_size) {
12223 woffs = buf->dtb_xamot_offset;
12224
12225 if (offs + total_off > buf->dtb_size) {
12226 /*
12227 * We can't fit in the end of the buffer. First, a
12228 * sanity check that we can fit in the buffer at all.
12229 */
12230 if (total_off > buf->dtb_size) {
12231 dtrace_buffer_drop(buf);
12232 return (-1);
12233 }
12234
12235 /*
12236 * We're going to be storing at the top of the buffer,
12237 * so now we need to deal with the wrapped offset. We
12238 * only reset our wrapped offset to 0 if it is
12239 * currently greater than the current offset. If it
12240 * is less than the current offset, it is because a
12241 * previous allocation induced a wrap -- but the
12242 * allocation didn't subsequently take the space due
12243 * to an error or false predicate evaluation. In this
12244 * case, we'll just leave the wrapped offset alone: if
12245 * the wrapped offset hasn't been advanced far enough
12246 * for this allocation, it will be adjusted in the
12247 * lower loop.
12248 */
12249 if (buf->dtb_flags & DTRACEBUF_WRAPPED) {
12250 if (woffs >= offs)
12251 woffs = 0;
12252 } else {
12253 woffs = 0;
12254 }
12255
12256 /*
12257 * Now we know that we're going to be storing to the
12258 * top of the buffer and that there is room for us
12259 * there. We need to clear the buffer from the current
12260 * offset to the end (there may be old gunk there).
12261 */
12262 while ((uint64_t)offs < buf->dtb_size)
12263 tomax[offs++] = 0;
12264
12265 /*
12266 * We need to set our offset to zero. And because we
12267 * are wrapping, we need to set the bit indicating as
12268 * much. We can also adjust our needed space back
12269 * down to the space required by the ECB -- we know
12270 * that the top of the buffer is aligned.
12271 */
12272 offs = 0;
12273 total_off = needed;
12274 buf->dtb_flags |= DTRACEBUF_WRAPPED;
12275 } else {
12276 /*
12277 * There is room for us in the buffer, so we simply
12278 * need to check the wrapped offset.
12279 */
12280 if (woffs < offs) {
12281 /*
12282 * The wrapped offset is less than the offset.
12283 * This can happen if we allocated buffer space
12284 * that induced a wrap, but then we didn't
12285 * subsequently take the space due to an error
12286 * or false predicate evaluation. This is
12287 * okay; we know that _this_ allocation isn't
12288 * going to induce a wrap. We still can't
12289 * reset the wrapped offset to be zero,
12290 * however: the space may have been trashed in
12291 * the previous failed probe attempt. But at
12292 * least the wrapped offset doesn't need to
12293 * be adjusted at all...
12294 */
12295 goto out;
12296 }
12297 }
12298
12299 while (offs + total_off > (size_t)woffs) {
12300 dtrace_epid_t epid = *(uint32_t *)(tomax + woffs);
12301 size_t size;
12302
12303 if (epid == DTRACE_EPIDNONE) {
12304 size = sizeof (uint32_t);
12305 } else {
12306 ASSERT(epid <= (dtrace_epid_t)state->dts_necbs);
12307 ASSERT(state->dts_ecbs[epid - 1] != NULL);
12308
12309 size = state->dts_ecbs[epid - 1]->dte_size;
12310 }
12311
12312 ASSERT(woffs + size <= buf->dtb_size);
12313 ASSERT(size != 0);
12314
12315 if (woffs + size == buf->dtb_size) {
12316 /*
12317 * We've reached the end of the buffer; we want
12318 * to set the wrapped offset to 0 and break
12319 * out. However, if the offs is 0, then we're
12320 * in a strange edge-condition: the amount of
12321 * space that we want to reserve plus the size
12322 * of the record that we're overwriting is
12323 * greater than the size of the buffer. This
12324 * is problematic because if we reserve the
12325 * space but subsequently don't consume it (due
12326 * to a failed predicate or error) the wrapped
12327 * offset will be 0 -- yet the EPID at offset 0
12328 * will not be committed. This situation is
12329 * relatively easy to deal with: if we're in
12330 * this case, the buffer is indistinguishable
12331 * from one that hasn't wrapped; we need only
12332 * finish the job by clearing the wrapped bit,
12333 * explicitly setting the offset to be 0, and
12334 * zero'ing out the old data in the buffer.
12335 */
12336 if (offs == 0) {
12337 buf->dtb_flags &= ~DTRACEBUF_WRAPPED;
12338 buf->dtb_offset = 0;
12339 woffs = total_off;
12340
12341 while ((uint64_t)woffs < buf->dtb_size)
12342 tomax[woffs++] = 0;
12343 }
12344
12345 woffs = 0;
12346 break;
12347 }
12348
12349 woffs += size;
12350 }
12351
12352 /*
12353 * We have a wrapped offset. It may be that the wrapped offset
12354 * has become zero -- that's okay.
12355 */
12356 buf->dtb_xamot_offset = woffs;
12357 }
12358
12359 out:
12360 /*
12361 * Now we can plow the buffer with any necessary padding.
12362 */
12363 while (offs & (align - 1)) {
12364 /*
12365 * Assert that our alignment is off by a number which
12366 * is itself sizeof (uint32_t) aligned.
12367 */
12368 ASSERT(!((align - (offs & (align - 1))) &
12369 (sizeof (uint32_t) - 1)));
12370 DTRACE_STORE(uint32_t, tomax, offs, DTRACE_EPIDNONE);
12371 offs += sizeof (uint32_t);
12372 }
12373
12374 if (buf->dtb_flags & DTRACEBUF_FILL) {
12375 if (offs + needed > buf->dtb_size - state->dts_reserve) {
12376 buf->dtb_flags |= DTRACEBUF_FULL;
12377 return (-1);
12378 }
12379 }
12380
12381 if (mstate == NULL)
12382 return (offs);
12383
12384 /*
12385 * For ring buffers and fill buffers, the scratch space is always
12386 * the inactive buffer.
12387 */
12388 mstate->dtms_scratch_base = (uintptr_t)buf->dtb_xamot;
12389 mstate->dtms_scratch_size = buf->dtb_size;
12390 mstate->dtms_scratch_ptr = mstate->dtms_scratch_base;
12391
12392 return (offs);
12393 }
12394
12395 static void
dtrace_buffer_polish(dtrace_buffer_t * buf)12396 dtrace_buffer_polish(dtrace_buffer_t *buf)
12397 {
12398 ASSERT(buf->dtb_flags & DTRACEBUF_RING);
12399 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
12400
12401 if (!(buf->dtb_flags & DTRACEBUF_WRAPPED))
12402 return;
12403
12404 /*
12405 * We need to polish the ring buffer. There are three cases:
12406 *
12407 * - The first (and presumably most common) is that there is no gap
12408 * between the buffer offset and the wrapped offset. In this case,
12409 * there is nothing in the buffer that isn't valid data; we can
12410 * mark the buffer as polished and return.
12411 *
12412 * - The second (less common than the first but still more common
12413 * than the third) is that there is a gap between the buffer offset
12414 * and the wrapped offset, and the wrapped offset is larger than the
12415 * buffer offset. This can happen because of an alignment issue, or
12416 * can happen because of a call to dtrace_buffer_reserve() that
12417 * didn't subsequently consume the buffer space. In this case,
12418 * we need to zero the data from the buffer offset to the wrapped
12419 * offset.
12420 *
12421 * - The third (and least common) is that there is a gap between the
12422 * buffer offset and the wrapped offset, but the wrapped offset is
12423 * _less_ than the buffer offset. This can only happen because a
12424 * call to dtrace_buffer_reserve() induced a wrap, but the space
12425 * was not subsequently consumed. In this case, we need to zero the
12426 * space from the offset to the end of the buffer _and_ from the
12427 * top of the buffer to the wrapped offset.
12428 */
12429 if (buf->dtb_offset < buf->dtb_xamot_offset) {
12430 bzero(buf->dtb_tomax + buf->dtb_offset,
12431 buf->dtb_xamot_offset - buf->dtb_offset);
12432 }
12433
12434 if (buf->dtb_offset > buf->dtb_xamot_offset) {
12435 bzero(buf->dtb_tomax + buf->dtb_offset,
12436 buf->dtb_size - buf->dtb_offset);
12437 bzero(buf->dtb_tomax, buf->dtb_xamot_offset);
12438 }
12439 }
12440
12441 static void
dtrace_buffer_free(dtrace_buffer_t * bufs)12442 dtrace_buffer_free(dtrace_buffer_t *bufs)
12443 {
12444 int i;
12445
12446 for (i = 0; i < (int)NCPU; i++) {
12447 dtrace_buffer_t *buf = &bufs[i];
12448
12449 if (buf->dtb_tomax == NULL) {
12450 ASSERT(buf->dtb_xamot == NULL);
12451 ASSERT(buf->dtb_size == 0);
12452 continue;
12453 }
12454
12455 if (buf->dtb_xamot != NULL) {
12456 ASSERT(!(buf->dtb_flags & DTRACEBUF_NOSWITCH));
12457 kmem_free(buf->dtb_xamot, buf->dtb_size);
12458
12459 ASSERT(dtrace_buffer_memory_inuse >= buf->dtb_size);
12460 dtrace_buffer_memory_inuse -= buf->dtb_size;
12461 }
12462
12463 kmem_free(buf->dtb_tomax, buf->dtb_size);
12464 ASSERT(dtrace_buffer_memory_inuse >= buf->dtb_size);
12465 dtrace_buffer_memory_inuse -= buf->dtb_size;
12466
12467 buf->dtb_size = 0;
12468 buf->dtb_tomax = NULL;
12469 buf->dtb_xamot = NULL;
12470 }
12471 }
12472
12473 /*
12474 * DTrace Enabling Functions
12475 */
12476 static dtrace_enabling_t *
dtrace_enabling_create(dtrace_vstate_t * vstate)12477 dtrace_enabling_create(dtrace_vstate_t *vstate)
12478 {
12479 dtrace_enabling_t *enab;
12480
12481 enab = kmem_zalloc(sizeof (dtrace_enabling_t), KM_SLEEP);
12482 enab->dten_vstate = vstate;
12483
12484 return (enab);
12485 }
12486
12487 static void
dtrace_enabling_add(dtrace_enabling_t * enab,dtrace_ecbdesc_t * ecb)12488 dtrace_enabling_add(dtrace_enabling_t *enab, dtrace_ecbdesc_t *ecb)
12489 {
12490 dtrace_ecbdesc_t **ndesc;
12491 size_t osize, nsize;
12492
12493 /*
12494 * We can't add to enablings after we've enabled them, or after we've
12495 * retained them.
12496 */
12497 ASSERT(enab->dten_probegen == 0);
12498 ASSERT(enab->dten_next == NULL && enab->dten_prev == NULL);
12499
12500 /* APPLE NOTE: this protects against gcc 4.0 botch on x86 */
12501 if (ecb == NULL) return;
12502
12503 if (enab->dten_ndesc < enab->dten_maxdesc) {
12504 enab->dten_desc[enab->dten_ndesc++] = ecb;
12505 return;
12506 }
12507
12508 osize = enab->dten_maxdesc * sizeof (dtrace_enabling_t *);
12509
12510 if (enab->dten_maxdesc == 0) {
12511 enab->dten_maxdesc = 1;
12512 } else {
12513 enab->dten_maxdesc <<= 1;
12514 }
12515
12516 ASSERT(enab->dten_ndesc < enab->dten_maxdesc);
12517
12518 nsize = enab->dten_maxdesc * sizeof (dtrace_enabling_t *);
12519 ndesc = kmem_zalloc(nsize, KM_SLEEP);
12520 bcopy(enab->dten_desc, ndesc, osize);
12521 kmem_free(enab->dten_desc, osize);
12522
12523 enab->dten_desc = ndesc;
12524 enab->dten_desc[enab->dten_ndesc++] = ecb;
12525 }
12526
12527 static void
dtrace_enabling_addlike(dtrace_enabling_t * enab,dtrace_ecbdesc_t * ecb,dtrace_probedesc_t * pd)12528 dtrace_enabling_addlike(dtrace_enabling_t *enab, dtrace_ecbdesc_t *ecb,
12529 dtrace_probedesc_t *pd)
12530 {
12531 dtrace_ecbdesc_t *new;
12532 dtrace_predicate_t *pred;
12533 dtrace_actdesc_t *act;
12534
12535 /*
12536 * We're going to create a new ECB description that matches the
12537 * specified ECB in every way, but has the specified probe description.
12538 */
12539 new = kmem_zalloc(sizeof (dtrace_ecbdesc_t), KM_SLEEP);
12540
12541 if ((pred = ecb->dted_pred.dtpdd_predicate) != NULL)
12542 dtrace_predicate_hold(pred);
12543
12544 for (act = ecb->dted_action; act != NULL; act = act->dtad_next)
12545 dtrace_actdesc_hold(act);
12546
12547 new->dted_action = ecb->dted_action;
12548 new->dted_pred = ecb->dted_pred;
12549 new->dted_probe = *pd;
12550 new->dted_uarg = ecb->dted_uarg;
12551
12552 dtrace_enabling_add(enab, new);
12553 }
12554
12555 static void
dtrace_enabling_dump(dtrace_enabling_t * enab)12556 dtrace_enabling_dump(dtrace_enabling_t *enab)
12557 {
12558 int i;
12559
12560 for (i = 0; i < enab->dten_ndesc; i++) {
12561 dtrace_probedesc_t *desc = &enab->dten_desc[i]->dted_probe;
12562
12563 cmn_err(CE_NOTE, "enabling probe %d (%s:%s:%s:%s)", i,
12564 desc->dtpd_provider, desc->dtpd_mod,
12565 desc->dtpd_func, desc->dtpd_name);
12566 }
12567 }
12568
12569 static void
dtrace_enabling_destroy(dtrace_enabling_t * enab)12570 dtrace_enabling_destroy(dtrace_enabling_t *enab)
12571 {
12572 int i;
12573 dtrace_ecbdesc_t *ep;
12574 dtrace_vstate_t *vstate = enab->dten_vstate;
12575
12576 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
12577
12578 for (i = 0; i < enab->dten_ndesc; i++) {
12579 dtrace_actdesc_t *act, *next;
12580 dtrace_predicate_t *pred;
12581
12582 ep = enab->dten_desc[i];
12583
12584 if ((pred = ep->dted_pred.dtpdd_predicate) != NULL)
12585 dtrace_predicate_release(pred, vstate);
12586
12587 for (act = ep->dted_action; act != NULL; act = next) {
12588 next = act->dtad_next;
12589 dtrace_actdesc_release(act, vstate);
12590 }
12591
12592 kmem_free(ep, sizeof (dtrace_ecbdesc_t));
12593 }
12594
12595 kmem_free(enab->dten_desc,
12596 enab->dten_maxdesc * sizeof (dtrace_enabling_t *));
12597
12598 /*
12599 * If this was a retained enabling, decrement the dts_nretained count
12600 * and take it off of the dtrace_retained list.
12601 */
12602 if (enab->dten_prev != NULL || enab->dten_next != NULL ||
12603 dtrace_retained == enab) {
12604 ASSERT(enab->dten_vstate->dtvs_state != NULL);
12605 ASSERT(enab->dten_vstate->dtvs_state->dts_nretained > 0);
12606 enab->dten_vstate->dtvs_state->dts_nretained--;
12607 dtrace_retained_gen++;
12608 }
12609
12610 if (enab->dten_prev == NULL) {
12611 if (dtrace_retained == enab) {
12612 dtrace_retained = enab->dten_next;
12613
12614 if (dtrace_retained != NULL)
12615 dtrace_retained->dten_prev = NULL;
12616 }
12617 } else {
12618 ASSERT(enab != dtrace_retained);
12619 ASSERT(dtrace_retained != NULL);
12620 enab->dten_prev->dten_next = enab->dten_next;
12621 }
12622
12623 if (enab->dten_next != NULL) {
12624 ASSERT(dtrace_retained != NULL);
12625 enab->dten_next->dten_prev = enab->dten_prev;
12626 }
12627
12628 kmem_free(enab, sizeof (dtrace_enabling_t));
12629 }
12630
12631 static int
dtrace_enabling_retain(dtrace_enabling_t * enab)12632 dtrace_enabling_retain(dtrace_enabling_t *enab)
12633 {
12634 dtrace_state_t *state;
12635
12636 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
12637 ASSERT(enab->dten_next == NULL && enab->dten_prev == NULL);
12638 ASSERT(enab->dten_vstate != NULL);
12639
12640 state = enab->dten_vstate->dtvs_state;
12641 ASSERT(state != NULL);
12642
12643 /*
12644 * We only allow each state to retain dtrace_retain_max enablings.
12645 */
12646 if (state->dts_nretained >= dtrace_retain_max)
12647 return (ENOSPC);
12648
12649 state->dts_nretained++;
12650 dtrace_retained_gen++;
12651
12652 if (dtrace_retained == NULL) {
12653 dtrace_retained = enab;
12654 return (0);
12655 }
12656
12657 enab->dten_next = dtrace_retained;
12658 dtrace_retained->dten_prev = enab;
12659 dtrace_retained = enab;
12660
12661 return (0);
12662 }
12663
12664 static int
dtrace_enabling_replicate(dtrace_state_t * state,dtrace_probedesc_t * match,dtrace_probedesc_t * create)12665 dtrace_enabling_replicate(dtrace_state_t *state, dtrace_probedesc_t *match,
12666 dtrace_probedesc_t *create)
12667 {
12668 dtrace_enabling_t *new, *enab;
12669 int found = 0, err = ENOENT;
12670
12671 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
12672 ASSERT(strlen(match->dtpd_provider) < DTRACE_PROVNAMELEN);
12673 ASSERT(strlen(match->dtpd_mod) < DTRACE_MODNAMELEN);
12674 ASSERT(strlen(match->dtpd_func) < DTRACE_FUNCNAMELEN);
12675 ASSERT(strlen(match->dtpd_name) < DTRACE_NAMELEN);
12676
12677 new = dtrace_enabling_create(&state->dts_vstate);
12678
12679 /*
12680 * Iterate over all retained enablings, looking for enablings that
12681 * match the specified state.
12682 */
12683 for (enab = dtrace_retained; enab != NULL; enab = enab->dten_next) {
12684 int i;
12685
12686 /*
12687 * dtvs_state can only be NULL for helper enablings -- and
12688 * helper enablings can't be retained.
12689 */
12690 ASSERT(enab->dten_vstate->dtvs_state != NULL);
12691
12692 if (enab->dten_vstate->dtvs_state != state)
12693 continue;
12694
12695 /*
12696 * Now iterate over each probe description; we're looking for
12697 * an exact match to the specified probe description.
12698 */
12699 for (i = 0; i < enab->dten_ndesc; i++) {
12700 dtrace_ecbdesc_t *ep = enab->dten_desc[i];
12701 dtrace_probedesc_t *pd = &ep->dted_probe;
12702
12703 /* APPLE NOTE: Darwin employs size bounded string operation. */
12704 if (strncmp(pd->dtpd_provider, match->dtpd_provider, DTRACE_PROVNAMELEN))
12705 continue;
12706
12707 if (strncmp(pd->dtpd_mod, match->dtpd_mod, DTRACE_MODNAMELEN))
12708 continue;
12709
12710 if (strncmp(pd->dtpd_func, match->dtpd_func, DTRACE_FUNCNAMELEN))
12711 continue;
12712
12713 if (strncmp(pd->dtpd_name, match->dtpd_name, DTRACE_NAMELEN))
12714 continue;
12715
12716 /*
12717 * We have a winning probe! Add it to our growing
12718 * enabling.
12719 */
12720 found = 1;
12721 dtrace_enabling_addlike(new, ep, create);
12722 }
12723 }
12724
12725 if (!found || (err = dtrace_enabling_retain(new)) != 0) {
12726 dtrace_enabling_destroy(new);
12727 return (err);
12728 }
12729
12730 return (0);
12731 }
12732
12733 static void
dtrace_enabling_retract(dtrace_state_t * state)12734 dtrace_enabling_retract(dtrace_state_t *state)
12735 {
12736 dtrace_enabling_t *enab, *next;
12737
12738 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
12739
12740 /*
12741 * Iterate over all retained enablings, destroy the enablings retained
12742 * for the specified state.
12743 */
12744 for (enab = dtrace_retained; enab != NULL; enab = next) {
12745 next = enab->dten_next;
12746
12747 /*
12748 * dtvs_state can only be NULL for helper enablings -- and
12749 * helper enablings can't be retained.
12750 */
12751 ASSERT(enab->dten_vstate->dtvs_state != NULL);
12752
12753 if (enab->dten_vstate->dtvs_state == state) {
12754 ASSERT(state->dts_nretained > 0);
12755 dtrace_enabling_destroy(enab);
12756 }
12757 }
12758
12759 ASSERT(state->dts_nretained == 0);
12760 }
12761
12762 static int
dtrace_enabling_match(dtrace_enabling_t * enab,int * nmatched,dtrace_match_cond_t * cond)12763 dtrace_enabling_match(dtrace_enabling_t *enab, int *nmatched, dtrace_match_cond_t *cond)
12764 {
12765 int i = 0;
12766 int total_matched = 0, matched = 0;
12767
12768 LCK_MTX_ASSERT(&cpu_lock, LCK_MTX_ASSERT_OWNED);
12769 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
12770
12771 for (i = 0; i < enab->dten_ndesc; i++) {
12772 dtrace_ecbdesc_t *ep = enab->dten_desc[i];
12773
12774 enab->dten_current = ep;
12775 enab->dten_error = 0;
12776
12777 /**
12778 * Before doing a dtrace_probe_enable, which is really
12779 * expensive, check that this enabling matches the matching precondition
12780 * if we have one
12781 */
12782 if (cond && (cond->dmc_func(&ep->dted_probe, cond->dmc_data) == 0)) {
12783 continue;
12784 }
12785 /*
12786 * If a provider failed to enable a probe then get out and
12787 * let the consumer know we failed.
12788 */
12789 if ((matched = dtrace_probe_enable(&ep->dted_probe, enab, ep)) < 0)
12790 return (EBUSY);
12791
12792 total_matched += matched;
12793
12794 if (enab->dten_error != 0) {
12795 /*
12796 * If we get an error half-way through enabling the
12797 * probes, we kick out -- perhaps with some number of
12798 * them enabled. Leaving enabled probes enabled may
12799 * be slightly confusing for user-level, but we expect
12800 * that no one will attempt to actually drive on in
12801 * the face of such errors. If this is an anonymous
12802 * enabling (indicated with a NULL nmatched pointer),
12803 * we cmn_err() a message. We aren't expecting to
12804 * get such an error -- such as it can exist at all,
12805 * it would be a result of corrupted DOF in the driver
12806 * properties.
12807 */
12808 if (nmatched == NULL) {
12809 cmn_err(CE_WARN, "dtrace_enabling_match() "
12810 "error on %p: %d", (void *)ep,
12811 enab->dten_error);
12812 }
12813
12814 return (enab->dten_error);
12815 }
12816
12817 ep->dted_probegen = dtrace_probegen;
12818 }
12819
12820 if (nmatched != NULL)
12821 *nmatched = total_matched;
12822
12823 return (0);
12824 }
12825
12826 static void
dtrace_enabling_matchall_with_cond(dtrace_match_cond_t * cond)12827 dtrace_enabling_matchall_with_cond(dtrace_match_cond_t *cond)
12828 {
12829 dtrace_enabling_t *enab;
12830
12831 lck_mtx_lock(&cpu_lock);
12832 lck_mtx_lock(&dtrace_lock);
12833
12834 /*
12835 * Iterate over all retained enablings to see if any probes match
12836 * against them. We only perform this operation on enablings for which
12837 * we have sufficient permissions by virtue of being in the global zone
12838 * or in the same zone as the DTrace client. Because we can be called
12839 * after dtrace_detach() has been called, we cannot assert that there
12840 * are retained enablings. We can safely load from dtrace_retained,
12841 * however: the taskq_destroy() at the end of dtrace_detach() will
12842 * block pending our completion.
12843 */
12844
12845 /*
12846 * Darwin doesn't do zones.
12847 * Behave as if always in "global" zone."
12848 */
12849 for (enab = dtrace_retained; enab != NULL; enab = enab->dten_next) {
12850 (void) dtrace_enabling_match(enab, NULL, cond);
12851 }
12852
12853 lck_mtx_unlock(&dtrace_lock);
12854 lck_mtx_unlock(&cpu_lock);
12855
12856 }
12857
12858 static void
dtrace_enabling_matchall(void)12859 dtrace_enabling_matchall(void)
12860 {
12861 dtrace_enabling_matchall_with_cond(NULL);
12862 }
12863
12864
12865
12866 /*
12867 * If an enabling is to be enabled without having matched probes (that is, if
12868 * dtrace_state_go() is to be called on the underlying dtrace_state_t), the
12869 * enabling must be _primed_ by creating an ECB for every ECB description.
12870 * This must be done to assure that we know the number of speculations, the
12871 * number of aggregations, the minimum buffer size needed, etc. before we
12872 * transition out of DTRACE_ACTIVITY_INACTIVE. To do this without actually
12873 * enabling any probes, we create ECBs for every ECB decription, but with a
12874 * NULL probe -- which is exactly what this function does.
12875 */
12876 static void
dtrace_enabling_prime(dtrace_state_t * state)12877 dtrace_enabling_prime(dtrace_state_t *state)
12878 {
12879 dtrace_enabling_t *enab;
12880 int i;
12881
12882 for (enab = dtrace_retained; enab != NULL; enab = enab->dten_next) {
12883 ASSERT(enab->dten_vstate->dtvs_state != NULL);
12884
12885 if (enab->dten_vstate->dtvs_state != state)
12886 continue;
12887
12888 /*
12889 * We don't want to prime an enabling more than once, lest
12890 * we allow a malicious user to induce resource exhaustion.
12891 * (The ECBs that result from priming an enabling aren't
12892 * leaked -- but they also aren't deallocated until the
12893 * consumer state is destroyed.)
12894 */
12895 if (enab->dten_primed)
12896 continue;
12897
12898 for (i = 0; i < enab->dten_ndesc; i++) {
12899 enab->dten_current = enab->dten_desc[i];
12900 (void) dtrace_probe_enable(NULL, enab, NULL);
12901 }
12902
12903 enab->dten_primed = 1;
12904 }
12905 }
12906
12907 /*
12908 * Called to indicate that probes should be provided due to retained
12909 * enablings. This is implemented in terms of dtrace_probe_provide(), but it
12910 * must take an initial lap through the enabling calling the dtps_provide()
12911 * entry point explicitly to allow for autocreated probes.
12912 */
12913 static void
dtrace_enabling_provide(dtrace_provider_t * prv)12914 dtrace_enabling_provide(dtrace_provider_t *prv)
12915 {
12916 int i, all = 0;
12917 dtrace_probedesc_t desc;
12918 dtrace_genid_t gen;
12919
12920 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
12921 LCK_MTX_ASSERT(&dtrace_provider_lock, LCK_MTX_ASSERT_OWNED);
12922
12923 if (prv == NULL) {
12924 all = 1;
12925 prv = dtrace_provider;
12926 }
12927
12928 do {
12929 dtrace_enabling_t *enab;
12930 void *parg = prv->dtpv_arg;
12931
12932 retry:
12933 gen = dtrace_retained_gen;
12934 for (enab = dtrace_retained; enab != NULL;
12935 enab = enab->dten_next) {
12936 for (i = 0; i < enab->dten_ndesc; i++) {
12937 desc = enab->dten_desc[i]->dted_probe;
12938 lck_mtx_unlock(&dtrace_lock);
12939 prv->dtpv_pops.dtps_provide(parg, &desc);
12940 lck_mtx_lock(&dtrace_lock);
12941 /*
12942 * Process the retained enablings again if
12943 * they have changed while we weren't holding
12944 * dtrace_lock.
12945 */
12946 if (gen != dtrace_retained_gen)
12947 goto retry;
12948 }
12949 }
12950 } while (all && (prv = prv->dtpv_next) != NULL);
12951
12952 lck_mtx_unlock(&dtrace_lock);
12953 dtrace_probe_provide(NULL, all ? NULL : prv);
12954 lck_mtx_lock(&dtrace_lock);
12955 }
12956
12957 /*
12958 * DTrace DOF Functions
12959 */
12960 /*ARGSUSED*/
12961 static void
dtrace_dof_error(dof_hdr_t * dof,const char * str)12962 dtrace_dof_error(dof_hdr_t *dof, const char *str)
12963 {
12964 #pragma unused(dof) /* __APPLE__ */
12965 if (dtrace_err_verbose)
12966 cmn_err(CE_WARN, "failed to process DOF: %s", str);
12967
12968 #ifdef DTRACE_ERRDEBUG
12969 dtrace_errdebug(str);
12970 #endif
12971 }
12972
12973 /*
12974 * Create DOF out of a currently enabled state. Right now, we only create
12975 * DOF containing the run-time options -- but this could be expanded to create
12976 * complete DOF representing the enabled state.
12977 */
12978 static dof_hdr_t *
dtrace_dof_create(dtrace_state_t * state)12979 dtrace_dof_create(dtrace_state_t *state)
12980 {
12981 dof_hdr_t *dof;
12982 dof_sec_t *sec;
12983 dof_optdesc_t *opt;
12984 int i, len = sizeof (dof_hdr_t) +
12985 roundup(sizeof (dof_sec_t), sizeof (uint64_t)) +
12986 sizeof (dof_optdesc_t) * DTRACEOPT_MAX;
12987
12988 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
12989
12990 dof = kmem_zalloc_aligned(len, 8, KM_SLEEP);
12991 dof->dofh_ident[DOF_ID_MAG0] = DOF_MAG_MAG0;
12992 dof->dofh_ident[DOF_ID_MAG1] = DOF_MAG_MAG1;
12993 dof->dofh_ident[DOF_ID_MAG2] = DOF_MAG_MAG2;
12994 dof->dofh_ident[DOF_ID_MAG3] = DOF_MAG_MAG3;
12995
12996 dof->dofh_ident[DOF_ID_MODEL] = DOF_MODEL_NATIVE;
12997 dof->dofh_ident[DOF_ID_ENCODING] = DOF_ENCODE_NATIVE;
12998 dof->dofh_ident[DOF_ID_VERSION] = DOF_VERSION;
12999 dof->dofh_ident[DOF_ID_DIFVERS] = DIF_VERSION;
13000 dof->dofh_ident[DOF_ID_DIFIREG] = DIF_DIR_NREGS;
13001 dof->dofh_ident[DOF_ID_DIFTREG] = DIF_DTR_NREGS;
13002
13003 dof->dofh_flags = 0;
13004 dof->dofh_hdrsize = sizeof (dof_hdr_t);
13005 dof->dofh_secsize = sizeof (dof_sec_t);
13006 dof->dofh_secnum = 1; /* only DOF_SECT_OPTDESC */
13007 dof->dofh_secoff = sizeof (dof_hdr_t);
13008 dof->dofh_loadsz = len;
13009 dof->dofh_filesz = len;
13010 dof->dofh_pad = 0;
13011
13012 /*
13013 * Fill in the option section header...
13014 */
13015 sec = (dof_sec_t *)((uintptr_t)dof + sizeof (dof_hdr_t));
13016 sec->dofs_type = DOF_SECT_OPTDESC;
13017 sec->dofs_align = sizeof (uint64_t);
13018 sec->dofs_flags = DOF_SECF_LOAD;
13019 sec->dofs_entsize = sizeof (dof_optdesc_t);
13020
13021 opt = (dof_optdesc_t *)((uintptr_t)sec +
13022 roundup(sizeof (dof_sec_t), sizeof (uint64_t)));
13023
13024 sec->dofs_offset = (uintptr_t)opt - (uintptr_t)dof;
13025 sec->dofs_size = sizeof (dof_optdesc_t) * DTRACEOPT_MAX;
13026
13027 for (i = 0; i < DTRACEOPT_MAX; i++) {
13028 opt[i].dofo_option = i;
13029 opt[i].dofo_strtab = DOF_SECIDX_NONE;
13030 opt[i].dofo_value = state->dts_options[i];
13031 }
13032
13033 return (dof);
13034 }
13035
13036 static dof_hdr_t *
dtrace_dof_copyin(user_addr_t uarg,int * errp)13037 dtrace_dof_copyin(user_addr_t uarg, int *errp)
13038 {
13039 dof_hdr_t hdr, *dof;
13040
13041 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_NOTOWNED);
13042
13043 /*
13044 * First, we're going to copyin() the sizeof (dof_hdr_t).
13045 */
13046 if (copyin(uarg, &hdr, sizeof (hdr)) != 0) {
13047 dtrace_dof_error(NULL, "failed to copyin DOF header");
13048 *errp = EFAULT;
13049 return (NULL);
13050 }
13051
13052 /*
13053 * Now we'll allocate the entire DOF and copy it in -- provided
13054 * that the length isn't outrageous.
13055 */
13056 if (hdr.dofh_loadsz >= (uint64_t)dtrace_dof_maxsize) {
13057 dtrace_dof_error(&hdr, "load size exceeds maximum");
13058 *errp = E2BIG;
13059 return (NULL);
13060 }
13061
13062 if (hdr.dofh_loadsz < sizeof (hdr)) {
13063 dtrace_dof_error(&hdr, "invalid load size");
13064 *errp = EINVAL;
13065 return (NULL);
13066 }
13067
13068 dof = kmem_alloc_aligned(hdr.dofh_loadsz, 8, KM_SLEEP);
13069
13070 if (copyin(uarg, dof, hdr.dofh_loadsz) != 0 ||
13071 dof->dofh_loadsz != hdr.dofh_loadsz) {
13072 kmem_free_aligned(dof, hdr.dofh_loadsz);
13073 *errp = EFAULT;
13074 return (NULL);
13075 }
13076
13077 return (dof);
13078 }
13079
13080 static dof_hdr_t *
dtrace_dof_copyin_from_proc(proc_t * p,user_addr_t uarg,int * errp)13081 dtrace_dof_copyin_from_proc(proc_t* p, user_addr_t uarg, int *errp)
13082 {
13083 dof_hdr_t hdr, *dof;
13084
13085 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_NOTOWNED);
13086
13087 /*
13088 * First, we're going to copyin() the sizeof (dof_hdr_t).
13089 */
13090 if (uread(p, &hdr, sizeof(hdr), uarg) != KERN_SUCCESS) {
13091 dtrace_dof_error(NULL, "failed to copyin DOF header");
13092 *errp = EFAULT;
13093 return (NULL);
13094 }
13095
13096 /*
13097 * Now we'll allocate the entire DOF and copy it in -- provided
13098 * that the length isn't outrageous.
13099 */
13100 if (hdr.dofh_loadsz >= (uint64_t)dtrace_dof_maxsize) {
13101 dtrace_dof_error(&hdr, "load size exceeds maximum");
13102 *errp = E2BIG;
13103 return (NULL);
13104 }
13105
13106 if (hdr.dofh_loadsz < sizeof (hdr)) {
13107 dtrace_dof_error(&hdr, "invalid load size");
13108 *errp = EINVAL;
13109 return (NULL);
13110 }
13111
13112 dof = kmem_alloc_aligned(hdr.dofh_loadsz, 8, KM_SLEEP);
13113
13114 if (uread(p, dof, hdr.dofh_loadsz, uarg) != KERN_SUCCESS) {
13115 kmem_free_aligned(dof, hdr.dofh_loadsz);
13116 *errp = EFAULT;
13117 return (NULL);
13118 }
13119
13120 return (dof);
13121 }
13122
13123 static void
dtrace_dof_destroy(dof_hdr_t * dof)13124 dtrace_dof_destroy(dof_hdr_t *dof)
13125 {
13126 kmem_free_aligned(dof, dof->dofh_loadsz);
13127 }
13128
13129 static dof_hdr_t *
dtrace_dof_property(const char * name)13130 dtrace_dof_property(const char *name)
13131 {
13132 unsigned int len = 0;
13133 dof_hdr_t *dof;
13134
13135 if (dtrace_is_restricted() && !dtrace_are_restrictions_relaxed()) {
13136 return NULL;
13137 }
13138
13139 if (!PEReadNVRAMProperty(name, NULL, &len)) {
13140 return NULL;
13141 }
13142
13143 dof = kmem_alloc_aligned(len, 8, KM_SLEEP);
13144
13145 if (!PEReadNVRAMProperty(name, dof, &len)) {
13146 dtrace_dof_destroy(dof);
13147 dtrace_dof_error(NULL, "unreadable DOF");
13148 return NULL;
13149 }
13150
13151 if (len < sizeof (dof_hdr_t)) {
13152 dtrace_dof_destroy(dof);
13153 dtrace_dof_error(NULL, "truncated header");
13154 return (NULL);
13155 }
13156
13157 if (len < dof->dofh_loadsz) {
13158 dtrace_dof_destroy(dof);
13159 dtrace_dof_error(NULL, "truncated DOF");
13160 return (NULL);
13161 }
13162
13163 if (len != dof->dofh_loadsz) {
13164 dtrace_dof_destroy(dof);
13165 dtrace_dof_error(NULL, "invalid DOF size");
13166 return (NULL);
13167 }
13168
13169 if (dof->dofh_loadsz >= (uint64_t)dtrace_dof_maxsize) {
13170 dtrace_dof_destroy(dof);
13171 dtrace_dof_error(NULL, "oversized DOF");
13172 return (NULL);
13173 }
13174
13175 return (dof);
13176 }
13177
13178 /*
13179 * Return the dof_sec_t pointer corresponding to a given section index. If the
13180 * index is not valid, dtrace_dof_error() is called and NULL is returned. If
13181 * a type other than DOF_SECT_NONE is specified, the header is checked against
13182 * this type and NULL is returned if the types do not match.
13183 */
13184 static dof_sec_t *
dtrace_dof_sect(dof_hdr_t * dof,uint32_t type,dof_secidx_t i)13185 dtrace_dof_sect(dof_hdr_t *dof, uint32_t type, dof_secidx_t i)
13186 {
13187 dof_sec_t *sec = (dof_sec_t *)(uintptr_t)
13188 ((uintptr_t)dof + dof->dofh_secoff + i * dof->dofh_secsize);
13189
13190 if (i >= dof->dofh_secnum) {
13191 dtrace_dof_error(dof, "referenced section index is invalid");
13192 return (NULL);
13193 }
13194
13195 if (!(sec->dofs_flags & DOF_SECF_LOAD)) {
13196 dtrace_dof_error(dof, "referenced section is not loadable");
13197 return (NULL);
13198 }
13199
13200 if (type != DOF_SECT_NONE && type != sec->dofs_type) {
13201 dtrace_dof_error(dof, "referenced section is the wrong type");
13202 return (NULL);
13203 }
13204
13205 return (sec);
13206 }
13207
13208 static dtrace_probedesc_t *
dtrace_dof_probedesc(dof_hdr_t * dof,dof_sec_t * sec,dtrace_probedesc_t * desc)13209 dtrace_dof_probedesc(dof_hdr_t *dof, dof_sec_t *sec, dtrace_probedesc_t *desc)
13210 {
13211 dof_probedesc_t *probe;
13212 dof_sec_t *strtab;
13213 uintptr_t daddr = (uintptr_t)dof;
13214 uintptr_t str;
13215 size_t size;
13216
13217 if (sec->dofs_type != DOF_SECT_PROBEDESC) {
13218 dtrace_dof_error(dof, "invalid probe section");
13219 return (NULL);
13220 }
13221
13222 if (sec->dofs_align != sizeof (dof_secidx_t)) {
13223 dtrace_dof_error(dof, "bad alignment in probe description");
13224 return (NULL);
13225 }
13226
13227 if (sec->dofs_offset + sizeof (dof_probedesc_t) > dof->dofh_loadsz) {
13228 dtrace_dof_error(dof, "truncated probe description");
13229 return (NULL);
13230 }
13231
13232 probe = (dof_probedesc_t *)(uintptr_t)(daddr + sec->dofs_offset);
13233 strtab = dtrace_dof_sect(dof, DOF_SECT_STRTAB, probe->dofp_strtab);
13234
13235 if (strtab == NULL)
13236 return (NULL);
13237
13238 str = daddr + strtab->dofs_offset;
13239 size = strtab->dofs_size;
13240
13241 if (probe->dofp_provider >= strtab->dofs_size) {
13242 dtrace_dof_error(dof, "corrupt probe provider");
13243 return (NULL);
13244 }
13245
13246 (void) strncpy(desc->dtpd_provider,
13247 (char *)(str + probe->dofp_provider),
13248 MIN(DTRACE_PROVNAMELEN - 1, size - probe->dofp_provider));
13249
13250 /* APPLE NOTE: Darwin employs size bounded string operation. */
13251 desc->dtpd_provider[DTRACE_PROVNAMELEN - 1] = '\0';
13252
13253 if (probe->dofp_mod >= strtab->dofs_size) {
13254 dtrace_dof_error(dof, "corrupt probe module");
13255 return (NULL);
13256 }
13257
13258 (void) strncpy(desc->dtpd_mod, (char *)(str + probe->dofp_mod),
13259 MIN(DTRACE_MODNAMELEN - 1, size - probe->dofp_mod));
13260
13261 /* APPLE NOTE: Darwin employs size bounded string operation. */
13262 desc->dtpd_mod[DTRACE_MODNAMELEN - 1] = '\0';
13263
13264 if (probe->dofp_func >= strtab->dofs_size) {
13265 dtrace_dof_error(dof, "corrupt probe function");
13266 return (NULL);
13267 }
13268
13269 (void) strncpy(desc->dtpd_func, (char *)(str + probe->dofp_func),
13270 MIN(DTRACE_FUNCNAMELEN - 1, size - probe->dofp_func));
13271
13272 /* APPLE NOTE: Darwin employs size bounded string operation. */
13273 desc->dtpd_func[DTRACE_FUNCNAMELEN - 1] = '\0';
13274
13275 if (probe->dofp_name >= strtab->dofs_size) {
13276 dtrace_dof_error(dof, "corrupt probe name");
13277 return (NULL);
13278 }
13279
13280 (void) strncpy(desc->dtpd_name, (char *)(str + probe->dofp_name),
13281 MIN(DTRACE_NAMELEN - 1, size - probe->dofp_name));
13282
13283 /* APPLE NOTE: Darwin employs size bounded string operation. */
13284 desc->dtpd_name[DTRACE_NAMELEN - 1] = '\0';
13285
13286 return (desc);
13287 }
13288
13289 static dtrace_difo_t *
dtrace_dof_difo(dof_hdr_t * dof,dof_sec_t * sec,dtrace_vstate_t * vstate,cred_t * cr)13290 dtrace_dof_difo(dof_hdr_t *dof, dof_sec_t *sec, dtrace_vstate_t *vstate,
13291 cred_t *cr)
13292 {
13293 dtrace_difo_t *dp;
13294 size_t ttl = 0;
13295 dof_difohdr_t *dofd;
13296 uintptr_t daddr = (uintptr_t)dof;
13297 size_t max_size = dtrace_difo_maxsize;
13298 uint_t i;
13299 int l, n;
13300
13301
13302 static const struct {
13303 int section;
13304 int bufoffs;
13305 int lenoffs;
13306 int entsize;
13307 int align;
13308 const char *msg;
13309 } difo[] = {
13310 { DOF_SECT_DIF, offsetof(dtrace_difo_t, dtdo_buf),
13311 offsetof(dtrace_difo_t, dtdo_len), sizeof (dif_instr_t),
13312 sizeof (dif_instr_t), "multiple DIF sections" },
13313
13314 { DOF_SECT_INTTAB, offsetof(dtrace_difo_t, dtdo_inttab),
13315 offsetof(dtrace_difo_t, dtdo_intlen), sizeof (uint64_t),
13316 sizeof (uint64_t), "multiple integer tables" },
13317
13318 { DOF_SECT_STRTAB, offsetof(dtrace_difo_t, dtdo_strtab),
13319 offsetof(dtrace_difo_t, dtdo_strlen), 0,
13320 sizeof (char), "multiple string tables" },
13321
13322 { DOF_SECT_VARTAB, offsetof(dtrace_difo_t, dtdo_vartab),
13323 offsetof(dtrace_difo_t, dtdo_varlen), sizeof (dtrace_difv_t),
13324 sizeof (uint_t), "multiple variable tables" },
13325
13326 { DOF_SECT_NONE, 0, 0, 0, 0, NULL }
13327 };
13328
13329 if (sec->dofs_type != DOF_SECT_DIFOHDR) {
13330 dtrace_dof_error(dof, "invalid DIFO header section");
13331 return (NULL);
13332 }
13333
13334 if (sec->dofs_align != sizeof (dof_secidx_t)) {
13335 dtrace_dof_error(dof, "bad alignment in DIFO header");
13336 return (NULL);
13337 }
13338
13339 if (sec->dofs_size < sizeof (dof_difohdr_t) ||
13340 sec->dofs_size % sizeof (dof_secidx_t)) {
13341 dtrace_dof_error(dof, "bad size in DIFO header");
13342 return (NULL);
13343 }
13344
13345 dofd = (dof_difohdr_t *)(uintptr_t)(daddr + sec->dofs_offset);
13346 n = (sec->dofs_size - sizeof (*dofd)) / sizeof (dof_secidx_t) + 1;
13347
13348 dp = kmem_zalloc(sizeof (dtrace_difo_t), KM_SLEEP);
13349 dp->dtdo_rtype = dofd->dofd_rtype;
13350
13351 for (l = 0; l < n; l++) {
13352 dof_sec_t *subsec;
13353 void **bufp;
13354 uint32_t *lenp;
13355
13356 if ((subsec = dtrace_dof_sect(dof, DOF_SECT_NONE,
13357 dofd->dofd_links[l])) == NULL)
13358 goto err; /* invalid section link */
13359
13360 if (ttl + subsec->dofs_size > max_size) {
13361 dtrace_dof_error(dof, "exceeds maximum size");
13362 goto err;
13363 }
13364
13365 ttl += subsec->dofs_size;
13366
13367 for (i = 0; difo[i].section != DOF_SECT_NONE; i++) {
13368
13369 if (subsec->dofs_type != (uint32_t)difo[i].section)
13370 continue;
13371
13372 if (!(subsec->dofs_flags & DOF_SECF_LOAD)) {
13373 dtrace_dof_error(dof, "section not loaded");
13374 goto err;
13375 }
13376
13377 if (subsec->dofs_align != (uint32_t)difo[i].align) {
13378 dtrace_dof_error(dof, "bad alignment");
13379 goto err;
13380 }
13381
13382 bufp = (void **)((uintptr_t)dp + difo[i].bufoffs);
13383 lenp = (uint32_t *)((uintptr_t)dp + difo[i].lenoffs);
13384
13385 if (*bufp != NULL) {
13386 dtrace_dof_error(dof, difo[i].msg);
13387 goto err;
13388 }
13389
13390 if ((uint32_t)difo[i].entsize != subsec->dofs_entsize) {
13391 dtrace_dof_error(dof, "entry size mismatch");
13392 goto err;
13393 }
13394
13395 if (subsec->dofs_entsize != 0 &&
13396 (subsec->dofs_size % subsec->dofs_entsize) != 0) {
13397 dtrace_dof_error(dof, "corrupt entry size");
13398 goto err;
13399 }
13400
13401 *lenp = subsec->dofs_size;
13402 *bufp = kmem_alloc(subsec->dofs_size, KM_SLEEP);
13403 bcopy((char *)(uintptr_t)(daddr + subsec->dofs_offset),
13404 *bufp, subsec->dofs_size);
13405
13406 if (subsec->dofs_entsize != 0)
13407 *lenp /= subsec->dofs_entsize;
13408
13409 break;
13410 }
13411
13412 /*
13413 * If we encounter a loadable DIFO sub-section that is not
13414 * known to us, assume this is a broken program and fail.
13415 */
13416 if (difo[i].section == DOF_SECT_NONE &&
13417 (subsec->dofs_flags & DOF_SECF_LOAD)) {
13418 dtrace_dof_error(dof, "unrecognized DIFO subsection");
13419 goto err;
13420 }
13421 }
13422
13423 if (dp->dtdo_buf == NULL) {
13424 /*
13425 * We can't have a DIF object without DIF text.
13426 */
13427 dtrace_dof_error(dof, "missing DIF text");
13428 goto err;
13429 }
13430
13431 /*
13432 * Before we validate the DIF object, run through the variable table
13433 * looking for the strings -- if any of their size are under, we'll set
13434 * their size to be the system-wide default string size. Note that
13435 * this should _not_ happen if the "strsize" option has been set --
13436 * in this case, the compiler should have set the size to reflect the
13437 * setting of the option.
13438 */
13439 for (i = 0; i < dp->dtdo_varlen; i++) {
13440 dtrace_difv_t *v = &dp->dtdo_vartab[i];
13441 dtrace_diftype_t *t = &v->dtdv_type;
13442
13443 if (v->dtdv_id < DIF_VAR_OTHER_UBASE)
13444 continue;
13445
13446 if (t->dtdt_kind == DIF_TYPE_STRING && t->dtdt_size == 0)
13447 t->dtdt_size = dtrace_strsize_default;
13448 }
13449
13450 if (dtrace_difo_validate(dp, vstate, DIF_DIR_NREGS, cr) != 0)
13451 goto err;
13452
13453 dtrace_difo_init(dp, vstate);
13454 return (dp);
13455
13456 err:
13457 kmem_free(dp->dtdo_buf, dp->dtdo_len * sizeof (dif_instr_t));
13458 kmem_free(dp->dtdo_inttab, dp->dtdo_intlen * sizeof (uint64_t));
13459 kmem_free(dp->dtdo_strtab, dp->dtdo_strlen);
13460 kmem_free(dp->dtdo_vartab, dp->dtdo_varlen * sizeof (dtrace_difv_t));
13461
13462 kmem_free(dp, sizeof (dtrace_difo_t));
13463 return (NULL);
13464 }
13465
13466 static dtrace_predicate_t *
dtrace_dof_predicate(dof_hdr_t * dof,dof_sec_t * sec,dtrace_vstate_t * vstate,cred_t * cr)13467 dtrace_dof_predicate(dof_hdr_t *dof, dof_sec_t *sec, dtrace_vstate_t *vstate,
13468 cred_t *cr)
13469 {
13470 dtrace_difo_t *dp;
13471
13472 if ((dp = dtrace_dof_difo(dof, sec, vstate, cr)) == NULL)
13473 return (NULL);
13474
13475 return (dtrace_predicate_create(dp));
13476 }
13477
13478 static dtrace_actdesc_t *
dtrace_dof_actdesc(dof_hdr_t * dof,dof_sec_t * sec,dtrace_vstate_t * vstate,cred_t * cr)13479 dtrace_dof_actdesc(dof_hdr_t *dof, dof_sec_t *sec, dtrace_vstate_t *vstate,
13480 cred_t *cr)
13481 {
13482 dtrace_actdesc_t *act, *first = NULL, *last = NULL, *next;
13483 dof_actdesc_t *desc;
13484 dof_sec_t *difosec;
13485 size_t offs;
13486 uintptr_t daddr = (uintptr_t)dof;
13487 uint64_t arg;
13488 dtrace_actkind_t kind;
13489
13490 if (sec->dofs_type != DOF_SECT_ACTDESC) {
13491 dtrace_dof_error(dof, "invalid action section");
13492 return (NULL);
13493 }
13494
13495 if (sec->dofs_offset + sizeof (dof_actdesc_t) > dof->dofh_loadsz) {
13496 dtrace_dof_error(dof, "truncated action description");
13497 return (NULL);
13498 }
13499
13500 if (sec->dofs_align != sizeof (uint64_t)) {
13501 dtrace_dof_error(dof, "bad alignment in action description");
13502 return (NULL);
13503 }
13504
13505 if (sec->dofs_size < sec->dofs_entsize) {
13506 dtrace_dof_error(dof, "section entry size exceeds total size");
13507 return (NULL);
13508 }
13509
13510 if (sec->dofs_entsize != sizeof (dof_actdesc_t)) {
13511 dtrace_dof_error(dof, "bad entry size in action description");
13512 return (NULL);
13513 }
13514
13515 if (sec->dofs_size / sec->dofs_entsize > dtrace_actions_max) {
13516 dtrace_dof_error(dof, "actions exceed dtrace_actions_max");
13517 return (NULL);
13518 }
13519
13520 for (offs = 0; offs < sec->dofs_size; offs += sec->dofs_entsize) {
13521 desc = (dof_actdesc_t *)(daddr +
13522 (uintptr_t)sec->dofs_offset + offs);
13523 kind = (dtrace_actkind_t)desc->dofa_kind;
13524
13525 if ((DTRACEACT_ISPRINTFLIKE(kind) &&
13526 (kind != DTRACEACT_PRINTA || desc->dofa_strtab != DOF_SECIDX_NONE)) ||
13527 (kind == DTRACEACT_DIFEXPR && desc->dofa_strtab != DOF_SECIDX_NONE))
13528 {
13529 dof_sec_t *strtab;
13530 char *str, *fmt;
13531 uint64_t i;
13532
13533 /*
13534 * The argument to these actions is an index into the
13535 * DOF string table. For printf()-like actions, this
13536 * is the format string. For print(), this is the
13537 * CTF type of the expression result.
13538 */
13539 if ((strtab = dtrace_dof_sect(dof,
13540 DOF_SECT_STRTAB, desc->dofa_strtab)) == NULL)
13541 goto err;
13542
13543 str = (char *)((uintptr_t)dof +
13544 (uintptr_t)strtab->dofs_offset);
13545
13546 for (i = desc->dofa_arg; i < strtab->dofs_size; i++) {
13547 if (str[i] == '\0')
13548 break;
13549 }
13550
13551 if (i >= strtab->dofs_size) {
13552 dtrace_dof_error(dof, "bogus format string");
13553 goto err;
13554 }
13555
13556 if (i == desc->dofa_arg) {
13557 dtrace_dof_error(dof, "empty format string");
13558 goto err;
13559 }
13560
13561 i -= desc->dofa_arg;
13562 fmt = kmem_alloc(i + 1, KM_SLEEP);
13563 bcopy(&str[desc->dofa_arg], fmt, i + 1);
13564 arg = (uint64_t)(uintptr_t)fmt;
13565 } else {
13566 if (kind == DTRACEACT_PRINTA) {
13567 ASSERT(desc->dofa_strtab == DOF_SECIDX_NONE);
13568 arg = 0;
13569 } else {
13570 arg = desc->dofa_arg;
13571 }
13572 }
13573
13574 act = dtrace_actdesc_create(kind, desc->dofa_ntuple,
13575 desc->dofa_uarg, arg);
13576
13577 if (last != NULL) {
13578 last->dtad_next = act;
13579 } else {
13580 first = act;
13581 }
13582
13583 last = act;
13584
13585 if (desc->dofa_difo == DOF_SECIDX_NONE)
13586 continue;
13587
13588 if ((difosec = dtrace_dof_sect(dof,
13589 DOF_SECT_DIFOHDR, desc->dofa_difo)) == NULL)
13590 goto err;
13591
13592 act->dtad_difo = dtrace_dof_difo(dof, difosec, vstate, cr);
13593
13594 if (act->dtad_difo == NULL)
13595 goto err;
13596 }
13597
13598 ASSERT(first != NULL);
13599 return (first);
13600
13601 err:
13602 for (act = first; act != NULL; act = next) {
13603 next = act->dtad_next;
13604 dtrace_actdesc_release(act, vstate);
13605 }
13606
13607 return (NULL);
13608 }
13609
13610 static dtrace_ecbdesc_t *
dtrace_dof_ecbdesc(dof_hdr_t * dof,dof_sec_t * sec,dtrace_vstate_t * vstate,cred_t * cr)13611 dtrace_dof_ecbdesc(dof_hdr_t *dof, dof_sec_t *sec, dtrace_vstate_t *vstate,
13612 cred_t *cr)
13613 {
13614 dtrace_ecbdesc_t *ep;
13615 dof_ecbdesc_t *ecb;
13616 dtrace_probedesc_t *desc;
13617 dtrace_predicate_t *pred = NULL;
13618
13619 if (sec->dofs_size < sizeof (dof_ecbdesc_t)) {
13620 dtrace_dof_error(dof, "truncated ECB description");
13621 return (NULL);
13622 }
13623
13624 if (sec->dofs_align != sizeof (uint64_t)) {
13625 dtrace_dof_error(dof, "bad alignment in ECB description");
13626 return (NULL);
13627 }
13628
13629 ecb = (dof_ecbdesc_t *)((uintptr_t)dof + (uintptr_t)sec->dofs_offset);
13630 sec = dtrace_dof_sect(dof, DOF_SECT_PROBEDESC, ecb->dofe_probes);
13631
13632 if (sec == NULL)
13633 return (NULL);
13634
13635 ep = kmem_zalloc(sizeof (dtrace_ecbdesc_t), KM_SLEEP);
13636 ep->dted_uarg = ecb->dofe_uarg;
13637 desc = &ep->dted_probe;
13638
13639 if (dtrace_dof_probedesc(dof, sec, desc) == NULL)
13640 goto err;
13641
13642 if (ecb->dofe_pred != DOF_SECIDX_NONE) {
13643 if ((sec = dtrace_dof_sect(dof,
13644 DOF_SECT_DIFOHDR, ecb->dofe_pred)) == NULL)
13645 goto err;
13646
13647 if ((pred = dtrace_dof_predicate(dof, sec, vstate, cr)) == NULL)
13648 goto err;
13649
13650 ep->dted_pred.dtpdd_predicate = pred;
13651 }
13652
13653 if (ecb->dofe_actions != DOF_SECIDX_NONE) {
13654 if ((sec = dtrace_dof_sect(dof,
13655 DOF_SECT_ACTDESC, ecb->dofe_actions)) == NULL)
13656 goto err;
13657
13658 ep->dted_action = dtrace_dof_actdesc(dof, sec, vstate, cr);
13659
13660 if (ep->dted_action == NULL)
13661 goto err;
13662 }
13663
13664 return (ep);
13665
13666 err:
13667 if (pred != NULL)
13668 dtrace_predicate_release(pred, vstate);
13669 kmem_free(ep, sizeof (dtrace_ecbdesc_t));
13670 return (NULL);
13671 }
13672
13673 /*
13674 * APPLE NOTE: dyld handles dof relocation.
13675 * Darwin does not need dtrace_dof_relocate()
13676 */
13677
13678 /*
13679 * The dof_hdr_t passed to dtrace_dof_slurp() should be a partially validated
13680 * header: it should be at the front of a memory region that is at least
13681 * sizeof (dof_hdr_t) in size -- and then at least dof_hdr.dofh_loadsz in
13682 * size. It need not be validated in any other way.
13683 */
13684 static int
dtrace_dof_slurp(dof_hdr_t * dof,dtrace_vstate_t * vstate,cred_t * cr,dtrace_enabling_t ** enabp,uint64_t ubase,int noprobes)13685 dtrace_dof_slurp(dof_hdr_t *dof, dtrace_vstate_t *vstate, cred_t *cr,
13686 dtrace_enabling_t **enabp, uint64_t ubase, int noprobes)
13687 {
13688 #pragma unused(ubase) /* __APPLE__ */
13689 uint64_t len = dof->dofh_loadsz, seclen;
13690 uintptr_t daddr = (uintptr_t)dof;
13691 dtrace_ecbdesc_t *ep;
13692 dtrace_enabling_t *enab;
13693 uint_t i;
13694
13695 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
13696 ASSERT(dof->dofh_loadsz >= sizeof (dof_hdr_t));
13697
13698 /*
13699 * Check the DOF header identification bytes. In addition to checking
13700 * valid settings, we also verify that unused bits/bytes are zeroed so
13701 * we can use them later without fear of regressing existing binaries.
13702 */
13703 if (bcmp(&dof->dofh_ident[DOF_ID_MAG0],
13704 DOF_MAG_STRING, DOF_MAG_STRLEN) != 0) {
13705 dtrace_dof_error(dof, "DOF magic string mismatch");
13706 return (-1);
13707 }
13708
13709 if (dof->dofh_ident[DOF_ID_MODEL] != DOF_MODEL_ILP32 &&
13710 dof->dofh_ident[DOF_ID_MODEL] != DOF_MODEL_LP64) {
13711 dtrace_dof_error(dof, "DOF has invalid data model");
13712 return (-1);
13713 }
13714
13715 if (dof->dofh_ident[DOF_ID_ENCODING] != DOF_ENCODE_NATIVE) {
13716 dtrace_dof_error(dof, "DOF encoding mismatch");
13717 return (-1);
13718 }
13719
13720 /*
13721 * APPLE NOTE: Darwin only supports DOF_VERSION_3 for now.
13722 */
13723 if (dof->dofh_ident[DOF_ID_VERSION] != DOF_VERSION_3) {
13724 dtrace_dof_error(dof, "DOF version mismatch");
13725 return (-1);
13726 }
13727
13728 if (dof->dofh_ident[DOF_ID_DIFVERS] != DIF_VERSION_2) {
13729 dtrace_dof_error(dof, "DOF uses unsupported instruction set");
13730 return (-1);
13731 }
13732
13733 if (dof->dofh_ident[DOF_ID_DIFIREG] > DIF_DIR_NREGS) {
13734 dtrace_dof_error(dof, "DOF uses too many integer registers");
13735 return (-1);
13736 }
13737
13738 if (dof->dofh_ident[DOF_ID_DIFTREG] > DIF_DTR_NREGS) {
13739 dtrace_dof_error(dof, "DOF uses too many tuple registers");
13740 return (-1);
13741 }
13742
13743 for (i = DOF_ID_PAD; i < DOF_ID_SIZE; i++) {
13744 if (dof->dofh_ident[i] != 0) {
13745 dtrace_dof_error(dof, "DOF has invalid ident byte set");
13746 return (-1);
13747 }
13748 }
13749
13750 if (dof->dofh_flags & ~DOF_FL_VALID) {
13751 dtrace_dof_error(dof, "DOF has invalid flag bits set");
13752 return (-1);
13753 }
13754
13755 if (dof->dofh_secsize < sizeof(dof_sec_t)) {
13756 dtrace_dof_error(dof, "invalid section header size");
13757 return (-1);
13758 }
13759
13760 /*
13761 * Check that the section headers don't exceed the amount of DOF
13762 * data. Note that we cast the section size and number of sections
13763 * to uint64_t's to prevent possible overflow in the multiplication.
13764 */
13765 seclen = (uint64_t)dof->dofh_secnum * (uint64_t)dof->dofh_secsize;
13766
13767 if (dof->dofh_secoff > len || seclen > len ||
13768 dof->dofh_secoff + seclen > len) {
13769 dtrace_dof_error(dof, "truncated section headers");
13770 return (-1);
13771 }
13772
13773 if (!IS_P2ALIGNED(dof->dofh_secoff, sizeof (uint64_t))) {
13774 dtrace_dof_error(dof, "misaligned section headers");
13775 return (-1);
13776 }
13777
13778 if (!IS_P2ALIGNED(dof->dofh_secsize, sizeof (uint64_t))) {
13779 dtrace_dof_error(dof, "misaligned section size");
13780 return (-1);
13781 }
13782
13783 /*
13784 * Take an initial pass through the section headers to be sure that
13785 * the headers don't have stray offsets. If the 'noprobes' flag is
13786 * set, do not permit sections relating to providers, probes, or args.
13787 */
13788 for (i = 0; i < dof->dofh_secnum; i++) {
13789 dof_sec_t *sec = (dof_sec_t *)(daddr +
13790 (uintptr_t)dof->dofh_secoff + i * dof->dofh_secsize);
13791
13792 if (noprobes) {
13793 switch (sec->dofs_type) {
13794 case DOF_SECT_PROVIDER:
13795 case DOF_SECT_PROBES:
13796 case DOF_SECT_PRARGS:
13797 case DOF_SECT_PROFFS:
13798 dtrace_dof_error(dof, "illegal sections "
13799 "for enabling");
13800 return (-1);
13801 }
13802 }
13803
13804 if (sec->dofs_align & (sec->dofs_align - 1)) {
13805 dtrace_dof_error(dof, "bad section alignment");
13806 return (-1);
13807 }
13808
13809 if (sec->dofs_offset & (sec->dofs_align - 1)) {
13810 dtrace_dof_error(dof, "misaligned section");
13811 return (-1);
13812 }
13813
13814 if (sec->dofs_offset > len || sec->dofs_size > len ||
13815 sec->dofs_offset + sec->dofs_size > len) {
13816 dtrace_dof_error(dof, "corrupt section header");
13817 return (-1);
13818 }
13819
13820 if (sec->dofs_type == DOF_SECT_STRTAB && *((char *)daddr +
13821 sec->dofs_offset + sec->dofs_size - 1) != '\0') {
13822 dtrace_dof_error(dof, "non-terminating string table");
13823 return (-1);
13824 }
13825 }
13826
13827 /*
13828 * APPLE NOTE: We have no further relocation to perform.
13829 * All dof values are relative offsets.
13830 */
13831
13832 if ((enab = *enabp) == NULL)
13833 enab = *enabp = dtrace_enabling_create(vstate);
13834
13835 for (i = 0; i < dof->dofh_secnum; i++) {
13836 dof_sec_t *sec = (dof_sec_t *)(daddr +
13837 (uintptr_t)dof->dofh_secoff + i * dof->dofh_secsize);
13838
13839 if (sec->dofs_type != DOF_SECT_ECBDESC)
13840 continue;
13841
13842 /*
13843 * APPLE NOTE: Defend against gcc 4.0 botch on x86.
13844 * not all paths out of inlined dtrace_dof_ecbdesc
13845 * are checked for the NULL return value.
13846 * Check for NULL explicitly here.
13847 */
13848 ep = dtrace_dof_ecbdesc(dof, sec, vstate, cr);
13849 if (ep == NULL) {
13850 dtrace_enabling_destroy(enab);
13851 *enabp = NULL;
13852 return (-1);
13853 }
13854
13855 dtrace_enabling_add(enab, ep);
13856 }
13857
13858 return (0);
13859 }
13860
13861 /*
13862 * Process DOF for any options. This routine assumes that the DOF has been
13863 * at least processed by dtrace_dof_slurp().
13864 */
13865 static int
dtrace_dof_options(dof_hdr_t * dof,dtrace_state_t * state)13866 dtrace_dof_options(dof_hdr_t *dof, dtrace_state_t *state)
13867 {
13868 uint_t i;
13869 int rval;
13870 uint32_t entsize;
13871 size_t offs;
13872 dof_optdesc_t *desc;
13873
13874 for (i = 0; i < dof->dofh_secnum; i++) {
13875 dof_sec_t *sec = (dof_sec_t *)((uintptr_t)dof +
13876 (uintptr_t)dof->dofh_secoff + i * dof->dofh_secsize);
13877
13878 if (sec->dofs_type != DOF_SECT_OPTDESC)
13879 continue;
13880
13881 if (sec->dofs_align != sizeof (uint64_t)) {
13882 dtrace_dof_error(dof, "bad alignment in "
13883 "option description");
13884 return (EINVAL);
13885 }
13886
13887 if ((entsize = sec->dofs_entsize) == 0) {
13888 dtrace_dof_error(dof, "zeroed option entry size");
13889 return (EINVAL);
13890 }
13891
13892 if (entsize < sizeof (dof_optdesc_t)) {
13893 dtrace_dof_error(dof, "bad option entry size");
13894 return (EINVAL);
13895 }
13896
13897 for (offs = 0; offs < sec->dofs_size; offs += entsize) {
13898 desc = (dof_optdesc_t *)((uintptr_t)dof +
13899 (uintptr_t)sec->dofs_offset + offs);
13900
13901 if (desc->dofo_strtab != DOF_SECIDX_NONE) {
13902 dtrace_dof_error(dof, "non-zero option string");
13903 return (EINVAL);
13904 }
13905
13906 if (desc->dofo_value == (uint64_t)DTRACEOPT_UNSET) {
13907 dtrace_dof_error(dof, "unset option");
13908 return (EINVAL);
13909 }
13910
13911 if ((rval = dtrace_state_option(state,
13912 desc->dofo_option, desc->dofo_value)) != 0) {
13913 dtrace_dof_error(dof, "rejected option");
13914 return (rval);
13915 }
13916 }
13917 }
13918
13919 return (0);
13920 }
13921
13922 /*
13923 * DTrace Consumer State Functions
13924 */
13925 static int
dtrace_dstate_init(dtrace_dstate_t * dstate,size_t size)13926 dtrace_dstate_init(dtrace_dstate_t *dstate, size_t size)
13927 {
13928 size_t hashsize, maxper, min_size, chunksize = dstate->dtds_chunksize;
13929 void *base;
13930 uintptr_t limit;
13931 dtrace_dynvar_t *dvar, *next, *start;
13932 size_t i;
13933
13934 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
13935 ASSERT(dstate->dtds_base == NULL && dstate->dtds_percpu == NULL);
13936
13937 bzero(dstate, sizeof (dtrace_dstate_t));
13938
13939 if ((dstate->dtds_chunksize = chunksize) == 0)
13940 dstate->dtds_chunksize = DTRACE_DYNVAR_CHUNKSIZE;
13941
13942 VERIFY(dstate->dtds_chunksize < (LONG_MAX - sizeof (dtrace_dynhash_t)));
13943
13944 if (size < (min_size = dstate->dtds_chunksize + sizeof (dtrace_dynhash_t)))
13945 size = min_size;
13946
13947 if ((base = kmem_zalloc(size, KM_NOSLEEP)) == NULL)
13948 return (ENOMEM);
13949
13950 dstate->dtds_size = size;
13951 dstate->dtds_base = base;
13952 dstate->dtds_percpu = kmem_cache_alloc(dtrace_state_cache, KM_SLEEP);
13953 bzero(dstate->dtds_percpu, (int)NCPU * sizeof (dtrace_dstate_percpu_t));
13954
13955 hashsize = size / (dstate->dtds_chunksize + sizeof (dtrace_dynhash_t));
13956
13957 if (hashsize != 1 && (hashsize & 1))
13958 hashsize--;
13959
13960 dstate->dtds_hashsize = hashsize;
13961 dstate->dtds_hash = dstate->dtds_base;
13962
13963 /*
13964 * Set all of our hash buckets to point to the single sink, and (if
13965 * it hasn't already been set), set the sink's hash value to be the
13966 * sink sentinel value. The sink is needed for dynamic variable
13967 * lookups to know that they have iterated over an entire, valid hash
13968 * chain.
13969 */
13970 for (i = 0; i < hashsize; i++)
13971 dstate->dtds_hash[i].dtdh_chain = &dtrace_dynhash_sink;
13972
13973 if (dtrace_dynhash_sink.dtdv_hashval != DTRACE_DYNHASH_SINK)
13974 dtrace_dynhash_sink.dtdv_hashval = DTRACE_DYNHASH_SINK;
13975
13976 /*
13977 * Determine number of active CPUs. Divide free list evenly among
13978 * active CPUs.
13979 */
13980 start = (dtrace_dynvar_t *)
13981 ((uintptr_t)base + hashsize * sizeof (dtrace_dynhash_t));
13982 limit = (uintptr_t)base + size;
13983
13984 VERIFY((uintptr_t)start < limit);
13985 VERIFY((uintptr_t)start >= (uintptr_t)base);
13986
13987 maxper = (limit - (uintptr_t)start) / (int)NCPU;
13988 maxper = (maxper / dstate->dtds_chunksize) * dstate->dtds_chunksize;
13989
13990 for (i = 0; i < NCPU; i++) {
13991 dstate->dtds_percpu[i].dtdsc_free = dvar = start;
13992
13993 /*
13994 * If we don't even have enough chunks to make it once through
13995 * NCPUs, we're just going to allocate everything to the first
13996 * CPU. And if we're on the last CPU, we're going to allocate
13997 * whatever is left over. In either case, we set the limit to
13998 * be the limit of the dynamic variable space.
13999 */
14000 if (maxper == 0 || i == NCPU - 1) {
14001 limit = (uintptr_t)base + size;
14002 start = NULL;
14003 } else {
14004 limit = (uintptr_t)start + maxper;
14005 start = (dtrace_dynvar_t *)limit;
14006 }
14007
14008 VERIFY(limit <= (uintptr_t)base + size);
14009
14010 for (;;) {
14011 next = (dtrace_dynvar_t *)((uintptr_t)dvar +
14012 dstate->dtds_chunksize);
14013
14014 if ((uintptr_t)next + dstate->dtds_chunksize >= limit)
14015 break;
14016
14017 VERIFY((uintptr_t)dvar >= (uintptr_t)base &&
14018 (uintptr_t)dvar <= (uintptr_t)base + size);
14019 dvar->dtdv_next = next;
14020 dvar = next;
14021 }
14022
14023 if (maxper == 0)
14024 break;
14025 }
14026
14027 return (0);
14028 }
14029
14030 static void
dtrace_dstate_fini(dtrace_dstate_t * dstate)14031 dtrace_dstate_fini(dtrace_dstate_t *dstate)
14032 {
14033 LCK_MTX_ASSERT(&cpu_lock, LCK_MTX_ASSERT_OWNED);
14034
14035 if (dstate->dtds_base == NULL)
14036 return;
14037
14038 kmem_free(dstate->dtds_base, dstate->dtds_size);
14039 kmem_cache_free(dtrace_state_cache, dstate->dtds_percpu);
14040 }
14041
14042 static void
dtrace_vstate_fini(dtrace_vstate_t * vstate)14043 dtrace_vstate_fini(dtrace_vstate_t *vstate)
14044 {
14045 /*
14046 * Logical XOR, where are you?
14047 */
14048 ASSERT((vstate->dtvs_nglobals == 0) ^ (vstate->dtvs_globals != NULL));
14049
14050 if (vstate->dtvs_nglobals > 0) {
14051 kmem_free(vstate->dtvs_globals, vstate->dtvs_nglobals *
14052 sizeof (dtrace_statvar_t *));
14053 }
14054
14055 if (vstate->dtvs_ntlocals > 0) {
14056 kmem_free(vstate->dtvs_tlocals, vstate->dtvs_ntlocals *
14057 sizeof (dtrace_difv_t));
14058 }
14059
14060 ASSERT((vstate->dtvs_nlocals == 0) ^ (vstate->dtvs_locals != NULL));
14061
14062 if (vstate->dtvs_nlocals > 0) {
14063 kmem_free(vstate->dtvs_locals, vstate->dtvs_nlocals *
14064 sizeof (dtrace_statvar_t *));
14065 }
14066 }
14067
14068 static void
dtrace_state_clean(dtrace_state_t * state)14069 dtrace_state_clean(dtrace_state_t *state)
14070 {
14071 if (state->dts_activity == DTRACE_ACTIVITY_INACTIVE)
14072 return;
14073
14074 dtrace_dynvar_clean(&state->dts_vstate.dtvs_dynvars);
14075 dtrace_speculation_clean(state);
14076 }
14077
14078 static void
dtrace_state_deadman(dtrace_state_t * state)14079 dtrace_state_deadman(dtrace_state_t *state)
14080 {
14081 hrtime_t now;
14082
14083 dtrace_sync();
14084
14085 now = dtrace_gethrtime();
14086
14087 if (state != dtrace_anon.dta_state &&
14088 now - state->dts_laststatus >= dtrace_deadman_user)
14089 return;
14090
14091 /*
14092 * We must be sure that dts_alive never appears to be less than the
14093 * value upon entry to dtrace_state_deadman(), and because we lack a
14094 * dtrace_cas64(), we cannot store to it atomically. We thus instead
14095 * store INT64_MAX to it, followed by a memory barrier, followed by
14096 * the new value. This assures that dts_alive never appears to be
14097 * less than its true value, regardless of the order in which the
14098 * stores to the underlying storage are issued.
14099 */
14100 state->dts_alive = INT64_MAX;
14101 dtrace_membar_producer();
14102 state->dts_alive = now;
14103 }
14104
14105 static int
dtrace_state_create(dev_t * devp,cred_t * cr,dtrace_state_t ** new_state)14106 dtrace_state_create(dev_t *devp, cred_t *cr, dtrace_state_t **new_state)
14107 {
14108 minor_t minor;
14109 major_t major;
14110 char c[30];
14111 dtrace_state_t *state;
14112 dtrace_optval_t *opt;
14113 int bufsize = (int)NCPU * sizeof (dtrace_buffer_t), i;
14114 unsigned int cpu_it;
14115
14116 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
14117 LCK_MTX_ASSERT(&cpu_lock, LCK_MTX_ASSERT_OWNED);
14118
14119 /* Cause restart */
14120 *new_state = NULL;
14121
14122 if (devp != NULL) {
14123 minor = getminor(*devp);
14124 }
14125 else {
14126 minor = DTRACE_NCLIENTS - 1;
14127 }
14128
14129 state = dtrace_state_allocate(minor);
14130 if (NULL == state) {
14131 printf("dtrace_open: couldn't acquire minor number %d. This usually means that too many DTrace clients are in use at the moment", minor);
14132 return (ERESTART); /* can't reacquire */
14133 }
14134
14135 state->dts_epid = DTRACE_EPIDNONE + 1;
14136
14137 (void) snprintf(c, sizeof (c), "dtrace_aggid_%d", minor);
14138 state->dts_aggid_arena = vmem_create(c, (void *)1, INT32_MAX, 1,
14139 NULL, NULL, NULL, 0, VM_SLEEP | VMC_IDENTIFIER);
14140
14141 if (devp != NULL) {
14142 major = getemajor(*devp);
14143 } else {
14144 major = ddi_driver_major(dtrace_devi);
14145 }
14146
14147 state->dts_dev = makedev(major, minor);
14148
14149 if (devp != NULL)
14150 *devp = state->dts_dev;
14151
14152 /*
14153 * We allocate NCPU buffers. On the one hand, this can be quite
14154 * a bit of memory per instance (nearly 36K on a Starcat). On the
14155 * other hand, it saves an additional memory reference in the probe
14156 * path.
14157 */
14158 state->dts_buffer = kmem_zalloc(bufsize, KM_SLEEP);
14159 state->dts_aggbuffer = kmem_zalloc(bufsize, KM_SLEEP);
14160 state->dts_buf_over_limit = 0;
14161
14162 /*
14163 * Allocate and initialise the per-process per-CPU random state.
14164 * SI_SUB_RANDOM < SI_SUB_DTRACE_ANON therefore entropy device is
14165 * assumed to be seeded at this point (if from Fortuna seed file).
14166 */
14167 state->dts_rstate = kmem_zalloc(NCPU * sizeof(uint64_t*), KM_SLEEP);
14168 state->dts_rstate[0] = kmem_zalloc(2 * sizeof(uint64_t), KM_SLEEP);
14169 (void) read_random(state->dts_rstate[0], 2 * sizeof(uint64_t));
14170 for (cpu_it = 1; cpu_it < NCPU; cpu_it++) {
14171 state->dts_rstate[cpu_it] = kmem_zalloc(2 * sizeof(uint64_t), KM_SLEEP);
14172 /*
14173 * Each CPU is assigned a 2^64 period, non-overlapping
14174 * subsequence.
14175 */
14176 dtrace_xoroshiro128_plus_jump(state->dts_rstate[cpu_it-1],
14177 state->dts_rstate[cpu_it]);
14178 }
14179
14180 state->dts_cleaner = CYCLIC_NONE;
14181 state->dts_deadman = CYCLIC_NONE;
14182 state->dts_vstate.dtvs_state = state;
14183
14184 for (i = 0; i < DTRACEOPT_MAX; i++)
14185 state->dts_options[i] = DTRACEOPT_UNSET;
14186
14187 /*
14188 * Set the default options.
14189 */
14190 opt = state->dts_options;
14191 opt[DTRACEOPT_BUFPOLICY] = DTRACEOPT_BUFPOLICY_SWITCH;
14192 opt[DTRACEOPT_BUFRESIZE] = DTRACEOPT_BUFRESIZE_AUTO;
14193 opt[DTRACEOPT_NSPEC] = dtrace_nspec_default;
14194 opt[DTRACEOPT_SPECSIZE] = dtrace_specsize_default;
14195 opt[DTRACEOPT_CPU] = (dtrace_optval_t)DTRACE_CPUALL;
14196 opt[DTRACEOPT_STRSIZE] = dtrace_strsize_default;
14197 opt[DTRACEOPT_STACKFRAMES] = dtrace_stackframes_default;
14198 opt[DTRACEOPT_USTACKFRAMES] = dtrace_ustackframes_default;
14199 opt[DTRACEOPT_CLEANRATE] = dtrace_cleanrate_default;
14200 opt[DTRACEOPT_AGGRATE] = dtrace_aggrate_default;
14201 opt[DTRACEOPT_SWITCHRATE] = dtrace_switchrate_default;
14202 opt[DTRACEOPT_STATUSRATE] = dtrace_statusrate_default;
14203 opt[DTRACEOPT_JSTACKFRAMES] = dtrace_jstackframes_default;
14204 opt[DTRACEOPT_JSTACKSTRSIZE] = dtrace_jstackstrsize_default;
14205 opt[DTRACEOPT_BUFLIMIT] = dtrace_buflimit_default;
14206
14207 /*
14208 * Depending on the user credentials, we set flag bits which alter probe
14209 * visibility or the amount of destructiveness allowed. In the case of
14210 * actual anonymous tracing, or the possession of all privileges, all of
14211 * the normal checks are bypassed.
14212 */
14213 #if defined(__APPLE__)
14214 if (cr != NULL) {
14215 kauth_cred_ref(cr);
14216 state->dts_cred.dcr_cred = cr;
14217 }
14218 if (cr == NULL || PRIV_POLICY_ONLY(cr, PRIV_ALL, B_FALSE)) {
14219 if (dtrace_is_restricted() && !dtrace_are_restrictions_relaxed()) {
14220 /*
14221 * Allow only proc credentials when DTrace is
14222 * restricted by the current security policy
14223 */
14224 state->dts_cred.dcr_visible = DTRACE_CRV_ALLPROC;
14225 state->dts_cred.dcr_action = DTRACE_CRA_PROC | DTRACE_CRA_PROC_CONTROL | DTRACE_CRA_PROC_DESTRUCTIVE_ALLUSER;
14226 }
14227 else {
14228 state->dts_cred.dcr_visible = DTRACE_CRV_ALL;
14229 state->dts_cred.dcr_action = DTRACE_CRA_ALL;
14230 }
14231 }
14232
14233 #else
14234 if (cr == NULL || PRIV_POLICY_ONLY(cr, PRIV_ALL, B_FALSE)) {
14235 state->dts_cred.dcr_visible = DTRACE_CRV_ALL;
14236 state->dts_cred.dcr_action = DTRACE_CRA_ALL;
14237 }
14238 else {
14239 /*
14240 * Set up the credentials for this instantiation. We take a
14241 * hold on the credential to prevent it from disappearing on
14242 * us; this in turn prevents the zone_t referenced by this
14243 * credential from disappearing. This means that we can
14244 * examine the credential and the zone from probe context.
14245 */
14246 crhold(cr);
14247 state->dts_cred.dcr_cred = cr;
14248
14249 /*
14250 * CRA_PROC means "we have *some* privilege for dtrace" and
14251 * unlocks the use of variables like pid, zonename, etc.
14252 */
14253 if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_USER, B_FALSE) ||
14254 PRIV_POLICY_ONLY(cr, PRIV_DTRACE_PROC, B_FALSE)) {
14255 state->dts_cred.dcr_action |= DTRACE_CRA_PROC;
14256 }
14257
14258 /*
14259 * dtrace_user allows use of syscall and profile providers.
14260 * If the user also has proc_owner and/or proc_zone, we
14261 * extend the scope to include additional visibility and
14262 * destructive power.
14263 */
14264 if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_USER, B_FALSE)) {
14265 if (PRIV_POLICY_ONLY(cr, PRIV_PROC_OWNER, B_FALSE)) {
14266 state->dts_cred.dcr_visible |=
14267 DTRACE_CRV_ALLPROC;
14268
14269 state->dts_cred.dcr_action |=
14270 DTRACE_CRA_PROC_DESTRUCTIVE_ALLUSER;
14271 }
14272
14273 if (PRIV_POLICY_ONLY(cr, PRIV_PROC_ZONE, B_FALSE)) {
14274 state->dts_cred.dcr_visible |=
14275 DTRACE_CRV_ALLZONE;
14276
14277 state->dts_cred.dcr_action |=
14278 DTRACE_CRA_PROC_DESTRUCTIVE_ALLZONE;
14279 }
14280
14281 /*
14282 * If we have all privs in whatever zone this is,
14283 * we can do destructive things to processes which
14284 * have altered credentials.
14285 *
14286 * APPLE NOTE: Darwin doesn't do zones.
14287 * Behave as if zone always has destructive privs.
14288 */
14289
14290 state->dts_cred.dcr_action |=
14291 DTRACE_CRA_PROC_DESTRUCTIVE_CREDCHG;
14292 }
14293
14294 /*
14295 * Holding the dtrace_kernel privilege also implies that
14296 * the user has the dtrace_user privilege from a visibility
14297 * perspective. But without further privileges, some
14298 * destructive actions are not available.
14299 */
14300 if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_KERNEL, B_FALSE)) {
14301 /*
14302 * Make all probes in all zones visible. However,
14303 * this doesn't mean that all actions become available
14304 * to all zones.
14305 */
14306 state->dts_cred.dcr_visible |= DTRACE_CRV_KERNEL |
14307 DTRACE_CRV_ALLPROC | DTRACE_CRV_ALLZONE;
14308
14309 state->dts_cred.dcr_action |= DTRACE_CRA_KERNEL |
14310 DTRACE_CRA_PROC;
14311 /*
14312 * Holding proc_owner means that destructive actions
14313 * for *this* zone are allowed.
14314 */
14315 if (PRIV_POLICY_ONLY(cr, PRIV_PROC_OWNER, B_FALSE))
14316 state->dts_cred.dcr_action |=
14317 DTRACE_CRA_PROC_DESTRUCTIVE_ALLUSER;
14318
14319 /*
14320 * Holding proc_zone means that destructive actions
14321 * for this user/group ID in all zones is allowed.
14322 */
14323 if (PRIV_POLICY_ONLY(cr, PRIV_PROC_ZONE, B_FALSE))
14324 state->dts_cred.dcr_action |=
14325 DTRACE_CRA_PROC_DESTRUCTIVE_ALLZONE;
14326
14327 /*
14328 * If we have all privs in whatever zone this is,
14329 * we can do destructive things to processes which
14330 * have altered credentials.
14331 *
14332 * APPLE NOTE: Darwin doesn't do zones.
14333 * Behave as if zone always has destructive privs.
14334 */
14335 state->dts_cred.dcr_action |=
14336 DTRACE_CRA_PROC_DESTRUCTIVE_CREDCHG;
14337 }
14338
14339 /*
14340 * Holding the dtrace_proc privilege gives control over fasttrap
14341 * and pid providers. We need to grant wider destructive
14342 * privileges in the event that the user has proc_owner and/or
14343 * proc_zone.
14344 */
14345 if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_PROC, B_FALSE)) {
14346 if (PRIV_POLICY_ONLY(cr, PRIV_PROC_OWNER, B_FALSE))
14347 state->dts_cred.dcr_action |=
14348 DTRACE_CRA_PROC_DESTRUCTIVE_ALLUSER;
14349
14350 if (PRIV_POLICY_ONLY(cr, PRIV_PROC_ZONE, B_FALSE))
14351 state->dts_cred.dcr_action |=
14352 DTRACE_CRA_PROC_DESTRUCTIVE_ALLZONE;
14353 }
14354 }
14355 #endif
14356
14357 *new_state = state;
14358 return(0); /* Success */
14359 }
14360
14361 static int
dtrace_state_buffer(dtrace_state_t * state,dtrace_buffer_t * buf,int which)14362 dtrace_state_buffer(dtrace_state_t *state, dtrace_buffer_t *buf, int which)
14363 {
14364 dtrace_optval_t *opt = state->dts_options, size;
14365 processorid_t cpu = 0;
14366 size_t limit = buf->dtb_size;
14367 int flags = 0, rval;
14368
14369 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
14370 LCK_MTX_ASSERT(&cpu_lock, LCK_MTX_ASSERT_OWNED);
14371 ASSERT(which < DTRACEOPT_MAX);
14372 ASSERT(state->dts_activity == DTRACE_ACTIVITY_INACTIVE ||
14373 (state == dtrace_anon.dta_state &&
14374 state->dts_activity == DTRACE_ACTIVITY_ACTIVE));
14375
14376 if (opt[which] == DTRACEOPT_UNSET || opt[which] == 0)
14377 return (0);
14378
14379 if (opt[DTRACEOPT_CPU] != DTRACEOPT_UNSET)
14380 cpu = opt[DTRACEOPT_CPU];
14381
14382 if (which == DTRACEOPT_SPECSIZE)
14383 flags |= DTRACEBUF_NOSWITCH;
14384
14385 if (which == DTRACEOPT_BUFSIZE) {
14386 if (opt[DTRACEOPT_BUFPOLICY] == DTRACEOPT_BUFPOLICY_RING)
14387 flags |= DTRACEBUF_RING;
14388
14389 if (opt[DTRACEOPT_BUFPOLICY] == DTRACEOPT_BUFPOLICY_FILL)
14390 flags |= DTRACEBUF_FILL;
14391
14392 if (state != dtrace_anon.dta_state ||
14393 state->dts_activity != DTRACE_ACTIVITY_ACTIVE)
14394 flags |= DTRACEBUF_INACTIVE;
14395 }
14396
14397 for (size = opt[which]; (size_t)size >= sizeof (uint64_t); size >>= 1) {
14398 /*
14399 * The size must be 8-byte aligned. If the size is not 8-byte
14400 * aligned, drop it down by the difference.
14401 */
14402 if (size & (sizeof (uint64_t) - 1))
14403 size -= size & (sizeof (uint64_t) - 1);
14404
14405 if (size < state->dts_reserve) {
14406 /*
14407 * Buffers always must be large enough to accommodate
14408 * their prereserved space. We return E2BIG instead
14409 * of ENOMEM in this case to allow for user-level
14410 * software to differentiate the cases.
14411 */
14412 return (E2BIG);
14413 }
14414 limit = opt[DTRACEOPT_BUFLIMIT] * size / 100;
14415 rval = dtrace_buffer_alloc(buf, limit, size, flags, cpu);
14416
14417 if (rval != ENOMEM) {
14418 opt[which] = size;
14419 return (rval);
14420 }
14421
14422 if (opt[DTRACEOPT_BUFRESIZE] == DTRACEOPT_BUFRESIZE_MANUAL)
14423 return (rval);
14424 }
14425
14426 return (ENOMEM);
14427 }
14428
14429 static int
dtrace_state_buffers(dtrace_state_t * state)14430 dtrace_state_buffers(dtrace_state_t *state)
14431 {
14432 dtrace_speculation_t *spec = state->dts_speculations;
14433 int rval, i;
14434
14435 if ((rval = dtrace_state_buffer(state, state->dts_buffer,
14436 DTRACEOPT_BUFSIZE)) != 0)
14437 return (rval);
14438
14439 if ((rval = dtrace_state_buffer(state, state->dts_aggbuffer,
14440 DTRACEOPT_AGGSIZE)) != 0)
14441 return (rval);
14442
14443 for (i = 0; i < state->dts_nspeculations; i++) {
14444 if ((rval = dtrace_state_buffer(state,
14445 spec[i].dtsp_buffer, DTRACEOPT_SPECSIZE)) != 0)
14446 return (rval);
14447 }
14448
14449 return (0);
14450 }
14451
14452 static void
dtrace_state_prereserve(dtrace_state_t * state)14453 dtrace_state_prereserve(dtrace_state_t *state)
14454 {
14455 dtrace_ecb_t *ecb;
14456 dtrace_probe_t *probe;
14457
14458 state->dts_reserve = 0;
14459
14460 if (state->dts_options[DTRACEOPT_BUFPOLICY] != DTRACEOPT_BUFPOLICY_FILL)
14461 return;
14462
14463 /*
14464 * If our buffer policy is a "fill" buffer policy, we need to set the
14465 * prereserved space to be the space required by the END probes.
14466 */
14467 probe = dtrace_probes[dtrace_probeid_end - 1];
14468 ASSERT(probe != NULL);
14469
14470 for (ecb = probe->dtpr_ecb; ecb != NULL; ecb = ecb->dte_next) {
14471 if (ecb->dte_state != state)
14472 continue;
14473
14474 state->dts_reserve += ecb->dte_needed + ecb->dte_alignment;
14475 }
14476 }
14477
14478 static int
dtrace_state_go(dtrace_state_t * state,processorid_t * cpu)14479 dtrace_state_go(dtrace_state_t *state, processorid_t *cpu)
14480 {
14481 dtrace_optval_t *opt = state->dts_options, sz, nspec;
14482 dtrace_speculation_t *spec;
14483 dtrace_buffer_t *buf;
14484 cyc_handler_t hdlr;
14485 cyc_time_t when;
14486 int rval = 0, i, bufsize = (int)NCPU * sizeof (dtrace_buffer_t);
14487 dtrace_icookie_t cookie;
14488
14489 lck_mtx_lock(&cpu_lock);
14490 lck_mtx_lock(&dtrace_lock);
14491
14492 if (state->dts_activity != DTRACE_ACTIVITY_INACTIVE) {
14493 rval = EBUSY;
14494 goto out;
14495 }
14496
14497 /*
14498 * Before we can perform any checks, we must prime all of the
14499 * retained enablings that correspond to this state.
14500 */
14501 dtrace_enabling_prime(state);
14502
14503 if (state->dts_destructive && !state->dts_cred.dcr_destructive) {
14504 rval = EACCES;
14505 goto out;
14506 }
14507
14508 dtrace_state_prereserve(state);
14509
14510 /*
14511 * Now we want to do is try to allocate our speculations.
14512 * We do not automatically resize the number of speculations; if
14513 * this fails, we will fail the operation.
14514 */
14515 nspec = opt[DTRACEOPT_NSPEC];
14516 ASSERT(nspec != DTRACEOPT_UNSET);
14517
14518 if (nspec > INT_MAX) {
14519 rval = ENOMEM;
14520 goto out;
14521 }
14522
14523 spec = kmem_zalloc(nspec * sizeof (dtrace_speculation_t), KM_NOSLEEP);
14524
14525 if (spec == NULL) {
14526 rval = ENOMEM;
14527 goto out;
14528 }
14529
14530 state->dts_speculations = spec;
14531 state->dts_nspeculations = (int)nspec;
14532
14533 for (i = 0; i < nspec; i++) {
14534 if ((buf = kmem_zalloc(bufsize, KM_NOSLEEP)) == NULL) {
14535 rval = ENOMEM;
14536 goto err;
14537 }
14538
14539 spec[i].dtsp_buffer = buf;
14540 }
14541
14542 if (opt[DTRACEOPT_GRABANON] != DTRACEOPT_UNSET) {
14543 if (dtrace_anon.dta_state == NULL) {
14544 rval = ENOENT;
14545 goto out;
14546 }
14547
14548 if (state->dts_necbs != 0) {
14549 rval = EALREADY;
14550 goto out;
14551 }
14552
14553 state->dts_anon = dtrace_anon_grab();
14554 ASSERT(state->dts_anon != NULL);
14555 state = state->dts_anon;
14556
14557 /*
14558 * We want "grabanon" to be set in the grabbed state, so we'll
14559 * copy that option value from the grabbing state into the
14560 * grabbed state.
14561 */
14562 state->dts_options[DTRACEOPT_GRABANON] =
14563 opt[DTRACEOPT_GRABANON];
14564
14565 *cpu = dtrace_anon.dta_beganon;
14566
14567 /*
14568 * If the anonymous state is active (as it almost certainly
14569 * is if the anonymous enabling ultimately matched anything),
14570 * we don't allow any further option processing -- but we
14571 * don't return failure.
14572 */
14573 if (state->dts_activity != DTRACE_ACTIVITY_INACTIVE)
14574 goto out;
14575 }
14576
14577 if (opt[DTRACEOPT_AGGSIZE] != DTRACEOPT_UNSET &&
14578 opt[DTRACEOPT_AGGSIZE] != 0) {
14579 if (state->dts_aggregations == NULL) {
14580 /*
14581 * We're not going to create an aggregation buffer
14582 * because we don't have any ECBs that contain
14583 * aggregations -- set this option to 0.
14584 */
14585 opt[DTRACEOPT_AGGSIZE] = 0;
14586 } else {
14587 /*
14588 * If we have an aggregation buffer, we must also have
14589 * a buffer to use as scratch.
14590 */
14591 if (opt[DTRACEOPT_BUFSIZE] == DTRACEOPT_UNSET ||
14592 (size_t)opt[DTRACEOPT_BUFSIZE] < state->dts_needed) {
14593 opt[DTRACEOPT_BUFSIZE] = state->dts_needed;
14594 }
14595 }
14596 }
14597
14598 if (opt[DTRACEOPT_SPECSIZE] != DTRACEOPT_UNSET &&
14599 opt[DTRACEOPT_SPECSIZE] != 0) {
14600 if (!state->dts_speculates) {
14601 /*
14602 * We're not going to create speculation buffers
14603 * because we don't have any ECBs that actually
14604 * speculate -- set the speculation size to 0.
14605 */
14606 opt[DTRACEOPT_SPECSIZE] = 0;
14607 }
14608 }
14609
14610 /*
14611 * The bare minimum size for any buffer that we're actually going to
14612 * do anything to is sizeof (uint64_t).
14613 */
14614 sz = sizeof (uint64_t);
14615
14616 if ((state->dts_needed != 0 && opt[DTRACEOPT_BUFSIZE] < sz) ||
14617 (state->dts_speculates && opt[DTRACEOPT_SPECSIZE] < sz) ||
14618 (state->dts_aggregations != NULL && opt[DTRACEOPT_AGGSIZE] < sz)) {
14619 /*
14620 * A buffer size has been explicitly set to 0 (or to a size
14621 * that will be adjusted to 0) and we need the space -- we
14622 * need to return failure. We return ENOSPC to differentiate
14623 * it from failing to allocate a buffer due to failure to meet
14624 * the reserve (for which we return E2BIG).
14625 */
14626 rval = ENOSPC;
14627 goto out;
14628 }
14629
14630 if ((rval = dtrace_state_buffers(state)) != 0)
14631 goto err;
14632
14633 if ((sz = opt[DTRACEOPT_DYNVARSIZE]) == DTRACEOPT_UNSET)
14634 sz = dtrace_dstate_defsize;
14635
14636 do {
14637 rval = dtrace_dstate_init(&state->dts_vstate.dtvs_dynvars, sz);
14638
14639 if (rval == 0)
14640 break;
14641
14642 if (opt[DTRACEOPT_BUFRESIZE] == DTRACEOPT_BUFRESIZE_MANUAL)
14643 goto err;
14644 } while (sz >>= 1);
14645
14646 opt[DTRACEOPT_DYNVARSIZE] = sz;
14647
14648 if (rval != 0)
14649 goto err;
14650
14651 if (opt[DTRACEOPT_STATUSRATE] > dtrace_statusrate_max)
14652 opt[DTRACEOPT_STATUSRATE] = dtrace_statusrate_max;
14653
14654 if (opt[DTRACEOPT_CLEANRATE] == 0)
14655 opt[DTRACEOPT_CLEANRATE] = dtrace_cleanrate_max;
14656
14657 if (opt[DTRACEOPT_CLEANRATE] < dtrace_cleanrate_min)
14658 opt[DTRACEOPT_CLEANRATE] = dtrace_cleanrate_min;
14659
14660 if (opt[DTRACEOPT_CLEANRATE] > dtrace_cleanrate_max)
14661 opt[DTRACEOPT_CLEANRATE] = dtrace_cleanrate_max;
14662
14663 if (opt[DTRACEOPT_STRSIZE] > dtrace_strsize_max)
14664 opt[DTRACEOPT_STRSIZE] = dtrace_strsize_max;
14665
14666 if (opt[DTRACEOPT_STRSIZE] < dtrace_strsize_min)
14667 opt[DTRACEOPT_STRSIZE] = dtrace_strsize_min;
14668
14669 if (opt[DTRACEOPT_BUFLIMIT] > dtrace_buflimit_max)
14670 opt[DTRACEOPT_BUFLIMIT] = dtrace_buflimit_max;
14671
14672 if (opt[DTRACEOPT_BUFLIMIT] < dtrace_buflimit_min)
14673 opt[DTRACEOPT_BUFLIMIT] = dtrace_buflimit_min;
14674
14675 hdlr.cyh_func = (cyc_func_t)dtrace_state_clean;
14676 hdlr.cyh_arg = state;
14677 hdlr.cyh_level = CY_LOW_LEVEL;
14678
14679 when.cyt_when = 0;
14680 when.cyt_interval = opt[DTRACEOPT_CLEANRATE];
14681
14682 state->dts_cleaner = cyclic_add(&hdlr, &when);
14683
14684 hdlr.cyh_func = (cyc_func_t)dtrace_state_deadman;
14685 hdlr.cyh_arg = state;
14686 hdlr.cyh_level = CY_LOW_LEVEL;
14687
14688 when.cyt_when = 0;
14689 when.cyt_interval = dtrace_deadman_interval;
14690
14691 state->dts_alive = state->dts_laststatus = dtrace_gethrtime();
14692 state->dts_deadman = cyclic_add(&hdlr, &when);
14693
14694 state->dts_activity = DTRACE_ACTIVITY_WARMUP;
14695
14696 /*
14697 * Now it's time to actually fire the BEGIN probe. We need to disable
14698 * interrupts here both to record the CPU on which we fired the BEGIN
14699 * probe (the data from this CPU will be processed first at user
14700 * level) and to manually activate the buffer for this CPU.
14701 */
14702 cookie = dtrace_interrupt_disable();
14703 *cpu = CPU->cpu_id;
14704 ASSERT(state->dts_buffer[*cpu].dtb_flags & DTRACEBUF_INACTIVE);
14705 state->dts_buffer[*cpu].dtb_flags &= ~DTRACEBUF_INACTIVE;
14706
14707 dtrace_probe(dtrace_probeid_begin,
14708 (uint64_t)(uintptr_t)state, 0, 0, 0, 0);
14709 dtrace_interrupt_enable(cookie);
14710 /*
14711 * We may have had an exit action from a BEGIN probe; only change our
14712 * state to ACTIVE if we're still in WARMUP.
14713 */
14714 ASSERT(state->dts_activity == DTRACE_ACTIVITY_WARMUP ||
14715 state->dts_activity == DTRACE_ACTIVITY_DRAINING);
14716
14717 if (state->dts_activity == DTRACE_ACTIVITY_WARMUP)
14718 state->dts_activity = DTRACE_ACTIVITY_ACTIVE;
14719
14720 /*
14721 * Regardless of whether or not now we're in ACTIVE or DRAINING, we
14722 * want each CPU to transition its principal buffer out of the
14723 * INACTIVE state. Doing this assures that no CPU will suddenly begin
14724 * processing an ECB halfway down a probe's ECB chain; all CPUs will
14725 * atomically transition from processing none of a state's ECBs to
14726 * processing all of them.
14727 */
14728 dtrace_xcall(DTRACE_CPUALL,
14729 (dtrace_xcall_t)dtrace_buffer_activate, state);
14730 goto out;
14731
14732 err:
14733 dtrace_buffer_free(state->dts_buffer);
14734 dtrace_buffer_free(state->dts_aggbuffer);
14735
14736 if ((nspec = state->dts_nspeculations) == 0) {
14737 ASSERT(state->dts_speculations == NULL);
14738 goto out;
14739 }
14740
14741 spec = state->dts_speculations;
14742 ASSERT(spec != NULL);
14743
14744 for (i = 0; i < state->dts_nspeculations; i++) {
14745 if ((buf = spec[i].dtsp_buffer) == NULL)
14746 break;
14747
14748 dtrace_buffer_free(buf);
14749 kmem_free(buf, bufsize);
14750 }
14751
14752 kmem_free(spec, nspec * sizeof (dtrace_speculation_t));
14753 state->dts_nspeculations = 0;
14754 state->dts_speculations = NULL;
14755
14756 out:
14757 lck_mtx_unlock(&dtrace_lock);
14758 lck_mtx_unlock(&cpu_lock);
14759
14760 return (rval);
14761 }
14762
14763 static int
dtrace_state_stop(dtrace_state_t * state,processorid_t * cpu)14764 dtrace_state_stop(dtrace_state_t *state, processorid_t *cpu)
14765 {
14766 dtrace_icookie_t cookie;
14767
14768 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
14769
14770 if (state->dts_activity != DTRACE_ACTIVITY_ACTIVE &&
14771 state->dts_activity != DTRACE_ACTIVITY_DRAINING)
14772 return (EINVAL);
14773
14774 /*
14775 * We'll set the activity to DTRACE_ACTIVITY_DRAINING, and issue a sync
14776 * to be sure that every CPU has seen it. See below for the details
14777 * on why this is done.
14778 */
14779 state->dts_activity = DTRACE_ACTIVITY_DRAINING;
14780 dtrace_sync();
14781
14782 /*
14783 * By this point, it is impossible for any CPU to be still processing
14784 * with DTRACE_ACTIVITY_ACTIVE. We can thus set our activity to
14785 * DTRACE_ACTIVITY_COOLDOWN and know that we're not racing with any
14786 * other CPU in dtrace_buffer_reserve(). This allows dtrace_probe()
14787 * and callees to know that the activity is DTRACE_ACTIVITY_COOLDOWN
14788 * iff we're in the END probe.
14789 */
14790 state->dts_activity = DTRACE_ACTIVITY_COOLDOWN;
14791 dtrace_sync();
14792 ASSERT(state->dts_activity == DTRACE_ACTIVITY_COOLDOWN);
14793
14794 /*
14795 * Finally, we can release the reserve and call the END probe. We
14796 * disable interrupts across calling the END probe to allow us to
14797 * return the CPU on which we actually called the END probe. This
14798 * allows user-land to be sure that this CPU's principal buffer is
14799 * processed last.
14800 */
14801 state->dts_reserve = 0;
14802
14803 cookie = dtrace_interrupt_disable();
14804 *cpu = CPU->cpu_id;
14805 dtrace_probe(dtrace_probeid_end,
14806 (uint64_t)(uintptr_t)state, 0, 0, 0, 0);
14807 dtrace_interrupt_enable(cookie);
14808
14809 state->dts_activity = DTRACE_ACTIVITY_STOPPED;
14810 dtrace_sync();
14811
14812 return (0);
14813 }
14814
14815 static int
dtrace_state_option(dtrace_state_t * state,dtrace_optid_t option,dtrace_optval_t val)14816 dtrace_state_option(dtrace_state_t *state, dtrace_optid_t option,
14817 dtrace_optval_t val)
14818 {
14819 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
14820
14821 if (state->dts_activity != DTRACE_ACTIVITY_INACTIVE)
14822 return (EBUSY);
14823
14824 if (option >= DTRACEOPT_MAX)
14825 return (EINVAL);
14826
14827 if (option != DTRACEOPT_CPU && val < 0)
14828 return (EINVAL);
14829
14830 switch (option) {
14831 case DTRACEOPT_DESTRUCTIVE:
14832 if (dtrace_destructive_disallow)
14833 return (EACCES);
14834
14835 state->dts_cred.dcr_destructive = 1;
14836 break;
14837
14838 case DTRACEOPT_BUFSIZE:
14839 case DTRACEOPT_DYNVARSIZE:
14840 case DTRACEOPT_AGGSIZE:
14841 case DTRACEOPT_SPECSIZE:
14842 case DTRACEOPT_STRSIZE:
14843 if (val < 0)
14844 return (EINVAL);
14845
14846 if (val >= LONG_MAX) {
14847 /*
14848 * If this is an otherwise negative value, set it to
14849 * the highest multiple of 128m less than LONG_MAX.
14850 * Technically, we're adjusting the size without
14851 * regard to the buffer resizing policy, but in fact,
14852 * this has no effect -- if we set the buffer size to
14853 * ~LONG_MAX and the buffer policy is ultimately set to
14854 * be "manual", the buffer allocation is guaranteed to
14855 * fail, if only because the allocation requires two
14856 * buffers. (We set the the size to the highest
14857 * multiple of 128m because it ensures that the size
14858 * will remain a multiple of a megabyte when
14859 * repeatedly halved -- all the way down to 15m.)
14860 */
14861 val = LONG_MAX - (1 << 27) + 1;
14862 }
14863 }
14864
14865 state->dts_options[option] = val;
14866
14867 return (0);
14868 }
14869
14870 static void
dtrace_state_destroy(dtrace_state_t * state)14871 dtrace_state_destroy(dtrace_state_t *state)
14872 {
14873 dtrace_ecb_t *ecb;
14874 dtrace_vstate_t *vstate = &state->dts_vstate;
14875 minor_t minor = getminor(state->dts_dev);
14876 int i, bufsize = (int)NCPU * sizeof (dtrace_buffer_t);
14877 dtrace_speculation_t *spec = state->dts_speculations;
14878 int nspec = state->dts_nspeculations;
14879 uint32_t match;
14880
14881 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
14882 LCK_MTX_ASSERT(&cpu_lock, LCK_MTX_ASSERT_OWNED);
14883
14884 /*
14885 * First, retract any retained enablings for this state.
14886 */
14887 dtrace_enabling_retract(state);
14888 ASSERT(state->dts_nretained == 0);
14889
14890 if (state->dts_activity == DTRACE_ACTIVITY_ACTIVE ||
14891 state->dts_activity == DTRACE_ACTIVITY_DRAINING) {
14892 /*
14893 * We have managed to come into dtrace_state_destroy() on a
14894 * hot enabling -- almost certainly because of a disorderly
14895 * shutdown of a consumer. (That is, a consumer that is
14896 * exiting without having called dtrace_stop().) In this case,
14897 * we're going to set our activity to be KILLED, and then
14898 * issue a sync to be sure that everyone is out of probe
14899 * context before we start blowing away ECBs.
14900 */
14901 state->dts_activity = DTRACE_ACTIVITY_KILLED;
14902 dtrace_sync();
14903 }
14904
14905 /*
14906 * Release the credential hold we took in dtrace_state_create().
14907 */
14908 if (state->dts_cred.dcr_cred != NULL)
14909 kauth_cred_unref(&state->dts_cred.dcr_cred);
14910
14911 /*
14912 * Now we can safely disable and destroy any enabled probes. Because
14913 * any DTRACE_PRIV_KERNEL probes may actually be slowing our progress
14914 * (especially if they're all enabled), we take two passes through the
14915 * ECBs: in the first, we disable just DTRACE_PRIV_KERNEL probes, and
14916 * in the second we disable whatever is left over.
14917 */
14918 for (match = DTRACE_PRIV_KERNEL; ; match = 0) {
14919 for (i = 0; i < state->dts_necbs; i++) {
14920 if ((ecb = state->dts_ecbs[i]) == NULL)
14921 continue;
14922
14923 if (match && ecb->dte_probe != NULL) {
14924 dtrace_probe_t *probe = ecb->dte_probe;
14925 dtrace_provider_t *prov = probe->dtpr_provider;
14926
14927 if (!(prov->dtpv_priv.dtpp_flags & match))
14928 continue;
14929 }
14930
14931 dtrace_ecb_disable(ecb);
14932 dtrace_ecb_destroy(ecb);
14933 }
14934
14935 if (!match)
14936 break;
14937 }
14938
14939 /*
14940 * Before we free the buffers, perform one more sync to assure that
14941 * every CPU is out of probe context.
14942 */
14943 dtrace_sync();
14944
14945 dtrace_buffer_free(state->dts_buffer);
14946 dtrace_buffer_free(state->dts_aggbuffer);
14947
14948 for (i = 0; i < (int)NCPU; i++) {
14949 kmem_free(state->dts_rstate[i], 2 * sizeof(uint64_t));
14950 }
14951 kmem_free(state->dts_rstate, NCPU * sizeof(uint64_t*));
14952
14953 for (i = 0; i < nspec; i++)
14954 dtrace_buffer_free(spec[i].dtsp_buffer);
14955
14956 if (state->dts_cleaner != CYCLIC_NONE)
14957 cyclic_remove(state->dts_cleaner);
14958
14959 if (state->dts_deadman != CYCLIC_NONE)
14960 cyclic_remove(state->dts_deadman);
14961
14962 dtrace_dstate_fini(&vstate->dtvs_dynvars);
14963 dtrace_vstate_fini(vstate);
14964 kmem_free(state->dts_ecbs, state->dts_necbs * sizeof (dtrace_ecb_t *));
14965
14966 if (state->dts_aggregations != NULL) {
14967 #if DEBUG
14968 for (i = 0; i < state->dts_naggregations; i++)
14969 ASSERT(state->dts_aggregations[i] == NULL);
14970 #endif
14971 ASSERT(state->dts_naggregations > 0);
14972 kmem_free(state->dts_aggregations,
14973 state->dts_naggregations * sizeof (dtrace_aggregation_t *));
14974 }
14975
14976 kmem_free(state->dts_buffer, bufsize);
14977 kmem_free(state->dts_aggbuffer, bufsize);
14978
14979 for (i = 0; i < nspec; i++)
14980 kmem_free(spec[i].dtsp_buffer, bufsize);
14981
14982 kmem_free(spec, nspec * sizeof (dtrace_speculation_t));
14983
14984 dtrace_format_destroy(state);
14985
14986 vmem_destroy(state->dts_aggid_arena);
14987 dtrace_state_free(minor);
14988 }
14989
14990 /*
14991 * DTrace Anonymous Enabling Functions
14992 */
14993
14994 int
dtrace_keep_kernel_symbols(void)14995 dtrace_keep_kernel_symbols(void)
14996 {
14997 if (dtrace_is_restricted() && !dtrace_are_restrictions_relaxed()) {
14998 return 0;
14999 }
15000
15001 if (dtrace_kernel_symbol_mode == DTRACE_KERNEL_SYMBOLS_ALWAYS_FROM_KERNEL)
15002 return 1;
15003
15004 return 0;
15005 }
15006
15007 static dtrace_state_t *
dtrace_anon_grab(void)15008 dtrace_anon_grab(void)
15009 {
15010 dtrace_state_t *state;
15011
15012 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
15013
15014 if ((state = dtrace_anon.dta_state) == NULL) {
15015 ASSERT(dtrace_anon.dta_enabling == NULL);
15016 return (NULL);
15017 }
15018
15019 ASSERT(dtrace_anon.dta_enabling != NULL);
15020 ASSERT(dtrace_retained != NULL);
15021
15022 dtrace_enabling_destroy(dtrace_anon.dta_enabling);
15023 dtrace_anon.dta_enabling = NULL;
15024 dtrace_anon.dta_state = NULL;
15025
15026 return (state);
15027 }
15028
15029 static void
dtrace_anon_property(void)15030 dtrace_anon_property(void)
15031 {
15032 int i, rv;
15033 dtrace_state_t *state;
15034 dof_hdr_t *dof;
15035 char c[32]; /* enough for "dof-data-" + digits */
15036
15037 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
15038 LCK_MTX_ASSERT(&cpu_lock, LCK_MTX_ASSERT_OWNED);
15039
15040 for (i = 0; ; i++) {
15041 (void) snprintf(c, sizeof (c), "dof-data-%d", i);
15042
15043 dtrace_err_verbose = 1;
15044
15045 if ((dof = dtrace_dof_property(c)) == NULL) {
15046 dtrace_err_verbose = 0;
15047 break;
15048 }
15049
15050 #ifdef illumos
15051 /*
15052 * We want to create anonymous state, so we need to transition
15053 * the kernel debugger to indicate that DTrace is active. If
15054 * this fails (e.g. because the debugger has modified text in
15055 * some way), we won't continue with the processing.
15056 */
15057 if (kdi_dtrace_set(KDI_DTSET_DTRACE_ACTIVATE) != 0) {
15058 cmn_err(CE_NOTE, "kernel debugger active; anonymous "
15059 "enabling ignored.");
15060 dtrace_dof_destroy(dof);
15061 break;
15062 }
15063 #endif
15064
15065 /*
15066 * If we haven't allocated an anonymous state, we'll do so now.
15067 */
15068 if ((state = dtrace_anon.dta_state) == NULL) {
15069 rv = dtrace_state_create(NULL, NULL, &state);
15070 dtrace_anon.dta_state = state;
15071 if (rv != 0 || state == NULL) {
15072 /*
15073 * This basically shouldn't happen: the only
15074 * failure mode from dtrace_state_create() is a
15075 * failure of ddi_soft_state_zalloc() that
15076 * itself should never happen. Still, the
15077 * interface allows for a failure mode, and
15078 * we want to fail as gracefully as possible:
15079 * we'll emit an error message and cease
15080 * processing anonymous state in this case.
15081 */
15082 cmn_err(CE_WARN, "failed to create "
15083 "anonymous state");
15084 dtrace_dof_destroy(dof);
15085 break;
15086 }
15087 }
15088
15089 rv = dtrace_dof_slurp(dof, &state->dts_vstate, CRED(),
15090 &dtrace_anon.dta_enabling, 0, B_TRUE);
15091
15092 if (rv == 0)
15093 rv = dtrace_dof_options(dof, state);
15094
15095 dtrace_err_verbose = 0;
15096 dtrace_dof_destroy(dof);
15097
15098 if (rv != 0) {
15099 /*
15100 * This is malformed DOF; chuck any anonymous state
15101 * that we created.
15102 */
15103 ASSERT(dtrace_anon.dta_enabling == NULL);
15104 dtrace_state_destroy(state);
15105 dtrace_anon.dta_state = NULL;
15106 break;
15107 }
15108
15109 ASSERT(dtrace_anon.dta_enabling != NULL);
15110 }
15111
15112 if (dtrace_anon.dta_enabling != NULL) {
15113 int rval;
15114
15115 /*
15116 * dtrace_enabling_retain() can only fail because we are
15117 * trying to retain more enablings than are allowed -- but
15118 * we only have one anonymous enabling, and we are guaranteed
15119 * to be allowed at least one retained enabling; we assert
15120 * that dtrace_enabling_retain() returns success.
15121 */
15122 rval = dtrace_enabling_retain(dtrace_anon.dta_enabling);
15123 ASSERT(rval == 0);
15124
15125 dtrace_enabling_dump(dtrace_anon.dta_enabling);
15126 }
15127 }
15128
15129 /*
15130 * DTrace Helper Functions
15131 */
15132 static void
dtrace_helper_trace(dtrace_helper_action_t * helper,dtrace_mstate_t * mstate,dtrace_vstate_t * vstate,int where)15133 dtrace_helper_trace(dtrace_helper_action_t *helper,
15134 dtrace_mstate_t *mstate, dtrace_vstate_t *vstate, int where)
15135 {
15136 uint32_t size, next, nnext;
15137 int i;
15138 dtrace_helptrace_t *ent;
15139 uint16_t flags = cpu_core[CPU->cpu_id].cpuc_dtrace_flags;
15140
15141 if (!dtrace_helptrace_enabled)
15142 return;
15143
15144 ASSERT((uint32_t)vstate->dtvs_nlocals <= dtrace_helptrace_nlocals);
15145
15146 /*
15147 * What would a tracing framework be without its own tracing
15148 * framework? (Well, a hell of a lot simpler, for starters...)
15149 */
15150 size = sizeof (dtrace_helptrace_t) + dtrace_helptrace_nlocals *
15151 sizeof (uint64_t) - sizeof (uint64_t);
15152
15153 /*
15154 * Iterate until we can allocate a slot in the trace buffer.
15155 */
15156 do {
15157 next = dtrace_helptrace_next;
15158
15159 if (next + size < dtrace_helptrace_bufsize) {
15160 nnext = next + size;
15161 } else {
15162 nnext = size;
15163 }
15164 } while (dtrace_cas32(&dtrace_helptrace_next, next, nnext) != next);
15165
15166 /*
15167 * We have our slot; fill it in.
15168 */
15169 if (nnext == size)
15170 next = 0;
15171
15172 ent = (dtrace_helptrace_t *)&dtrace_helptrace_buffer[next];
15173 ent->dtht_helper = helper;
15174 ent->dtht_where = where;
15175 ent->dtht_nlocals = vstate->dtvs_nlocals;
15176
15177 ent->dtht_fltoffs = (mstate->dtms_present & DTRACE_MSTATE_FLTOFFS) ?
15178 mstate->dtms_fltoffs : -1;
15179 ent->dtht_fault = DTRACE_FLAGS2FLT(flags);
15180 ent->dtht_illval = cpu_core[CPU->cpu_id].cpuc_dtrace_illval;
15181
15182 for (i = 0; i < vstate->dtvs_nlocals; i++) {
15183 dtrace_statvar_t *svar;
15184
15185 if ((svar = vstate->dtvs_locals[i]) == NULL)
15186 continue;
15187
15188 ASSERT(svar->dtsv_size >= (int)NCPU * sizeof (uint64_t));
15189 ent->dtht_locals[i] =
15190 ((uint64_t *)(uintptr_t)svar->dtsv_data)[CPU->cpu_id];
15191 }
15192 }
15193
15194 __attribute__((noinline))
15195 static uint64_t
dtrace_helper(int which,dtrace_mstate_t * mstate,dtrace_state_t * state,uint64_t arg0,uint64_t arg1)15196 dtrace_helper(int which, dtrace_mstate_t *mstate,
15197 dtrace_state_t *state, uint64_t arg0, uint64_t arg1)
15198 {
15199 uint16_t *flags = &cpu_core[CPU->cpu_id].cpuc_dtrace_flags;
15200 uint64_t sarg0 = mstate->dtms_arg[0];
15201 uint64_t sarg1 = mstate->dtms_arg[1];
15202 uint64_t rval = 0;
15203 dtrace_helpers_t *helpers = curproc->p_dtrace_helpers;
15204 dtrace_helper_action_t *helper;
15205 dtrace_vstate_t *vstate;
15206 dtrace_difo_t *pred;
15207 int i, trace = dtrace_helptrace_enabled;
15208
15209 ASSERT(which >= 0 && which < DTRACE_NHELPER_ACTIONS);
15210
15211 if (helpers == NULL)
15212 return (0);
15213
15214 if ((helper = helpers->dthps_actions[which]) == NULL)
15215 return (0);
15216
15217 vstate = &helpers->dthps_vstate;
15218 mstate->dtms_arg[0] = arg0;
15219 mstate->dtms_arg[1] = arg1;
15220
15221 /*
15222 * Now iterate over each helper. If its predicate evaluates to 'true',
15223 * we'll call the corresponding actions. Note that the below calls
15224 * to dtrace_dif_emulate() may set faults in machine state. This is
15225 * okay: our caller (the outer dtrace_dif_emulate()) will simply plow
15226 * the stored DIF offset with its own (which is the desired behavior).
15227 * Also, note the calls to dtrace_dif_emulate() may allocate scratch
15228 * from machine state; this is okay, too.
15229 */
15230 for (; helper != NULL; helper = helper->dtha_next) {
15231 if ((pred = helper->dtha_predicate) != NULL) {
15232 if (trace)
15233 dtrace_helper_trace(helper, mstate, vstate, 0);
15234
15235 if (!dtrace_dif_emulate(pred, mstate, vstate, state))
15236 goto next;
15237
15238 if (*flags & CPU_DTRACE_FAULT)
15239 goto err;
15240 }
15241
15242 for (i = 0; i < helper->dtha_nactions; i++) {
15243 if (trace)
15244 dtrace_helper_trace(helper,
15245 mstate, vstate, i + 1);
15246
15247 rval = dtrace_dif_emulate(helper->dtha_actions[i],
15248 mstate, vstate, state);
15249
15250 if (*flags & CPU_DTRACE_FAULT)
15251 goto err;
15252 }
15253
15254 next:
15255 if (trace)
15256 dtrace_helper_trace(helper, mstate, vstate,
15257 DTRACE_HELPTRACE_NEXT);
15258 }
15259
15260 if (trace)
15261 dtrace_helper_trace(helper, mstate, vstate,
15262 DTRACE_HELPTRACE_DONE);
15263
15264 /*
15265 * Restore the arg0 that we saved upon entry.
15266 */
15267 mstate->dtms_arg[0] = sarg0;
15268 mstate->dtms_arg[1] = sarg1;
15269
15270 return (rval);
15271
15272 err:
15273 if (trace)
15274 dtrace_helper_trace(helper, mstate, vstate,
15275 DTRACE_HELPTRACE_ERR);
15276
15277 /*
15278 * Restore the arg0 that we saved upon entry.
15279 */
15280 mstate->dtms_arg[0] = sarg0;
15281 mstate->dtms_arg[1] = sarg1;
15282
15283 return (0);
15284 }
15285
15286 static void
dtrace_helper_action_destroy(dtrace_helper_action_t * helper,dtrace_vstate_t * vstate)15287 dtrace_helper_action_destroy(dtrace_helper_action_t *helper,
15288 dtrace_vstate_t *vstate)
15289 {
15290 int i;
15291
15292 if (helper->dtha_predicate != NULL)
15293 dtrace_difo_release(helper->dtha_predicate, vstate);
15294
15295 for (i = 0; i < helper->dtha_nactions; i++) {
15296 ASSERT(helper->dtha_actions[i] != NULL);
15297 dtrace_difo_release(helper->dtha_actions[i], vstate);
15298 }
15299
15300 kmem_free(helper->dtha_actions,
15301 helper->dtha_nactions * sizeof (dtrace_difo_t *));
15302 kmem_free(helper, sizeof (dtrace_helper_action_t));
15303 }
15304
15305 static int
dtrace_helper_destroygen(proc_t * p,int gen)15306 dtrace_helper_destroygen(proc_t* p, int gen)
15307 {
15308 dtrace_helpers_t *help = p->p_dtrace_helpers;
15309 dtrace_vstate_t *vstate;
15310 uint_t i;
15311
15312 LCK_MTX_ASSERT(&dtrace_meta_lock, LCK_MTX_ASSERT_OWNED);
15313 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
15314
15315 if (help == NULL || gen > help->dthps_generation)
15316 return (EINVAL);
15317
15318 vstate = &help->dthps_vstate;
15319
15320 for (i = 0; i < DTRACE_NHELPER_ACTIONS; i++) {
15321 dtrace_helper_action_t *last = NULL, *h, *next;
15322
15323 for (h = help->dthps_actions[i]; h != NULL; h = next) {
15324 next = h->dtha_next;
15325
15326 if (h->dtha_generation == gen) {
15327 if (last != NULL) {
15328 last->dtha_next = next;
15329 } else {
15330 help->dthps_actions[i] = next;
15331 }
15332
15333 dtrace_helper_action_destroy(h, vstate);
15334 } else {
15335 last = h;
15336 }
15337 }
15338 }
15339
15340 /*
15341 * Interate until we've cleared out all helper providers with the
15342 * given generation number.
15343 */
15344 for (;;) {
15345 dtrace_helper_provider_t *prov = NULL;
15346
15347 /*
15348 * Look for a helper provider with the right generation. We
15349 * have to start back at the beginning of the list each time
15350 * because we drop dtrace_lock. It's unlikely that we'll make
15351 * more than two passes.
15352 */
15353 for (i = 0; i < help->dthps_nprovs; i++) {
15354 prov = help->dthps_provs[i];
15355
15356 if (prov->dthp_generation == gen)
15357 break;
15358 }
15359
15360 /*
15361 * If there were no matches, we're done.
15362 */
15363 if (i == help->dthps_nprovs)
15364 break;
15365
15366 /*
15367 * Move the last helper provider into this slot.
15368 */
15369 help->dthps_nprovs--;
15370 help->dthps_provs[i] = help->dthps_provs[help->dthps_nprovs];
15371 help->dthps_provs[help->dthps_nprovs] = NULL;
15372
15373 lck_mtx_unlock(&dtrace_lock);
15374
15375 /*
15376 * If we have a meta provider, remove this helper provider.
15377 */
15378 if (dtrace_meta_pid != NULL) {
15379 ASSERT(dtrace_deferred_pid == NULL);
15380 dtrace_helper_provider_remove(&prov->dthp_prov,
15381 p);
15382 }
15383
15384 dtrace_helper_provider_destroy(prov);
15385
15386 lck_mtx_lock(&dtrace_lock);
15387 }
15388
15389 return (0);
15390 }
15391
15392 static int
dtrace_helper_validate(dtrace_helper_action_t * helper)15393 dtrace_helper_validate(dtrace_helper_action_t *helper)
15394 {
15395 int err = 0, i;
15396 dtrace_difo_t *dp;
15397
15398 if ((dp = helper->dtha_predicate) != NULL)
15399 err += dtrace_difo_validate_helper(dp);
15400
15401 for (i = 0; i < helper->dtha_nactions; i++)
15402 err += dtrace_difo_validate_helper(helper->dtha_actions[i]);
15403
15404 return (err == 0);
15405 }
15406
15407 static int
dtrace_helper_action_add(proc_t * p,int which,dtrace_ecbdesc_t * ep)15408 dtrace_helper_action_add(proc_t* p, int which, dtrace_ecbdesc_t *ep)
15409 {
15410 dtrace_helpers_t *help;
15411 dtrace_helper_action_t *helper, *last;
15412 dtrace_actdesc_t *act;
15413 dtrace_vstate_t *vstate;
15414 dtrace_predicate_t *pred;
15415 int count = 0, nactions = 0, i;
15416
15417 if (which < 0 || which >= DTRACE_NHELPER_ACTIONS)
15418 return (EINVAL);
15419
15420 help = p->p_dtrace_helpers;
15421 last = help->dthps_actions[which];
15422 vstate = &help->dthps_vstate;
15423
15424 for (count = 0; last != NULL; last = last->dtha_next) {
15425 count++;
15426 if (last->dtha_next == NULL)
15427 break;
15428 }
15429
15430 /*
15431 * If we already have dtrace_helper_actions_max helper actions for this
15432 * helper action type, we'll refuse to add a new one.
15433 */
15434 if (count >= dtrace_helper_actions_max)
15435 return (ENOSPC);
15436
15437 helper = kmem_zalloc(sizeof (dtrace_helper_action_t), KM_SLEEP);
15438 helper->dtha_generation = help->dthps_generation;
15439
15440 if ((pred = ep->dted_pred.dtpdd_predicate) != NULL) {
15441 ASSERT(pred->dtp_difo != NULL);
15442 dtrace_difo_hold(pred->dtp_difo);
15443 helper->dtha_predicate = pred->dtp_difo;
15444 }
15445
15446 for (act = ep->dted_action; act != NULL; act = act->dtad_next) {
15447 if (act->dtad_kind != DTRACEACT_DIFEXPR)
15448 goto err;
15449
15450 if (act->dtad_difo == NULL)
15451 goto err;
15452
15453 nactions++;
15454 }
15455
15456 helper->dtha_actions = kmem_zalloc(sizeof (dtrace_difo_t *) *
15457 (helper->dtha_nactions = nactions), KM_SLEEP);
15458
15459 for (act = ep->dted_action, i = 0; act != NULL; act = act->dtad_next) {
15460 dtrace_difo_hold(act->dtad_difo);
15461 helper->dtha_actions[i++] = act->dtad_difo;
15462 }
15463
15464 if (!dtrace_helper_validate(helper))
15465 goto err;
15466
15467 if (last == NULL) {
15468 help->dthps_actions[which] = helper;
15469 } else {
15470 last->dtha_next = helper;
15471 }
15472
15473 if ((uint32_t)vstate->dtvs_nlocals > dtrace_helptrace_nlocals) {
15474 dtrace_helptrace_nlocals = vstate->dtvs_nlocals;
15475 dtrace_helptrace_next = 0;
15476 }
15477
15478 return (0);
15479 err:
15480 dtrace_helper_action_destroy(helper, vstate);
15481 return (EINVAL);
15482 }
15483
15484 static void
dtrace_helper_provider_register(proc_t * p,dtrace_helpers_t * help,dof_helper_t * dofhp)15485 dtrace_helper_provider_register(proc_t *p, dtrace_helpers_t *help,
15486 dof_helper_t *dofhp)
15487 {
15488 LCK_MTX_ASSERT(&dtrace_meta_lock, LCK_MTX_ASSERT_OWNED);
15489 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_NOTOWNED);
15490
15491 lck_mtx_lock(&dtrace_lock);
15492
15493 if (!dtrace_attached() || dtrace_meta_pid == NULL) {
15494 /*
15495 * If the dtrace module is loaded but not attached, or if
15496 * there aren't isn't a meta provider registered to deal with
15497 * these provider descriptions, we need to postpone creating
15498 * the actual providers until later.
15499 */
15500
15501 if (help->dthps_next == NULL && help->dthps_prev == NULL &&
15502 dtrace_deferred_pid != help) {
15503 help->dthps_deferred = 1;
15504 help->dthps_pid = proc_getpid(p);
15505 help->dthps_next = dtrace_deferred_pid;
15506 help->dthps_prev = NULL;
15507 if (dtrace_deferred_pid != NULL)
15508 dtrace_deferred_pid->dthps_prev = help;
15509 dtrace_deferred_pid = help;
15510 }
15511
15512 lck_mtx_unlock(&dtrace_lock);
15513
15514 } else if (dofhp != NULL) {
15515 /*
15516 * If the dtrace module is loaded and we have a particular
15517 * helper provider description, pass that off to the
15518 * meta provider.
15519 */
15520
15521 lck_mtx_unlock(&dtrace_lock);
15522
15523 dtrace_helper_provide(dofhp, p);
15524
15525 } else {
15526 /*
15527 * Otherwise, just pass all the helper provider descriptions
15528 * off to the meta provider.
15529 */
15530
15531 uint_t i;
15532 lck_mtx_unlock(&dtrace_lock);
15533
15534 for (i = 0; i < help->dthps_nprovs; i++) {
15535 dtrace_helper_provide(&help->dthps_provs[i]->dthp_prov,
15536 p);
15537 }
15538 }
15539 }
15540
15541 static int
dtrace_helper_provider_add(proc_t * p,dof_helper_t * dofhp,int gen)15542 dtrace_helper_provider_add(proc_t* p, dof_helper_t *dofhp, int gen)
15543 {
15544 dtrace_helpers_t *help;
15545 dtrace_helper_provider_t *hprov, **tmp_provs;
15546 uint_t tmp_maxprovs, i;
15547
15548 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
15549 help = p->p_dtrace_helpers;
15550 ASSERT(help != NULL);
15551
15552 /*
15553 * If we already have dtrace_helper_providers_max helper providers,
15554 * we're refuse to add a new one.
15555 */
15556 if (help->dthps_nprovs >= dtrace_helper_providers_max)
15557 return (ENOSPC);
15558
15559 /*
15560 * Check to make sure this isn't a duplicate.
15561 */
15562 for (i = 0; i < help->dthps_nprovs; i++) {
15563 if (dofhp->dofhp_addr ==
15564 help->dthps_provs[i]->dthp_prov.dofhp_addr)
15565 return (EALREADY);
15566 }
15567
15568 hprov = kmem_zalloc(sizeof (dtrace_helper_provider_t), KM_SLEEP);
15569 hprov->dthp_prov = *dofhp;
15570 hprov->dthp_ref = 1;
15571 hprov->dthp_generation = gen;
15572
15573 /*
15574 * Allocate a bigger table for helper providers if it's already full.
15575 */
15576 if (help->dthps_maxprovs == help->dthps_nprovs) {
15577 tmp_maxprovs = help->dthps_maxprovs;
15578 tmp_provs = help->dthps_provs;
15579
15580 if (help->dthps_maxprovs == 0)
15581 help->dthps_maxprovs = 2;
15582 else
15583 help->dthps_maxprovs *= 2;
15584 if (help->dthps_maxprovs > dtrace_helper_providers_max)
15585 help->dthps_maxprovs = dtrace_helper_providers_max;
15586
15587 ASSERT(tmp_maxprovs < help->dthps_maxprovs);
15588
15589 help->dthps_provs = kmem_zalloc(help->dthps_maxprovs *
15590 sizeof (dtrace_helper_provider_t *), KM_SLEEP);
15591
15592 if (tmp_provs != NULL) {
15593 bcopy(tmp_provs, help->dthps_provs, tmp_maxprovs *
15594 sizeof (dtrace_helper_provider_t *));
15595 kmem_free(tmp_provs, tmp_maxprovs *
15596 sizeof (dtrace_helper_provider_t *));
15597 }
15598 }
15599
15600 help->dthps_provs[help->dthps_nprovs] = hprov;
15601 help->dthps_nprovs++;
15602
15603 return (0);
15604 }
15605
15606 static void
dtrace_helper_provider_destroy(dtrace_helper_provider_t * hprov)15607 dtrace_helper_provider_destroy(dtrace_helper_provider_t *hprov)
15608 {
15609 lck_mtx_lock(&dtrace_lock);
15610
15611 if (--hprov->dthp_ref == 0) {
15612 dof_hdr_t *dof;
15613 lck_mtx_unlock(&dtrace_lock);
15614 dof = (dof_hdr_t *)(uintptr_t)hprov->dthp_prov.dofhp_dof;
15615 dtrace_dof_destroy(dof);
15616 kmem_free(hprov, sizeof (dtrace_helper_provider_t));
15617 } else {
15618 lck_mtx_unlock(&dtrace_lock);
15619 }
15620 }
15621
15622 static int
dtrace_helper_provider_validate(dof_hdr_t * dof,dof_sec_t * sec)15623 dtrace_helper_provider_validate(dof_hdr_t *dof, dof_sec_t *sec)
15624 {
15625 uintptr_t daddr = (uintptr_t)dof;
15626 dof_sec_t *str_sec, *prb_sec, *arg_sec, *off_sec, *enoff_sec;
15627 dof_provider_t *provider;
15628 dof_probe_t *probe;
15629 uint8_t *arg;
15630 char *strtab, *typestr;
15631 dof_stridx_t typeidx;
15632 size_t typesz;
15633 uint_t nprobes, j, k;
15634
15635 ASSERT(sec->dofs_type == DOF_SECT_PROVIDER);
15636
15637 if (sec->dofs_offset & (sizeof (uint_t) - 1)) {
15638 dtrace_dof_error(dof, "misaligned section offset");
15639 return (-1);
15640 }
15641
15642 /*
15643 * The section needs to be large enough to contain the DOF provider
15644 * structure appropriate for the given version.
15645 */
15646 if (sec->dofs_size <
15647 ((dof->dofh_ident[DOF_ID_VERSION] == DOF_VERSION_1) ?
15648 offsetof(dof_provider_t, dofpv_prenoffs) :
15649 sizeof (dof_provider_t))) {
15650 dtrace_dof_error(dof, "provider section too small");
15651 return (-1);
15652 }
15653
15654 provider = (dof_provider_t *)(uintptr_t)(daddr + sec->dofs_offset);
15655 str_sec = dtrace_dof_sect(dof, DOF_SECT_STRTAB, provider->dofpv_strtab);
15656 prb_sec = dtrace_dof_sect(dof, DOF_SECT_PROBES, provider->dofpv_probes);
15657 arg_sec = dtrace_dof_sect(dof, DOF_SECT_PRARGS, provider->dofpv_prargs);
15658 off_sec = dtrace_dof_sect(dof, DOF_SECT_PROFFS, provider->dofpv_proffs);
15659
15660 if (str_sec == NULL || prb_sec == NULL ||
15661 arg_sec == NULL || off_sec == NULL)
15662 return (-1);
15663
15664 enoff_sec = NULL;
15665
15666 if (dof->dofh_ident[DOF_ID_VERSION] != DOF_VERSION_1 &&
15667 provider->dofpv_prenoffs != DOF_SECT_NONE &&
15668 (enoff_sec = dtrace_dof_sect(dof, DOF_SECT_PRENOFFS,
15669 provider->dofpv_prenoffs)) == NULL)
15670 return (-1);
15671
15672 strtab = (char *)(uintptr_t)(daddr + str_sec->dofs_offset);
15673
15674 if (provider->dofpv_name >= str_sec->dofs_size ||
15675 strlen(strtab + provider->dofpv_name) >= DTRACE_PROVNAMELEN) {
15676 dtrace_dof_error(dof, "invalid provider name");
15677 return (-1);
15678 }
15679
15680 if (prb_sec->dofs_entsize == 0 ||
15681 prb_sec->dofs_entsize > prb_sec->dofs_size) {
15682 dtrace_dof_error(dof, "invalid entry size");
15683 return (-1);
15684 }
15685
15686 if (prb_sec->dofs_entsize & (sizeof (uintptr_t) - 1)) {
15687 dtrace_dof_error(dof, "misaligned entry size");
15688 return (-1);
15689 }
15690
15691 if (off_sec->dofs_entsize != sizeof (uint32_t)) {
15692 dtrace_dof_error(dof, "invalid entry size");
15693 return (-1);
15694 }
15695
15696 if (off_sec->dofs_offset & (sizeof (uint32_t) - 1)) {
15697 dtrace_dof_error(dof, "misaligned section offset");
15698 return (-1);
15699 }
15700
15701 if (arg_sec->dofs_entsize != sizeof (uint8_t)) {
15702 dtrace_dof_error(dof, "invalid entry size");
15703 return (-1);
15704 }
15705
15706 arg = (uint8_t *)(uintptr_t)(daddr + arg_sec->dofs_offset);
15707
15708 nprobes = prb_sec->dofs_size / prb_sec->dofs_entsize;
15709
15710 /*
15711 * Take a pass through the probes to check for errors.
15712 */
15713 for (j = 0; j < nprobes; j++) {
15714 probe = (dof_probe_t *)(uintptr_t)(daddr +
15715 prb_sec->dofs_offset + j * prb_sec->dofs_entsize);
15716
15717 if (probe->dofpr_func >= str_sec->dofs_size) {
15718 dtrace_dof_error(dof, "invalid function name");
15719 return (-1);
15720 }
15721
15722 if (strlen(strtab + probe->dofpr_func) >= DTRACE_FUNCNAMELEN) {
15723 dtrace_dof_error(dof, "function name too long");
15724 return (-1);
15725 }
15726
15727 if (probe->dofpr_name >= str_sec->dofs_size ||
15728 strlen(strtab + probe->dofpr_name) >= DTRACE_NAMELEN) {
15729 dtrace_dof_error(dof, "invalid probe name");
15730 return (-1);
15731 }
15732
15733 /*
15734 * The offset count must not wrap the index, and the offsets
15735 * must also not overflow the section's data.
15736 */
15737 if (probe->dofpr_offidx + probe->dofpr_noffs <
15738 probe->dofpr_offidx ||
15739 (probe->dofpr_offidx + probe->dofpr_noffs) *
15740 off_sec->dofs_entsize > off_sec->dofs_size) {
15741 dtrace_dof_error(dof, "invalid probe offset");
15742 return (-1);
15743 }
15744
15745 if (dof->dofh_ident[DOF_ID_VERSION] != DOF_VERSION_1) {
15746 /*
15747 * If there's no is-enabled offset section, make sure
15748 * there aren't any is-enabled offsets. Otherwise
15749 * perform the same checks as for probe offsets
15750 * (immediately above).
15751 */
15752 if (enoff_sec == NULL) {
15753 if (probe->dofpr_enoffidx != 0 ||
15754 probe->dofpr_nenoffs != 0) {
15755 dtrace_dof_error(dof, "is-enabled "
15756 "offsets with null section");
15757 return (-1);
15758 }
15759 } else if (probe->dofpr_enoffidx +
15760 probe->dofpr_nenoffs < probe->dofpr_enoffidx ||
15761 (probe->dofpr_enoffidx + probe->dofpr_nenoffs) *
15762 enoff_sec->dofs_entsize > enoff_sec->dofs_size) {
15763 dtrace_dof_error(dof, "invalid is-enabled "
15764 "offset");
15765 return (-1);
15766 }
15767
15768 if (probe->dofpr_noffs + probe->dofpr_nenoffs == 0) {
15769 dtrace_dof_error(dof, "zero probe and "
15770 "is-enabled offsets");
15771 return (-1);
15772 }
15773 } else if (probe->dofpr_noffs == 0) {
15774 dtrace_dof_error(dof, "zero probe offsets");
15775 return (-1);
15776 }
15777
15778 if (probe->dofpr_argidx + probe->dofpr_xargc <
15779 probe->dofpr_argidx ||
15780 (probe->dofpr_argidx + probe->dofpr_xargc) *
15781 arg_sec->dofs_entsize > arg_sec->dofs_size) {
15782 dtrace_dof_error(dof, "invalid args");
15783 return (-1);
15784 }
15785
15786 typeidx = probe->dofpr_nargv;
15787 typestr = strtab + probe->dofpr_nargv;
15788 for (k = 0; k < probe->dofpr_nargc; k++) {
15789 if (typeidx >= str_sec->dofs_size) {
15790 dtrace_dof_error(dof, "bad "
15791 "native argument type");
15792 return (-1);
15793 }
15794
15795 typesz = strlen(typestr) + 1;
15796 if (typesz > DTRACE_ARGTYPELEN) {
15797 dtrace_dof_error(dof, "native "
15798 "argument type too long");
15799 return (-1);
15800 }
15801 typeidx += typesz;
15802 typestr += typesz;
15803 }
15804
15805 typeidx = probe->dofpr_xargv;
15806 typestr = strtab + probe->dofpr_xargv;
15807 for (k = 0; k < probe->dofpr_xargc; k++) {
15808 if (arg[probe->dofpr_argidx + k] > probe->dofpr_nargc) {
15809 dtrace_dof_error(dof, "bad "
15810 "native argument index");
15811 return (-1);
15812 }
15813
15814 if (typeidx >= str_sec->dofs_size) {
15815 dtrace_dof_error(dof, "bad "
15816 "translated argument type");
15817 return (-1);
15818 }
15819
15820 typesz = strlen(typestr) + 1;
15821 if (typesz > DTRACE_ARGTYPELEN) {
15822 dtrace_dof_error(dof, "translated argument "
15823 "type too long");
15824 return (-1);
15825 }
15826
15827 typeidx += typesz;
15828 typestr += typesz;
15829 }
15830 }
15831
15832 return (0);
15833 }
15834
15835 static int
dtrace_helper_slurp(proc_t * p,dof_hdr_t * dof,dof_helper_t * dhp)15836 dtrace_helper_slurp(proc_t* p, dof_hdr_t *dof, dof_helper_t *dhp)
15837 {
15838 dtrace_helpers_t *help;
15839 dtrace_vstate_t *vstate;
15840 dtrace_enabling_t *enab = NULL;
15841 int i, gen, rv, nhelpers = 0, nprovs = 0, destroy = 1;
15842 uintptr_t daddr = (uintptr_t)dof;
15843
15844 LCK_MTX_ASSERT(&dtrace_meta_lock, LCK_MTX_ASSERT_OWNED);
15845 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
15846
15847 if ((help = p->p_dtrace_helpers) == NULL)
15848 help = dtrace_helpers_create(p);
15849
15850 vstate = &help->dthps_vstate;
15851
15852 if ((rv = dtrace_dof_slurp(dof, vstate, NULL, &enab,
15853 dhp != NULL ? dhp->dofhp_addr : 0, B_FALSE)) != 0) {
15854 dtrace_dof_destroy(dof);
15855 return (rv);
15856 }
15857
15858 /*
15859 * Look for helper providers and validate their descriptions.
15860 */
15861 if (dhp != NULL) {
15862 for (i = 0; (uint32_t)i < dof->dofh_secnum; i++) {
15863 dof_sec_t *sec = (dof_sec_t *)(uintptr_t)(daddr +
15864 dof->dofh_secoff + i * dof->dofh_secsize);
15865
15866 if (sec->dofs_type != DOF_SECT_PROVIDER)
15867 continue;
15868
15869 if (dtrace_helper_provider_validate(dof, sec) != 0) {
15870 dtrace_enabling_destroy(enab);
15871 dtrace_dof_destroy(dof);
15872 return (-1);
15873 }
15874
15875 nprovs++;
15876 }
15877 }
15878
15879 /*
15880 * Now we need to walk through the ECB descriptions in the enabling.
15881 */
15882 for (i = 0; i < enab->dten_ndesc; i++) {
15883 dtrace_ecbdesc_t *ep = enab->dten_desc[i];
15884 dtrace_probedesc_t *desc = &ep->dted_probe;
15885
15886 /* APPLE NOTE: Darwin employs size bounded string operation. */
15887 if (!LIT_STRNEQL(desc->dtpd_provider, "dtrace"))
15888 continue;
15889
15890 if (!LIT_STRNEQL(desc->dtpd_mod, "helper"))
15891 continue;
15892
15893 if (!LIT_STRNEQL(desc->dtpd_func, "ustack"))
15894 continue;
15895
15896 if ((rv = dtrace_helper_action_add(p, DTRACE_HELPER_ACTION_USTACK,
15897 ep)) != 0) {
15898 /*
15899 * Adding this helper action failed -- we are now going
15900 * to rip out the entire generation and return failure.
15901 */
15902 (void) dtrace_helper_destroygen(p, help->dthps_generation);
15903 dtrace_enabling_destroy(enab);
15904 dtrace_dof_destroy(dof);
15905 return (-1);
15906 }
15907
15908 nhelpers++;
15909 }
15910
15911 if (nhelpers < enab->dten_ndesc)
15912 dtrace_dof_error(dof, "unmatched helpers");
15913
15914 gen = help->dthps_generation++;
15915 dtrace_enabling_destroy(enab);
15916
15917 if (dhp != NULL && nprovs > 0) {
15918 dhp->dofhp_dof = (uint64_t)(uintptr_t)dof;
15919 if (dtrace_helper_provider_add(p, dhp, gen) == 0) {
15920 lck_mtx_unlock(&dtrace_lock);
15921 dtrace_helper_provider_register(p, help, dhp);
15922 lck_mtx_lock(&dtrace_lock);
15923
15924 destroy = 0;
15925 }
15926 }
15927
15928 if (destroy)
15929 dtrace_dof_destroy(dof);
15930
15931 return (gen);
15932 }
15933
15934 /*
15935 * APPLE NOTE: DTrace lazy dof implementation
15936 *
15937 * DTrace user static probes (USDT probes) and helper actions are loaded
15938 * in a process by proccessing dof sections. The dof sections are passed
15939 * into the kernel by dyld, in a dof_ioctl_data_t block. It is rather
15940 * expensive to process dof for a process that will never use it. There
15941 * is a memory cost (allocating the providers/probes), and a cpu cost
15942 * (creating the providers/probes).
15943 *
15944 * To reduce this cost, we use "lazy dof". The normal proceedure for
15945 * dof processing is to copyin the dof(s) pointed to by the dof_ioctl_data_t
15946 * block, and invoke dof_slurp_helper() on them. When "lazy dof" is
15947 * used, each process retains the dof_ioctl_data_t block, instead of
15948 * copying in the data it points to.
15949 *
15950 * The dof_ioctl_data_t blocks are managed as if they were the actual
15951 * processed dof; on fork the block is copied to the child, on exec and
15952 * exit the block is freed.
15953 *
15954 * If the process loads library(s) containing additional dof, the
15955 * new dof_ioctl_data_t is merged with the existing block.
15956 *
15957 * There are a few catches that make this slightly more difficult.
15958 * When dyld registers dof_ioctl_data_t blocks, it expects a unique
15959 * identifier value for each dof in the block. In non-lazy dof terms,
15960 * this is the generation that dof was loaded in. If we hand back
15961 * a UID for a lazy dof, that same UID must be able to unload the
15962 * dof once it has become non-lazy. To meet this requirement, the
15963 * code that loads lazy dof requires that the UID's for dof(s) in
15964 * the lazy dof be sorted, and in ascending order. It is okay to skip
15965 * UID's, I.E., 1 -> 5 -> 6 is legal.
15966 *
15967 * Once a process has become non-lazy, it will stay non-lazy. All
15968 * future dof operations for that process will be non-lazy, even
15969 * if the dof mode transitions back to lazy.
15970 *
15971 * Always do lazy dof checks before non-lazy (I.E. In fork, exit, exec.).
15972 * That way if the lazy check fails due to transitioning to non-lazy, the
15973 * right thing is done with the newly faulted in dof.
15974 */
15975
15976 /*
15977 * This method is a bit squicky. It must handle:
15978 *
15979 * dof should not be lazy.
15980 * dof should have been handled lazily, but there was an error
15981 * dof was handled lazily, and needs to be freed.
15982 * dof was handled lazily, and must not be freed.
15983 *
15984 *
15985 * Returns EACCESS if dof should be handled non-lazily.
15986 *
15987 * KERN_SUCCESS and all other return codes indicate lazy handling of dof.
15988 *
15989 * If the dofs data is claimed by this method, dofs_claimed will be set.
15990 * Callers should not free claimed dofs.
15991 */
15992 static int
dtrace_lazy_dofs_add(proc_t * p,dof_ioctl_data_t * incoming_dofs,int * dofs_claimed)15993 dtrace_lazy_dofs_add(proc_t *p, dof_ioctl_data_t* incoming_dofs, int *dofs_claimed)
15994 {
15995 ASSERT(p);
15996 ASSERT(incoming_dofs && incoming_dofs->dofiod_count > 0);
15997
15998 int rval = 0;
15999 *dofs_claimed = 0;
16000
16001 lck_rw_lock_shared(&dtrace_dof_mode_lock);
16002
16003 ASSERT(p->p_dtrace_lazy_dofs == NULL || p->p_dtrace_helpers == NULL);
16004 ASSERT(dtrace_dof_mode != DTRACE_DOF_MODE_NEVER);
16005
16006 /*
16007 * Any existing helpers force non-lazy behavior.
16008 */
16009 if (dtrace_dof_mode == DTRACE_DOF_MODE_LAZY_ON && (p->p_dtrace_helpers == NULL)) {
16010 dtrace_sprlock(p);
16011
16012 dof_ioctl_data_t* existing_dofs = p->p_dtrace_lazy_dofs;
16013 unsigned int existing_dofs_count = (existing_dofs) ? existing_dofs->dofiod_count : 0;
16014 unsigned int i, merged_dofs_count = incoming_dofs->dofiod_count + existing_dofs_count;
16015
16016 /*
16017 * Range check...
16018 */
16019 if (merged_dofs_count == 0 || merged_dofs_count > 1024) {
16020 dtrace_dof_error(NULL, "lazy_dofs_add merged_dofs_count out of range");
16021 rval = EINVAL;
16022 goto unlock;
16023 }
16024
16025 /*
16026 * Each dof being added must be assigned a unique generation.
16027 */
16028 uint64_t generation = (existing_dofs) ? existing_dofs->dofiod_helpers[existing_dofs_count - 1].dofhp_dof + 1 : 1;
16029 for (i=0; i<incoming_dofs->dofiod_count; i++) {
16030 /*
16031 * We rely on these being the same so we can overwrite dofhp_dof and not lose info.
16032 */
16033 ASSERT(incoming_dofs->dofiod_helpers[i].dofhp_dof == incoming_dofs->dofiod_helpers[i].dofhp_addr);
16034 incoming_dofs->dofiod_helpers[i].dofhp_dof = generation++;
16035 }
16036
16037
16038 if (existing_dofs) {
16039 /*
16040 * Merge the existing and incoming dofs
16041 */
16042 size_t merged_dofs_size = DOF_IOCTL_DATA_T_SIZE(merged_dofs_count);
16043 dof_ioctl_data_t* merged_dofs = kmem_alloc(merged_dofs_size, KM_SLEEP);
16044
16045 bcopy(&existing_dofs->dofiod_helpers[0],
16046 &merged_dofs->dofiod_helpers[0],
16047 sizeof(dof_helper_t) * existing_dofs_count);
16048 bcopy(&incoming_dofs->dofiod_helpers[0],
16049 &merged_dofs->dofiod_helpers[existing_dofs_count],
16050 sizeof(dof_helper_t) * incoming_dofs->dofiod_count);
16051
16052 merged_dofs->dofiod_count = merged_dofs_count;
16053
16054 kmem_free(existing_dofs, DOF_IOCTL_DATA_T_SIZE(existing_dofs_count));
16055
16056 p->p_dtrace_lazy_dofs = merged_dofs;
16057 } else {
16058 /*
16059 * Claim the incoming dofs
16060 */
16061 *dofs_claimed = 1;
16062 p->p_dtrace_lazy_dofs = incoming_dofs;
16063 }
16064
16065 #if DEBUG
16066 dof_ioctl_data_t* all_dofs = p->p_dtrace_lazy_dofs;
16067 for (i=0; i<all_dofs->dofiod_count-1; i++) {
16068 ASSERT(all_dofs->dofiod_helpers[i].dofhp_dof < all_dofs->dofiod_helpers[i+1].dofhp_dof);
16069 }
16070 #endif /* DEBUG */
16071
16072 unlock:
16073 dtrace_sprunlock(p);
16074 } else {
16075 rval = EACCES;
16076 }
16077
16078 lck_rw_unlock_shared(&dtrace_dof_mode_lock);
16079
16080 return rval;
16081 }
16082
16083 /*
16084 * Returns:
16085 *
16086 * EINVAL: lazy dof is enabled, but the requested generation was not found.
16087 * EACCES: This removal needs to be handled non-lazily.
16088 */
16089 static int
dtrace_lazy_dofs_remove(proc_t * p,int generation)16090 dtrace_lazy_dofs_remove(proc_t *p, int generation)
16091 {
16092 int rval = EINVAL;
16093
16094 lck_rw_lock_shared(&dtrace_dof_mode_lock);
16095
16096 ASSERT(p->p_dtrace_lazy_dofs == NULL || p->p_dtrace_helpers == NULL);
16097 ASSERT(dtrace_dof_mode != DTRACE_DOF_MODE_NEVER);
16098
16099 /*
16100 * Any existing helpers force non-lazy behavior.
16101 */
16102 if (dtrace_dof_mode == DTRACE_DOF_MODE_LAZY_ON && (p->p_dtrace_helpers == NULL)) {
16103 dtrace_sprlock(p);
16104
16105 dof_ioctl_data_t* existing_dofs = p->p_dtrace_lazy_dofs;
16106
16107 if (existing_dofs) {
16108 int index, existing_dofs_count = existing_dofs->dofiod_count;
16109 for (index=0; index<existing_dofs_count; index++) {
16110 if ((int)existing_dofs->dofiod_helpers[index].dofhp_dof == generation) {
16111 dof_ioctl_data_t* removed_dofs = NULL;
16112
16113 /*
16114 * If there is only 1 dof, we'll delete it and swap in NULL.
16115 */
16116 if (existing_dofs_count > 1) {
16117 int removed_dofs_count = existing_dofs_count - 1;
16118 size_t removed_dofs_size = DOF_IOCTL_DATA_T_SIZE(removed_dofs_count);
16119
16120 removed_dofs = kmem_alloc(removed_dofs_size, KM_SLEEP);
16121 removed_dofs->dofiod_count = removed_dofs_count;
16122
16123 /*
16124 * copy the remaining data.
16125 */
16126 if (index > 0) {
16127 bcopy(&existing_dofs->dofiod_helpers[0],
16128 &removed_dofs->dofiod_helpers[0],
16129 index * sizeof(dof_helper_t));
16130 }
16131
16132 if (index < existing_dofs_count-1) {
16133 bcopy(&existing_dofs->dofiod_helpers[index+1],
16134 &removed_dofs->dofiod_helpers[index],
16135 (existing_dofs_count - index - 1) * sizeof(dof_helper_t));
16136 }
16137 }
16138
16139 kmem_free(existing_dofs, DOF_IOCTL_DATA_T_SIZE(existing_dofs_count));
16140
16141 p->p_dtrace_lazy_dofs = removed_dofs;
16142
16143 rval = KERN_SUCCESS;
16144
16145 break;
16146 }
16147 }
16148
16149 #if DEBUG
16150 dof_ioctl_data_t* all_dofs = p->p_dtrace_lazy_dofs;
16151 if (all_dofs) {
16152 unsigned int i;
16153 for (i=0; i<all_dofs->dofiod_count-1; i++) {
16154 ASSERT(all_dofs->dofiod_helpers[i].dofhp_dof < all_dofs->dofiod_helpers[i+1].dofhp_dof);
16155 }
16156 }
16157 #endif
16158
16159 }
16160 dtrace_sprunlock(p);
16161 } else {
16162 rval = EACCES;
16163 }
16164
16165 lck_rw_unlock_shared(&dtrace_dof_mode_lock);
16166
16167 return rval;
16168 }
16169
16170 void
dtrace_lazy_dofs_destroy(proc_t * p)16171 dtrace_lazy_dofs_destroy(proc_t *p)
16172 {
16173 lck_rw_lock_shared(&dtrace_dof_mode_lock);
16174 dtrace_sprlock(p);
16175
16176 ASSERT(p->p_dtrace_lazy_dofs == NULL || p->p_dtrace_helpers == NULL);
16177
16178 dof_ioctl_data_t* lazy_dofs = p->p_dtrace_lazy_dofs;
16179 p->p_dtrace_lazy_dofs = NULL;
16180
16181 dtrace_sprunlock(p);
16182 lck_rw_unlock_shared(&dtrace_dof_mode_lock);
16183
16184 if (lazy_dofs) {
16185 kmem_free(lazy_dofs, DOF_IOCTL_DATA_T_SIZE(lazy_dofs->dofiod_count));
16186 }
16187 }
16188
16189 static int
dtrace_lazy_dofs_proc_iterate_filter(proc_t * p,void * ignored)16190 dtrace_lazy_dofs_proc_iterate_filter(proc_t *p, void* ignored)
16191 {
16192 #pragma unused(ignored)
16193 /*
16194 * Okay to NULL test without taking the sprlock.
16195 */
16196 return p->p_dtrace_lazy_dofs != NULL;
16197 }
16198
16199 static void
dtrace_lazy_dofs_process(proc_t * p)16200 dtrace_lazy_dofs_process(proc_t *p) {
16201 /*
16202 * It is possible this process may exit during our attempt to
16203 * fault in the dof. We could fix this by holding locks longer,
16204 * but the errors are benign.
16205 */
16206 dtrace_sprlock(p);
16207
16208
16209 ASSERT(p->p_dtrace_lazy_dofs == NULL || p->p_dtrace_helpers == NULL);
16210 ASSERT(dtrace_dof_mode == DTRACE_DOF_MODE_LAZY_OFF);
16211
16212 dof_ioctl_data_t* lazy_dofs = p->p_dtrace_lazy_dofs;
16213 p->p_dtrace_lazy_dofs = NULL;
16214
16215 dtrace_sprunlock(p);
16216 lck_mtx_lock(&dtrace_meta_lock);
16217 /*
16218 * Process each dof_helper_t
16219 */
16220 if (lazy_dofs != NULL) {
16221 unsigned int i;
16222 int rval;
16223
16224 for (i=0; i<lazy_dofs->dofiod_count; i++) {
16225 /*
16226 * When loading lazy dof, we depend on the generations being sorted in ascending order.
16227 */
16228 ASSERT(i >= (lazy_dofs->dofiod_count - 1) || lazy_dofs->dofiod_helpers[i].dofhp_dof < lazy_dofs->dofiod_helpers[i+1].dofhp_dof);
16229
16230 dof_helper_t *dhp = &lazy_dofs->dofiod_helpers[i];
16231
16232 /*
16233 * We stored the generation in dofhp_dof. Save it, and restore the original value.
16234 */
16235 int generation = dhp->dofhp_dof;
16236 dhp->dofhp_dof = dhp->dofhp_addr;
16237
16238 dof_hdr_t *dof = dtrace_dof_copyin_from_proc(p, dhp->dofhp_dof, &rval);
16239
16240 if (dof != NULL) {
16241 dtrace_helpers_t *help;
16242
16243 lck_mtx_lock(&dtrace_lock);
16244
16245 /*
16246 * This must be done with the dtrace_lock held
16247 */
16248 if ((help = p->p_dtrace_helpers) == NULL)
16249 help = dtrace_helpers_create(p);
16250
16251 /*
16252 * If the generation value has been bumped, someone snuck in
16253 * when we released the dtrace lock. We have to dump this generation,
16254 * there is no safe way to load it.
16255 */
16256 if (help->dthps_generation <= generation) {
16257 help->dthps_generation = generation;
16258
16259 /*
16260 * dtrace_helper_slurp() takes responsibility for the dof --
16261 * it may free it now or it may save it and free it later.
16262 */
16263 if ((rval = dtrace_helper_slurp(p, dof, dhp)) != generation) {
16264 dtrace_dof_error(NULL, "returned value did not match expected generation");
16265 }
16266 }
16267
16268 lck_mtx_unlock(&dtrace_lock);
16269 }
16270 }
16271 lck_mtx_unlock(&dtrace_meta_lock);
16272 kmem_free(lazy_dofs, DOF_IOCTL_DATA_T_SIZE(lazy_dofs->dofiod_count));
16273 } else {
16274 lck_mtx_unlock(&dtrace_meta_lock);
16275 }
16276 }
16277
16278 static int
dtrace_lazy_dofs_proc_iterate_doit(proc_t * p,void * ignored)16279 dtrace_lazy_dofs_proc_iterate_doit(proc_t *p, void* ignored)
16280 {
16281 #pragma unused(ignored)
16282
16283 dtrace_lazy_dofs_process(p);
16284
16285 return PROC_RETURNED;
16286 }
16287
16288 #define DTRACE_LAZY_DOFS_DUPLICATED 1
16289
16290 static int
dtrace_lazy_dofs_duplicate(proc_t * parent,proc_t * child)16291 dtrace_lazy_dofs_duplicate(proc_t *parent, proc_t *child)
16292 {
16293 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_NOTOWNED);
16294 LCK_MTX_ASSERT(&parent->p_dtrace_sprlock, LCK_MTX_ASSERT_NOTOWNED);
16295 LCK_MTX_ASSERT(&child->p_dtrace_sprlock, LCK_MTX_ASSERT_NOTOWNED);
16296
16297 lck_rw_lock_shared(&dtrace_dof_mode_lock);
16298 dtrace_sprlock(parent);
16299
16300 /*
16301 * We need to make sure that the transition to lazy dofs -> helpers
16302 * was atomic for our parent
16303 */
16304 ASSERT(parent->p_dtrace_lazy_dofs == NULL || parent->p_dtrace_helpers == NULL);
16305 /*
16306 * In theory we should hold the child sprlock, but this is safe...
16307 */
16308 ASSERT(child->p_dtrace_lazy_dofs == NULL && child->p_dtrace_helpers == NULL);
16309
16310 dof_ioctl_data_t* parent_dofs = parent->p_dtrace_lazy_dofs;
16311 dof_ioctl_data_t* child_dofs = NULL;
16312 if (parent_dofs) {
16313 size_t parent_dofs_size = DOF_IOCTL_DATA_T_SIZE(parent_dofs->dofiod_count);
16314 child_dofs = kmem_alloc(parent_dofs_size, KM_SLEEP);
16315 bcopy(parent_dofs, child_dofs, parent_dofs_size);
16316 }
16317
16318 dtrace_sprunlock(parent);
16319
16320 if (child_dofs) {
16321 dtrace_sprlock(child);
16322 child->p_dtrace_lazy_dofs = child_dofs;
16323 dtrace_sprunlock(child);
16324 /**
16325 * We process the DOF at this point if the mode is set to
16326 * LAZY_OFF. This can happen if DTrace is still processing the
16327 * DOF of other process (which can happen because the
16328 * protected pager can have a huge latency)
16329 * but has not processed our parent yet
16330 */
16331 if (dtrace_dof_mode == DTRACE_DOF_MODE_LAZY_OFF) {
16332 dtrace_lazy_dofs_process(child);
16333 }
16334 lck_rw_unlock_shared(&dtrace_dof_mode_lock);
16335
16336 return DTRACE_LAZY_DOFS_DUPLICATED;
16337 }
16338 lck_rw_unlock_shared(&dtrace_dof_mode_lock);
16339
16340 return 0;
16341 }
16342
16343 static dtrace_helpers_t *
dtrace_helpers_create(proc_t * p)16344 dtrace_helpers_create(proc_t *p)
16345 {
16346 dtrace_helpers_t *help;
16347
16348 LCK_MTX_ASSERT(&dtrace_lock, LCK_MTX_ASSERT_OWNED);
16349 ASSERT(p->p_dtrace_helpers == NULL);
16350
16351 help = kmem_zalloc(sizeof (dtrace_helpers_t), KM_SLEEP);
16352 help->dthps_actions = kmem_zalloc(sizeof (dtrace_helper_action_t *) *
16353 DTRACE_NHELPER_ACTIONS, KM_SLEEP);
16354
16355 p->p_dtrace_helpers = help;
16356 dtrace_helpers++;
16357
16358 return (help);
16359 }
16360
16361 static void
dtrace_helpers_destroy(proc_t * p)16362 dtrace_helpers_destroy(proc_t* p)
16363 {
16364 dtrace_helpers_t *help;
16365 dtrace_vstate_t *vstate;
16366 uint_t i;
16367
16368 lck_mtx_lock(&dtrace_meta_lock);
16369 lck_mtx_lock(&dtrace_lock);
16370
16371 ASSERT(p->p_dtrace_helpers != NULL);
16372 ASSERT(dtrace_helpers > 0);
16373
16374 help = p->p_dtrace_helpers;
16375 vstate = &help->dthps_vstate;
16376
16377 /*
16378 * We're now going to lose the help from this process.
16379 */
16380 p->p_dtrace_helpers = NULL;
16381 dtrace_sync();
16382
16383 /*
16384 * Destory the helper actions.
16385 */
16386 for (i = 0; i < DTRACE_NHELPER_ACTIONS; i++) {
16387 dtrace_helper_action_t *h, *next;
16388
16389 for (h = help->dthps_actions[i]; h != NULL; h = next) {
16390 next = h->dtha_next;
16391 dtrace_helper_action_destroy(h, vstate);
16392 h = next;
16393 }
16394 }
16395
16396 lck_mtx_unlock(&dtrace_lock);
16397
16398 /*
16399 * Destroy the helper providers.
16400 */
16401 if (help->dthps_maxprovs > 0) {
16402 if (dtrace_meta_pid != NULL) {
16403 ASSERT(dtrace_deferred_pid == NULL);
16404
16405 for (i = 0; i < help->dthps_nprovs; i++) {
16406 dtrace_helper_provider_remove(
16407 &help->dthps_provs[i]->dthp_prov, p);
16408 }
16409 } else {
16410 lck_mtx_lock(&dtrace_lock);
16411 ASSERT(help->dthps_deferred == 0 ||
16412 help->dthps_next != NULL ||
16413 help->dthps_prev != NULL ||
16414 help == dtrace_deferred_pid);
16415
16416 /*
16417 * Remove the helper from the deferred list.
16418 */
16419 if (help->dthps_next != NULL)
16420 help->dthps_next->dthps_prev = help->dthps_prev;
16421 if (help->dthps_prev != NULL)
16422 help->dthps_prev->dthps_next = help->dthps_next;
16423 if (dtrace_deferred_pid == help) {
16424 dtrace_deferred_pid = help->dthps_next;
16425 ASSERT(help->dthps_prev == NULL);
16426 }
16427
16428 lck_mtx_unlock(&dtrace_lock);
16429 }
16430
16431
16432 for (i = 0; i < help->dthps_nprovs; i++) {
16433 dtrace_helper_provider_destroy(help->dthps_provs[i]);
16434 }
16435
16436 kmem_free(help->dthps_provs, help->dthps_maxprovs *
16437 sizeof (dtrace_helper_provider_t *));
16438 }
16439
16440 lck_mtx_lock(&dtrace_lock);
16441
16442 dtrace_vstate_fini(&help->dthps_vstate);
16443 kmem_free(help->dthps_actions,
16444 sizeof (dtrace_helper_action_t *) * DTRACE_NHELPER_ACTIONS);
16445 kmem_free(help, sizeof (dtrace_helpers_t));
16446
16447 --dtrace_helpers;
16448 lck_mtx_unlock(&dtrace_lock);
16449 lck_mtx_unlock(&dtrace_meta_lock);
16450 }
16451
16452 static void
dtrace_helpers_duplicate(proc_t * from,proc_t * to)16453 dtrace_helpers_duplicate(proc_t *from, proc_t *to)
16454 {
16455 dtrace_helpers_t *help, *newhelp;
16456 dtrace_helper_action_t *helper, *new, *last;
16457 dtrace_difo_t *dp;
16458 dtrace_vstate_t *vstate;
16459 uint_t i;
16460 int j, sz, hasprovs = 0;
16461
16462 lck_mtx_lock(&dtrace_meta_lock);
16463 lck_mtx_lock(&dtrace_lock);
16464 ASSERT(from->p_dtrace_helpers != NULL);
16465 ASSERT(dtrace_helpers > 0);
16466
16467 help = from->p_dtrace_helpers;
16468 newhelp = dtrace_helpers_create(to);
16469 ASSERT(to->p_dtrace_helpers != NULL);
16470
16471 newhelp->dthps_generation = help->dthps_generation;
16472 vstate = &newhelp->dthps_vstate;
16473
16474 /*
16475 * Duplicate the helper actions.
16476 */
16477 for (i = 0; i < DTRACE_NHELPER_ACTIONS; i++) {
16478 if ((helper = help->dthps_actions[i]) == NULL)
16479 continue;
16480
16481 for (last = NULL; helper != NULL; helper = helper->dtha_next) {
16482 new = kmem_zalloc(sizeof (dtrace_helper_action_t),
16483 KM_SLEEP);
16484 new->dtha_generation = helper->dtha_generation;
16485
16486 if ((dp = helper->dtha_predicate) != NULL) {
16487 dp = dtrace_difo_duplicate(dp, vstate);
16488 new->dtha_predicate = dp;
16489 }
16490
16491 new->dtha_nactions = helper->dtha_nactions;
16492 sz = sizeof (dtrace_difo_t *) * new->dtha_nactions;
16493 new->dtha_actions = kmem_alloc(sz, KM_SLEEP);
16494
16495 for (j = 0; j < new->dtha_nactions; j++) {
16496 dtrace_difo_t *dpj = helper->dtha_actions[j];
16497
16498 ASSERT(dpj != NULL);
16499 dpj = dtrace_difo_duplicate(dpj, vstate);
16500 new->dtha_actions[j] = dpj;
16501 }
16502
16503 if (last != NULL) {
16504 last->dtha_next = new;
16505 } else {
16506 newhelp->dthps_actions[i] = new;
16507 }
16508
16509 last = new;
16510 }
16511 }
16512
16513 /*
16514 * Duplicate the helper providers and register them with the
16515 * DTrace framework.
16516 */
16517 if (help->dthps_nprovs > 0) {
16518 newhelp->dthps_nprovs = help->dthps_nprovs;
16519 newhelp->dthps_maxprovs = help->dthps_nprovs;
16520 newhelp->dthps_provs = kmem_alloc(newhelp->dthps_nprovs *
16521 sizeof (dtrace_helper_provider_t *), KM_SLEEP);
16522 for (i = 0; i < newhelp->dthps_nprovs; i++) {
16523 newhelp->dthps_provs[i] = help->dthps_provs[i];
16524 newhelp->dthps_provs[i]->dthp_ref++;
16525 }
16526
16527 hasprovs = 1;
16528 }
16529
16530 lck_mtx_unlock(&dtrace_lock);
16531
16532 if (hasprovs)
16533 dtrace_helper_provider_register(to, newhelp, NULL);
16534
16535 lck_mtx_unlock(&dtrace_meta_lock);
16536 }
16537
16538 /**
16539 * DTrace Process functions
16540 */
16541
16542 void
dtrace_proc_fork(proc_t * parent_proc,proc_t * child_proc,int spawn)16543 dtrace_proc_fork(proc_t *parent_proc, proc_t *child_proc, int spawn)
16544 {
16545 /*
16546 * This code applies to new processes who are copying the task
16547 * and thread state and address spaces of their parent process.
16548 */
16549 if (!spawn) {
16550 /*
16551 * APPLE NOTE: Solaris does a sprlock() and drops the
16552 * proc_lock here. We're cheating a bit and only taking
16553 * the p_dtrace_sprlock lock. A full sprlock would
16554 * task_suspend the parent.
16555 */
16556 dtrace_sprlock(parent_proc);
16557
16558 /*
16559 * Remove all DTrace tracepoints from the child process. We
16560 * need to do this _before_ duplicating USDT providers since
16561 * any associated probes may be immediately enabled.
16562 */
16563 if (parent_proc->p_dtrace_count > 0) {
16564 dtrace_fasttrap_fork(parent_proc, child_proc);
16565 }
16566
16567 dtrace_sprunlock(parent_proc);
16568
16569 /*
16570 * Duplicate any lazy dof(s). This must be done while NOT
16571 * holding the parent sprlock! Lock ordering is
16572 * dtrace_dof_mode_lock, then sprlock. It is imperative we
16573 * always call dtrace_lazy_dofs_duplicate, rather than null
16574 * check and call if !NULL. If we NULL test, during lazy dof
16575 * faulting we can race with the faulting code and proceed
16576 * from here to beyond the helpers copy. The lazy dof
16577 * faulting will then fail to copy the helpers to the child
16578 * process. We return if we duplicated lazy dofs as a process
16579 * can only have one at the same time to avoid a race between
16580 * a dtrace client and dtrace_proc_fork where a process would
16581 * end up with both lazy dofs and helpers.
16582 */
16583 if (dtrace_lazy_dofs_duplicate(parent_proc, child_proc) == DTRACE_LAZY_DOFS_DUPLICATED) {
16584 return;
16585 }
16586
16587 /*
16588 * Duplicate any helper actions and providers if they haven't
16589 * already.
16590 */
16591 #if !defined(__APPLE__)
16592 /*
16593 * The SFORKING
16594 * we set above informs the code to enable USDT probes that
16595 * sprlock() may fail because the child is being forked.
16596 */
16597 #endif
16598 /*
16599 * APPLE NOTE: As best I can tell, Apple's sprlock() equivalent
16600 * never fails to find the child. We do not set SFORKING.
16601 */
16602 if (parent_proc->p_dtrace_helpers != NULL && dtrace_helpers_fork) {
16603 (*dtrace_helpers_fork)(parent_proc, child_proc);
16604 }
16605 }
16606 }
16607
16608 void
dtrace_proc_exec(proc_t * p)16609 dtrace_proc_exec(proc_t *p)
16610 {
16611 /*
16612 * Invalidate any predicate evaluation already cached for this thread by DTrace.
16613 * That's because we've just stored to p_comm and DTrace refers to that when it
16614 * evaluates the "execname" special variable. uid and gid may have changed as well.
16615 */
16616 dtrace_set_thread_predcache(current_thread(), 0);
16617
16618 /*
16619 * Free any outstanding lazy dof entries. It is imperative we
16620 * always call dtrace_lazy_dofs_destroy, rather than null check
16621 * and call if !NULL. If we NULL test, during lazy dof faulting
16622 * we can race with the faulting code and proceed from here to
16623 * beyond the helpers cleanup. The lazy dof faulting will then
16624 * install new helpers which no longer belong to this process!
16625 */
16626 dtrace_lazy_dofs_destroy(p);
16627
16628
16629 /*
16630 * Clean up any DTrace helpers for the process.
16631 */
16632 if (p->p_dtrace_helpers != NULL && dtrace_helpers_cleanup) {
16633 (*dtrace_helpers_cleanup)(p);
16634 }
16635
16636 /*
16637 * Cleanup the DTrace provider associated with this process.
16638 */
16639 proc_lock(p);
16640 if (p->p_dtrace_probes && dtrace_fasttrap_exec_ptr) {
16641 (*dtrace_fasttrap_exec_ptr)(p);
16642 }
16643 proc_unlock(p);
16644 }
16645
16646 void
dtrace_proc_exit(proc_t * p)16647 dtrace_proc_exit(proc_t *p)
16648 {
16649 /*
16650 * Free any outstanding lazy dof entries. It is imperative we
16651 * always call dtrace_lazy_dofs_destroy, rather than null check
16652 * and call if !NULL. If we NULL test, during lazy dof faulting
16653 * we can race with the faulting code and proceed from here to
16654 * beyond the helpers cleanup. The lazy dof faulting will then
16655 * install new helpers which will never be cleaned up, and leak.
16656 */
16657 dtrace_lazy_dofs_destroy(p);
16658
16659 /*
16660 * Clean up any DTrace helper actions or probes for the process.
16661 */
16662 if (p->p_dtrace_helpers != NULL) {
16663 (*dtrace_helpers_cleanup)(p);
16664 }
16665
16666 /*
16667 * Clean up any DTrace probes associated with this process.
16668 */
16669 /*
16670 * APPLE NOTE: We release ptss pages/entries in dtrace_fasttrap_exit_ptr(),
16671 * call this after dtrace_helpers_cleanup()
16672 */
16673 proc_lock(p);
16674 if (p->p_dtrace_probes && dtrace_fasttrap_exit_ptr) {
16675 (*dtrace_fasttrap_exit_ptr)(p);
16676 }
16677 proc_unlock(p);
16678 }
16679
16680 /*
16681 * DTrace Hook Functions
16682 */
16683
16684 /*
16685 * APPLE NOTE: dtrace_modctl_* routines for kext support.
16686 * Used to manipulate the modctl list within dtrace xnu.
16687 */
16688
16689 modctl_t *dtrace_modctl_list;
16690
16691 static void
dtrace_modctl_add(struct modctl * newctl)16692 dtrace_modctl_add(struct modctl * newctl)
16693 {
16694 struct modctl *nextp, *prevp;
16695
16696 ASSERT(newctl != NULL);
16697 LCK_MTX_ASSERT(&mod_lock, LCK_MTX_ASSERT_OWNED);
16698
16699 // Insert new module at the front of the list,
16700
16701 newctl->mod_next = dtrace_modctl_list;
16702 dtrace_modctl_list = newctl;
16703
16704 /*
16705 * If a module exists with the same name, then that module
16706 * must have been unloaded with enabled probes. We will move
16707 * the unloaded module to the new module's stale chain and
16708 * then stop traversing the list.
16709 */
16710
16711 prevp = newctl;
16712 nextp = newctl->mod_next;
16713
16714 while (nextp != NULL) {
16715 if (nextp->mod_loaded) {
16716 /* This is a loaded module. Keep traversing. */
16717 prevp = nextp;
16718 nextp = nextp->mod_next;
16719 continue;
16720 }
16721 else {
16722 /* Found an unloaded module */
16723 if (strncmp (newctl->mod_modname, nextp->mod_modname, KMOD_MAX_NAME)) {
16724 /* Names don't match. Keep traversing. */
16725 prevp = nextp;
16726 nextp = nextp->mod_next;
16727 continue;
16728 }
16729 else {
16730 /* We found a stale entry, move it. We're done. */
16731 prevp->mod_next = nextp->mod_next;
16732 newctl->mod_stale = nextp;
16733 nextp->mod_next = NULL;
16734 break;
16735 }
16736 }
16737 }
16738 }
16739
16740 static modctl_t *
dtrace_modctl_lookup(struct kmod_info * kmod)16741 dtrace_modctl_lookup(struct kmod_info * kmod)
16742 {
16743 LCK_MTX_ASSERT(&mod_lock, LCK_MTX_ASSERT_OWNED);
16744
16745 struct modctl * ctl;
16746
16747 for (ctl = dtrace_modctl_list; ctl; ctl=ctl->mod_next) {
16748 if (ctl->mod_id == kmod->id)
16749 return(ctl);
16750 }
16751 return (NULL);
16752 }
16753
16754 /*
16755 * This routine is called from dtrace_module_unloaded().
16756 * It removes a modctl structure and its stale chain
16757 * from the kext shadow list.
16758 */
16759 static void
dtrace_modctl_remove(struct modctl * ctl)16760 dtrace_modctl_remove(struct modctl * ctl)
16761 {
16762 ASSERT(ctl != NULL);
16763 LCK_MTX_ASSERT(&mod_lock, LCK_MTX_ASSERT_OWNED);
16764 modctl_t *prevp, *nextp, *curp;
16765
16766 // Remove stale chain first
16767 for (curp=ctl->mod_stale; curp != NULL; curp=nextp) {
16768 nextp = curp->mod_stale;
16769 /* There should NEVER be user symbols allocated at this point */
16770 ASSERT(curp->mod_user_symbols == NULL);
16771 kmem_free(curp, sizeof(modctl_t));
16772 }
16773
16774 prevp = NULL;
16775 curp = dtrace_modctl_list;
16776
16777 while (curp != ctl) {
16778 prevp = curp;
16779 curp = curp->mod_next;
16780 }
16781
16782 if (prevp != NULL) {
16783 prevp->mod_next = ctl->mod_next;
16784 }
16785 else {
16786 dtrace_modctl_list = ctl->mod_next;
16787 }
16788
16789 /* There should NEVER be user symbols allocated at this point */
16790 ASSERT(ctl->mod_user_symbols == NULL);
16791
16792 kmem_free (ctl, sizeof(modctl_t));
16793 }
16794
16795 /*
16796 * APPLE NOTE: The kext loader will call dtrace_module_loaded
16797 * when the kext is loaded in memory, but before calling the
16798 * kext's start routine.
16799 *
16800 * Return 0 on success
16801 * Return -1 on failure
16802 */
16803
16804 static int
dtrace_module_loaded(struct kmod_info * kmod,uint32_t flag)16805 dtrace_module_loaded(struct kmod_info *kmod, uint32_t flag)
16806 {
16807 dtrace_provider_t *prv;
16808
16809 /*
16810 * If kernel symbols have been disabled, return immediately
16811 * DTRACE_KERNEL_SYMBOLS_NEVER is a permanent mode, it is safe to test without holding locks
16812 */
16813 if (dtrace_kernel_symbol_mode == DTRACE_KERNEL_SYMBOLS_NEVER)
16814 return 0;
16815
16816 struct modctl *ctl = NULL;
16817 if (!kmod || kmod->address == 0 || kmod->size == 0)
16818 return(-1);
16819
16820 lck_mtx_lock(&dtrace_provider_lock);
16821 lck_mtx_lock(&mod_lock);
16822
16823 /*
16824 * Have we seen this kext before?
16825 */
16826
16827 ctl = dtrace_modctl_lookup(kmod);
16828
16829 if (ctl != NULL) {
16830 /* bail... we already have this kext in the modctl list */
16831 lck_mtx_unlock(&mod_lock);
16832 lck_mtx_unlock(&dtrace_provider_lock);
16833 if (dtrace_err_verbose)
16834 cmn_err(CE_WARN, "dtrace load module already exists '%s %u' is failing against '%s %u'", kmod->name, (uint_t)kmod->id, ctl->mod_modname, ctl->mod_id);
16835 return(-1);
16836 }
16837 else {
16838 ctl = kmem_alloc(sizeof(struct modctl), KM_SLEEP);
16839 if (ctl == NULL) {
16840 if (dtrace_err_verbose)
16841 cmn_err(CE_WARN, "dtrace module load '%s %u' is failing ", kmod->name, (uint_t)kmod->id);
16842 lck_mtx_unlock(&mod_lock);
16843 lck_mtx_unlock(&dtrace_provider_lock);
16844 return (-1);
16845 }
16846 ctl->mod_next = NULL;
16847 ctl->mod_stale = NULL;
16848 strlcpy (ctl->mod_modname, kmod->name, sizeof(ctl->mod_modname));
16849 ctl->mod_loadcnt = kmod->id;
16850 ctl->mod_nenabled = 0;
16851 ctl->mod_address = kmod->address;
16852 ctl->mod_size = kmod->size;
16853 ctl->mod_id = kmod->id;
16854 ctl->mod_loaded = 1;
16855 ctl->mod_flags = 0;
16856 ctl->mod_user_symbols = NULL;
16857 ctl->mod_sdtprobecnt = 0;
16858 ctl->mod_sdtdesc = NULL;
16859
16860 /*
16861 * Find the UUID for this module, if it has one
16862 */
16863 kernel_mach_header_t* header = (kernel_mach_header_t *)ctl->mod_address;
16864 struct load_command* load_cmd = (struct load_command *)&header[1];
16865 uint32_t i;
16866 for (i = 0; i < header->ncmds; i++) {
16867 if (load_cmd->cmd == LC_UUID) {
16868 struct uuid_command* uuid_cmd = (struct uuid_command *)load_cmd;
16869 memcpy(ctl->mod_uuid, uuid_cmd->uuid, sizeof(uuid_cmd->uuid));
16870 ctl->mod_flags |= MODCTL_HAS_UUID;
16871 break;
16872 }
16873 load_cmd = (struct load_command *)((caddr_t)load_cmd + load_cmd->cmdsize);
16874 }
16875
16876 if (ctl->mod_address == g_kernel_kmod_info.address) {
16877 ctl->mod_flags |= MODCTL_IS_MACH_KERNEL;
16878 memcpy(dtrace_kerneluuid, ctl->mod_uuid, sizeof(dtrace_kerneluuid));
16879 }
16880 /*
16881 * Static kexts have a UUID that is not used for symbolication, as all their
16882 * symbols are in kernel
16883 */
16884 else if ((flag & KMOD_DTRACE_STATIC_KEXT) == KMOD_DTRACE_STATIC_KEXT) {
16885 memcpy(ctl->mod_uuid, dtrace_kerneluuid, sizeof(dtrace_kerneluuid));
16886 ctl->mod_flags |= MODCTL_IS_STATIC_KEXT;
16887 }
16888 }
16889 dtrace_modctl_add(ctl);
16890
16891 /*
16892 * We must hold the dtrace_lock to safely test non permanent dtrace_fbt_symbol_mode(s)
16893 */
16894 lck_mtx_lock(&dtrace_lock);
16895
16896 /*
16897 * DTrace must decide if it will instrument modules lazily via
16898 * userspace symbols (default mode), or instrument immediately via
16899 * kernel symbols (non-default mode)
16900 *
16901 * When in default/lazy mode, DTrace will only support modules
16902 * built with a valid UUID.
16903 *
16904 * Overriding the default can be done explicitly in one of
16905 * the following two ways.
16906 *
16907 * A module can force symbols from kernel space using the plist key,
16908 * OSBundleForceDTraceInit (see kmod.h). If this per kext state is set,
16909 * we fall through and instrument this module now.
16910 *
16911 * Or, the boot-arg, dtrace_kernel_symbol_mode, can be set to force symbols
16912 * from kernel space (see dtrace_impl.h). If this system state is set
16913 * to a non-userspace mode, we fall through and instrument the module now.
16914 */
16915
16916 if ((dtrace_kernel_symbol_mode == DTRACE_KERNEL_SYMBOLS_FROM_USERSPACE) &&
16917 (!(flag & KMOD_DTRACE_FORCE_INIT)))
16918 {
16919 /* Load SDT section for module. Symbol related data will be handled lazily. */
16920 sdt_load_machsect(ctl);
16921
16922 /* We will instrument the module lazily -- this is the default */
16923 lck_mtx_unlock(&dtrace_lock);
16924 lck_mtx_unlock(&mod_lock);
16925 lck_mtx_unlock(&dtrace_provider_lock);
16926 return 0;
16927 }
16928
16929 /* We will instrument the module immediately using kernel symbols */
16930 if (!(flag & KMOD_DTRACE_NO_KERNEL_SYMS)) {
16931 ctl->mod_flags |= MODCTL_HAS_KERNEL_SYMBOLS;
16932 }
16933
16934 /* Load SDT section for module. Symbol related data will be handled lazily. */
16935 sdt_load_machsect(ctl);
16936
16937 lck_mtx_unlock(&dtrace_lock);
16938
16939 /*
16940 * We're going to call each providers per-module provide operation
16941 * specifying only this module.
16942 */
16943 for (prv = dtrace_provider; prv != NULL; prv = prv->dtpv_next)
16944 prv->dtpv_pops.dtps_provide_module(prv->dtpv_arg, ctl);
16945
16946 /*
16947 * APPLE NOTE: The contract with the kext loader is that once this function
16948 * has completed, it may delete kernel symbols at will.
16949 * We must set this while still holding the mod_lock.
16950 */
16951 ctl->mod_flags &= ~MODCTL_HAS_KERNEL_SYMBOLS;
16952
16953 lck_mtx_unlock(&mod_lock);
16954 lck_mtx_unlock(&dtrace_provider_lock);
16955
16956 /*
16957 * If we have any retained enablings, we need to match against them.
16958 * Enabling probes requires that cpu_lock be held, and we cannot hold
16959 * cpu_lock here -- it is legal for cpu_lock to be held when loading a
16960 * module. (In particular, this happens when loading scheduling
16961 * classes.) So if we have any retained enablings, we need to dispatch
16962 * our task queue to do the match for us.
16963 */
16964 lck_mtx_lock(&dtrace_lock);
16965
16966 if (dtrace_retained == NULL) {
16967 lck_mtx_unlock(&dtrace_lock);
16968 return 0;
16969 }
16970
16971 /* APPLE NOTE!
16972 *
16973 * The cpu_lock mentioned above is only held by dtrace code, Apple's xnu never actually
16974 * holds it for any reason. Thus the comment above is invalid, we can directly invoke
16975 * dtrace_enabling_matchall without jumping through all the hoops, and we can avoid
16976 * the delay call as well.
16977 */
16978 lck_mtx_unlock(&dtrace_lock);
16979
16980 dtrace_enabling_matchall();
16981
16982 return 0;
16983 }
16984
16985 /*
16986 * Return 0 on success
16987 * Return -1 on failure
16988 */
16989 static int
dtrace_module_unloaded(struct kmod_info * kmod)16990 dtrace_module_unloaded(struct kmod_info *kmod)
16991 {
16992 dtrace_probe_t template, *probe, *first, *next;
16993 dtrace_provider_t *prov;
16994 struct modctl *ctl = NULL;
16995 struct modctl *syncctl = NULL;
16996 struct modctl *nextsyncctl = NULL;
16997 int syncmode = 0;
16998
16999 lck_mtx_lock(&dtrace_provider_lock);
17000 lck_mtx_lock(&mod_lock);
17001 lck_mtx_lock(&dtrace_lock);
17002
17003 if (kmod == NULL) {
17004 syncmode = 1;
17005 }
17006 else {
17007 ctl = dtrace_modctl_lookup(kmod);
17008 if (ctl == NULL)
17009 {
17010 lck_mtx_unlock(&dtrace_lock);
17011 lck_mtx_unlock(&mod_lock);
17012 lck_mtx_unlock(&dtrace_provider_lock);
17013 return (-1);
17014 }
17015 ctl->mod_loaded = 0;
17016 ctl->mod_address = 0;
17017 ctl->mod_size = 0;
17018 }
17019
17020 if (dtrace_bymod == NULL) {
17021 /*
17022 * The DTrace module is loaded (obviously) but not attached;
17023 * we don't have any work to do.
17024 */
17025 if (ctl != NULL)
17026 (void)dtrace_modctl_remove(ctl);
17027 lck_mtx_unlock(&dtrace_lock);
17028 lck_mtx_unlock(&mod_lock);
17029 lck_mtx_unlock(&dtrace_provider_lock);
17030 return(0);
17031 }
17032
17033 /* Syncmode set means we target and traverse entire modctl list. */
17034 if (syncmode)
17035 nextsyncctl = dtrace_modctl_list;
17036
17037 syncloop:
17038 if (syncmode)
17039 {
17040 /* find a stale modctl struct */
17041 for (syncctl = nextsyncctl; syncctl != NULL; syncctl=syncctl->mod_next) {
17042 if (syncctl->mod_address == 0)
17043 break;
17044 }
17045 if (syncctl==NULL)
17046 {
17047 /* We have no more work to do */
17048 lck_mtx_unlock(&dtrace_lock);
17049 lck_mtx_unlock(&mod_lock);
17050 lck_mtx_unlock(&dtrace_provider_lock);
17051 return(0);
17052 }
17053 else {
17054 /* keep track of next syncctl in case this one is removed */
17055 nextsyncctl = syncctl->mod_next;
17056 ctl = syncctl;
17057 }
17058 }
17059
17060 template.dtpr_mod = ctl->mod_modname;
17061
17062 for (probe = first = dtrace_hash_lookup(dtrace_bymod, &template);
17063 probe != NULL; probe = probe->dtpr_nextmod) {
17064 if (probe->dtpr_ecb != NULL) {
17065 /*
17066 * This shouldn't _actually_ be possible -- we're
17067 * unloading a module that has an enabled probe in it.
17068 * (It's normally up to the provider to make sure that
17069 * this can't happen.) However, because dtps_enable()
17070 * doesn't have a failure mode, there can be an
17071 * enable/unload race. Upshot: we don't want to
17072 * assert, but we're not going to disable the
17073 * probe, either.
17074 */
17075
17076
17077 if (syncmode) {
17078 /* We're syncing, let's look at next in list */
17079 goto syncloop;
17080 }
17081
17082 lck_mtx_unlock(&dtrace_lock);
17083 lck_mtx_unlock(&mod_lock);
17084 lck_mtx_unlock(&dtrace_provider_lock);
17085
17086 if (dtrace_err_verbose) {
17087 cmn_err(CE_WARN, "unloaded module '%s' had "
17088 "enabled probes", ctl->mod_modname);
17089 }
17090 return(-1);
17091 }
17092 }
17093
17094 probe = first;
17095
17096 for (first = NULL; probe != NULL; probe = next) {
17097 ASSERT(dtrace_probes[probe->dtpr_id - 1] == probe);
17098
17099 dtrace_probes[probe->dtpr_id - 1] = NULL;
17100 probe->dtpr_provider->dtpv_probe_count--;
17101
17102 next = probe->dtpr_nextmod;
17103 dtrace_hash_remove(dtrace_byprov, probe);
17104 dtrace_hash_remove(dtrace_bymod, probe);
17105 dtrace_hash_remove(dtrace_byfunc, probe);
17106 dtrace_hash_remove(dtrace_byname, probe);
17107
17108 if (first == NULL) {
17109 first = probe;
17110 probe->dtpr_nextmod = NULL;
17111 } else {
17112 probe->dtpr_nextmod = first;
17113 first = probe;
17114 }
17115 }
17116
17117 /*
17118 * We've removed all of the module's probes from the hash chains and
17119 * from the probe array. Now issue a dtrace_sync() to be sure that
17120 * everyone has cleared out from any probe array processing.
17121 */
17122 dtrace_sync();
17123
17124 for (probe = first; probe != NULL; probe = first) {
17125 first = probe->dtpr_nextmod;
17126 prov = probe->dtpr_provider;
17127 prov->dtpv_pops.dtps_destroy(prov->dtpv_arg, probe->dtpr_id,
17128 probe->dtpr_arg);
17129 dtrace_strunref(probe->dtpr_mod);
17130 dtrace_strunref(probe->dtpr_func);
17131 dtrace_strunref(probe->dtpr_name);
17132 vmem_free(dtrace_arena, (void *)(uintptr_t)probe->dtpr_id, 1);
17133
17134 zfree(dtrace_probe_t_zone, probe);
17135 }
17136
17137 dtrace_modctl_remove(ctl);
17138
17139 if (syncmode)
17140 goto syncloop;
17141
17142 lck_mtx_unlock(&dtrace_lock);
17143 lck_mtx_unlock(&mod_lock);
17144 lck_mtx_unlock(&dtrace_provider_lock);
17145
17146 return(0);
17147 }
17148
17149 void
dtrace_suspend(void)17150 dtrace_suspend(void)
17151 {
17152 dtrace_probe_foreach(offsetof(dtrace_pops_t, dtps_suspend));
17153 }
17154
17155 void
dtrace_resume(void)17156 dtrace_resume(void)
17157 {
17158 dtrace_probe_foreach(offsetof(dtrace_pops_t, dtps_resume));
17159 }
17160
17161 static int
dtrace_cpu_setup(cpu_setup_t what,processorid_t cpu)17162 dtrace_cpu_setup(cpu_setup_t what, processorid_t cpu)
17163 {
17164 LCK_MTX_ASSERT(&cpu_lock, LCK_MTX_ASSERT_OWNED);
17165 lck_mtx_lock(&dtrace_lock);
17166
17167 switch (what) {
17168 case CPU_CONFIG: {
17169 dtrace_state_t *state;
17170 dtrace_optval_t *opt, rs, c;
17171
17172 /*
17173 * For now, we only allocate a new buffer for anonymous state.
17174 */
17175 if ((state = dtrace_anon.dta_state) == NULL)
17176 break;
17177
17178 if (state->dts_activity != DTRACE_ACTIVITY_ACTIVE)
17179 break;
17180
17181 opt = state->dts_options;
17182 c = opt[DTRACEOPT_CPU];
17183
17184 if (c != DTRACE_CPUALL && c != DTRACEOPT_UNSET && c != cpu)
17185 break;
17186
17187 /*
17188 * Regardless of what the actual policy is, we're going to
17189 * temporarily set our resize policy to be manual. We're
17190 * also going to temporarily set our CPU option to denote
17191 * the newly configured CPU.
17192 */
17193 rs = opt[DTRACEOPT_BUFRESIZE];
17194 opt[DTRACEOPT_BUFRESIZE] = DTRACEOPT_BUFRESIZE_MANUAL;
17195 opt[DTRACEOPT_CPU] = (dtrace_optval_t)cpu;
17196
17197 (void) dtrace_state_buffers(state);
17198
17199 opt[DTRACEOPT_BUFRESIZE] = rs;
17200 opt[DTRACEOPT_CPU] = c;
17201
17202 break;
17203 }
17204
17205 case CPU_UNCONFIG:
17206 /*
17207 * We don't free the buffer in the CPU_UNCONFIG case. (The
17208 * buffer will be freed when the consumer exits.)
17209 */
17210 break;
17211
17212 default:
17213 break;
17214 }
17215
17216 lck_mtx_unlock(&dtrace_lock);
17217 return (0);
17218 }
17219
17220 static void
dtrace_cpu_setup_initial(processorid_t cpu)17221 dtrace_cpu_setup_initial(processorid_t cpu)
17222 {
17223 (void) dtrace_cpu_setup(CPU_CONFIG, cpu);
17224 }
17225
17226 static void
dtrace_toxrange_add(uintptr_t base,uintptr_t limit)17227 dtrace_toxrange_add(uintptr_t base, uintptr_t limit)
17228 {
17229 if (dtrace_toxranges >= dtrace_toxranges_max) {
17230 int osize, nsize;
17231 dtrace_toxrange_t *range;
17232
17233 osize = dtrace_toxranges_max * sizeof (dtrace_toxrange_t);
17234
17235 if (osize == 0) {
17236 ASSERT(dtrace_toxrange == NULL);
17237 ASSERT(dtrace_toxranges_max == 0);
17238 dtrace_toxranges_max = 1;
17239 } else {
17240 dtrace_toxranges_max <<= 1;
17241 }
17242
17243 nsize = dtrace_toxranges_max * sizeof (dtrace_toxrange_t);
17244 range = kmem_zalloc(nsize, KM_SLEEP);
17245
17246 if (dtrace_toxrange != NULL) {
17247 ASSERT(osize != 0);
17248 bcopy(dtrace_toxrange, range, osize);
17249 kmem_free(dtrace_toxrange, osize);
17250 }
17251
17252 dtrace_toxrange = range;
17253 }
17254
17255 ASSERT(dtrace_toxrange[dtrace_toxranges].dtt_base == 0);
17256 ASSERT(dtrace_toxrange[dtrace_toxranges].dtt_limit == 0);
17257
17258 dtrace_toxrange[dtrace_toxranges].dtt_base = base;
17259 dtrace_toxrange[dtrace_toxranges].dtt_limit = limit;
17260 dtrace_toxranges++;
17261 }
17262
17263 /*
17264 * DTrace Driver Cookbook Functions
17265 */
17266 /*ARGSUSED*/
17267 static int
dtrace_attach(dev_info_t * devi)17268 dtrace_attach(dev_info_t *devi)
17269 {
17270 dtrace_provider_id_t id;
17271 dtrace_state_t *state = NULL;
17272 dtrace_enabling_t *enab;
17273
17274 lck_mtx_lock(&cpu_lock);
17275 lck_mtx_lock(&dtrace_provider_lock);
17276 lck_mtx_lock(&dtrace_lock);
17277
17278 /* Darwin uses BSD cloning device driver to automagically obtain minor device number. */
17279 dtrace_devi = devi;
17280
17281 dtrace_modload = dtrace_module_loaded;
17282 dtrace_modunload = dtrace_module_unloaded;
17283 dtrace_cpu_init = dtrace_cpu_setup_initial;
17284 dtrace_helpers_cleanup = dtrace_helpers_destroy;
17285 dtrace_helpers_fork = dtrace_helpers_duplicate;
17286 dtrace_cpustart_init = dtrace_suspend;
17287 dtrace_cpustart_fini = dtrace_resume;
17288 dtrace_debugger_init = dtrace_suspend;
17289 dtrace_debugger_fini = dtrace_resume;
17290
17291 register_cpu_setup_func((cpu_setup_func_t *)dtrace_cpu_setup, NULL);
17292
17293 LCK_MTX_ASSERT(&cpu_lock, LCK_MTX_ASSERT_OWNED);
17294
17295 dtrace_arena = vmem_create("dtrace", (void *)1, INT32_MAX, 1,
17296 NULL, NULL, NULL, 0, VM_SLEEP | VMC_IDENTIFIER);
17297
17298 dtrace_state_cache = kmem_cache_create("dtrace_state_cache",
17299 sizeof (dtrace_dstate_percpu_t) * (int)NCPU, DTRACE_STATE_ALIGN,
17300 NULL, NULL, NULL, NULL, NULL, 0);
17301
17302 LCK_MTX_ASSERT(&cpu_lock, LCK_MTX_ASSERT_OWNED);
17303
17304 dtrace_nprobes = dtrace_nprobes_default;
17305 dtrace_probes = kmem_zalloc(sizeof(dtrace_probe_t*) * dtrace_nprobes,
17306 KM_SLEEP);
17307
17308 dtrace_byprov = dtrace_hash_create(dtrace_strkey_probe_provider,
17309 0, /* unused */
17310 offsetof(dtrace_probe_t, dtpr_nextprov),
17311 offsetof(dtrace_probe_t, dtpr_prevprov));
17312
17313 dtrace_bymod = dtrace_hash_create(dtrace_strkey_deref_offset,
17314 offsetof(dtrace_probe_t, dtpr_mod),
17315 offsetof(dtrace_probe_t, dtpr_nextmod),
17316 offsetof(dtrace_probe_t, dtpr_prevmod));
17317
17318 dtrace_byfunc = dtrace_hash_create(dtrace_strkey_deref_offset,
17319 offsetof(dtrace_probe_t, dtpr_func),
17320 offsetof(dtrace_probe_t, dtpr_nextfunc),
17321 offsetof(dtrace_probe_t, dtpr_prevfunc));
17322
17323 dtrace_byname = dtrace_hash_create(dtrace_strkey_deref_offset,
17324 offsetof(dtrace_probe_t, dtpr_name),
17325 offsetof(dtrace_probe_t, dtpr_nextname),
17326 offsetof(dtrace_probe_t, dtpr_prevname));
17327
17328 if (dtrace_retain_max < 1) {
17329 cmn_err(CE_WARN, "illegal value (%lu) for dtrace_retain_max; "
17330 "setting to 1", dtrace_retain_max);
17331 dtrace_retain_max = 1;
17332 }
17333
17334 /*
17335 * Now discover our toxic ranges.
17336 */
17337 dtrace_toxic_ranges(dtrace_toxrange_add);
17338
17339 /*
17340 * Before we register ourselves as a provider to our own framework,
17341 * we would like to assert that dtrace_provider is NULL -- but that's
17342 * not true if we were loaded as a dependency of a DTrace provider.
17343 * Once we've registered, we can assert that dtrace_provider is our
17344 * pseudo provider.
17345 */
17346 (void) dtrace_register("dtrace", &dtrace_provider_attr,
17347 DTRACE_PRIV_NONE, 0, &dtrace_provider_ops, NULL, &id);
17348
17349 ASSERT(dtrace_provider != NULL);
17350 ASSERT((dtrace_provider_id_t)dtrace_provider == id);
17351
17352 #if defined (__x86_64__)
17353 dtrace_probeid_begin = dtrace_probe_create((dtrace_provider_id_t)
17354 dtrace_provider, NULL, NULL, "BEGIN", 1, NULL);
17355 dtrace_probeid_end = dtrace_probe_create((dtrace_provider_id_t)
17356 dtrace_provider, NULL, NULL, "END", 0, NULL);
17357 dtrace_probeid_error = dtrace_probe_create((dtrace_provider_id_t)
17358 dtrace_provider, NULL, NULL, "ERROR", 3, NULL);
17359 #elif (defined(__arm__) || defined(__arm64__))
17360 dtrace_probeid_begin = dtrace_probe_create((dtrace_provider_id_t)
17361 dtrace_provider, NULL, NULL, "BEGIN", 2, NULL);
17362 dtrace_probeid_end = dtrace_probe_create((dtrace_provider_id_t)
17363 dtrace_provider, NULL, NULL, "END", 1, NULL);
17364 dtrace_probeid_error = dtrace_probe_create((dtrace_provider_id_t)
17365 dtrace_provider, NULL, NULL, "ERROR", 4, NULL);
17366 #else
17367 #error Unknown Architecture
17368 #endif
17369
17370 dtrace_anon_property();
17371 lck_mtx_unlock(&cpu_lock);
17372
17373 /*
17374 * If DTrace helper tracing is enabled, we need to allocate the
17375 * trace buffer and initialize the values.
17376 */
17377 if (dtrace_helptrace_enabled) {
17378 ASSERT(dtrace_helptrace_buffer == NULL);
17379 dtrace_helptrace_buffer =
17380 kmem_zalloc(dtrace_helptrace_bufsize, KM_SLEEP);
17381 dtrace_helptrace_next = 0;
17382 }
17383
17384 /*
17385 * If there are already providers, we must ask them to provide their
17386 * probes, and then match any anonymous enabling against them. Note
17387 * that there should be no other retained enablings at this time:
17388 * the only retained enablings at this time should be the anonymous
17389 * enabling.
17390 */
17391 if (dtrace_anon.dta_enabling != NULL) {
17392 ASSERT(dtrace_retained == dtrace_anon.dta_enabling);
17393
17394 /*
17395 * APPLE NOTE: if handling anonymous dof, switch symbol modes.
17396 */
17397 if (dtrace_kernel_symbol_mode == DTRACE_KERNEL_SYMBOLS_FROM_USERSPACE) {
17398 dtrace_kernel_symbol_mode = DTRACE_KERNEL_SYMBOLS_FROM_KERNEL;
17399 }
17400
17401 dtrace_enabling_provide(NULL);
17402 state = dtrace_anon.dta_state;
17403
17404 /*
17405 * We couldn't hold cpu_lock across the above call to
17406 * dtrace_enabling_provide(), but we must hold it to actually
17407 * enable the probes. We have to drop all of our locks, pick
17408 * up cpu_lock, and regain our locks before matching the
17409 * retained anonymous enabling.
17410 */
17411 lck_mtx_unlock(&dtrace_lock);
17412 lck_mtx_unlock(&dtrace_provider_lock);
17413
17414 lck_mtx_lock(&cpu_lock);
17415 lck_mtx_lock(&dtrace_provider_lock);
17416 lck_mtx_lock(&dtrace_lock);
17417
17418 if ((enab = dtrace_anon.dta_enabling) != NULL)
17419 (void) dtrace_enabling_match(enab, NULL, NULL);
17420
17421 lck_mtx_unlock(&cpu_lock);
17422 }
17423
17424 lck_mtx_unlock(&dtrace_lock);
17425 lck_mtx_unlock(&dtrace_provider_lock);
17426
17427 if (state != NULL) {
17428 /*
17429 * If we created any anonymous state, set it going now.
17430 */
17431 (void) dtrace_state_go(state, &dtrace_anon.dta_beganon);
17432 }
17433
17434 return (DDI_SUCCESS);
17435 }
17436
17437 /*ARGSUSED*/
17438 static int
dtrace_open(dev_t * devp,int flag,int otyp,cred_t * cred_p)17439 dtrace_open(dev_t *devp, int flag, int otyp, cred_t *cred_p)
17440 {
17441 #pragma unused(flag, otyp)
17442 dtrace_state_t *state;
17443 uint32_t priv;
17444 uid_t uid;
17445 zoneid_t zoneid;
17446 int rv;
17447
17448 /* APPLE: Darwin puts Helper on its own major device. */
17449
17450 /*
17451 * If no DTRACE_PRIV_* bits are set in the credential, then the
17452 * caller lacks sufficient permission to do anything with DTrace.
17453 */
17454 dtrace_cred2priv(cred_p, &priv, &uid, &zoneid);
17455 if (priv == DTRACE_PRIV_NONE)
17456 return (EACCES);
17457
17458 /*
17459 * APPLE NOTE: We delay the initialization of fasttrap as late as possible.
17460 * It certainly can't be later than now!
17461 */
17462 fasttrap_init();
17463
17464 /*
17465 * Ask all providers to provide all their probes.
17466 */
17467 lck_mtx_lock(&dtrace_provider_lock);
17468 dtrace_probe_provide(NULL, NULL);
17469 lck_mtx_unlock(&dtrace_provider_lock);
17470
17471 lck_mtx_lock(&cpu_lock);
17472 lck_mtx_lock(&dtrace_lock);
17473 dtrace_opens++;
17474 dtrace_membar_producer();
17475
17476 #ifdef illumos
17477 /*
17478 * If the kernel debugger is active (that is, if the kernel debugger
17479 * modified text in some way), we won't allow the open.
17480 */
17481 if (kdi_dtrace_set(KDI_DTSET_DTRACE_ACTIVATE) != 0) {
17482 dtrace_opens--;
17483 lck_mtx_unlock(&dtrace_lock);
17484 lck_mtx_unlock(&cpu_lock);
17485 return (EBUSY);
17486 }
17487 #endif
17488
17489 rv = dtrace_state_create(devp, cred_p, &state);
17490 lck_mtx_unlock(&cpu_lock);
17491
17492 if (rv != 0 || state == NULL) {
17493 if (--dtrace_opens == 0 && dtrace_anon.dta_enabling == NULL) {
17494 #ifdef illumos
17495 (void) kdi_dtrace_set(KDI_DTSET_DTRACE_DEACTIVATE);
17496 #endif
17497 }
17498 lck_mtx_unlock(&dtrace_lock);
17499 /* propagate EAGAIN or ERESTART */
17500 return (rv);
17501 }
17502
17503 lck_mtx_unlock(&dtrace_lock);
17504
17505 lck_rw_lock_exclusive(&dtrace_dof_mode_lock);
17506
17507 /*
17508 * If we are currently lazy, transition states.
17509 *
17510 * Unlike dtrace_close, we do not need to check the
17511 * value of dtrace_opens, as any positive value (and
17512 * we count as 1) means we transition states.
17513 */
17514 if (dtrace_dof_mode == DTRACE_DOF_MODE_LAZY_ON) {
17515 dtrace_dof_mode = DTRACE_DOF_MODE_LAZY_OFF;
17516 /*
17517 * We do not need to hold the exclusive lock while processing
17518 * DOF on processes. We do need to make sure the mode does not get
17519 * changed to DTRACE_DOF_MODE_LAZY_ON during that stage though
17520 * (which should not happen anyway since it only happens in
17521 * dtrace_close). There is no way imcomplete USDT probes can be
17522 * activate by any DTrace clients here since they all have to
17523 * call dtrace_open and be blocked on dtrace_dof_mode_lock
17524 */
17525 lck_rw_lock_exclusive_to_shared(&dtrace_dof_mode_lock);
17526 /*
17527 * Iterate all existing processes and load lazy dofs.
17528 */
17529 proc_iterate(PROC_ALLPROCLIST | PROC_NOWAITTRANS,
17530 dtrace_lazy_dofs_proc_iterate_doit,
17531 NULL,
17532 dtrace_lazy_dofs_proc_iterate_filter,
17533 NULL);
17534
17535 lck_rw_unlock_shared(&dtrace_dof_mode_lock);
17536 }
17537 else {
17538 lck_rw_unlock_exclusive(&dtrace_dof_mode_lock);
17539 }
17540
17541
17542 /*
17543 * Update kernel symbol state.
17544 *
17545 * We must own the provider and dtrace locks.
17546 *
17547 * NOTE! It may appear there is a race by setting this value so late
17548 * after dtrace_probe_provide. However, any kext loaded after the
17549 * call to probe provide and before we set LAZY_OFF will be marked as
17550 * eligible for symbols from userspace. The same dtrace that is currently
17551 * calling dtrace_open() (this call!) will get a list of kexts needing
17552 * symbols and fill them in, thus closing the race window.
17553 *
17554 * We want to set this value only after it certain it will succeed, as
17555 * this significantly reduces the complexity of error exits.
17556 */
17557 lck_mtx_lock(&dtrace_lock);
17558 if (dtrace_kernel_symbol_mode == DTRACE_KERNEL_SYMBOLS_FROM_USERSPACE) {
17559 dtrace_kernel_symbol_mode = DTRACE_KERNEL_SYMBOLS_FROM_KERNEL;
17560 }
17561 lck_mtx_unlock(&dtrace_lock);
17562
17563 return (0);
17564 }
17565
17566 /*ARGSUSED*/
17567 static int
dtrace_close(dev_t dev,int flag,int otyp,cred_t * cred_p)17568 dtrace_close(dev_t dev, int flag, int otyp, cred_t *cred_p)
17569 {
17570 #pragma unused(flag, otyp, cred_p) /* __APPLE__ */
17571 minor_t minor = getminor(dev);
17572 dtrace_state_t *state;
17573
17574 /* APPLE NOTE: Darwin puts Helper on its own major device. */
17575 state = dtrace_state_get(minor);
17576
17577 lck_mtx_lock(&cpu_lock);
17578 lck_mtx_lock(&dtrace_lock);
17579
17580 if (state->dts_anon) {
17581 /*
17582 * There is anonymous state. Destroy that first.
17583 */
17584 ASSERT(dtrace_anon.dta_state == NULL);
17585 dtrace_state_destroy(state->dts_anon);
17586 }
17587
17588 dtrace_state_destroy(state);
17589 ASSERT(dtrace_opens > 0);
17590
17591 /*
17592 * Only relinquish control of the kernel debugger interface when there
17593 * are no consumers and no anonymous enablings.
17594 */
17595 if (--dtrace_opens == 0 && dtrace_anon.dta_enabling == NULL) {
17596 #ifdef illumos
17597 (void) kdi_dtrace_set(KDI_DTSET_DTRACE_DEACTIVATE);
17598 #endif
17599 }
17600
17601 lck_mtx_unlock(&dtrace_lock);
17602 lck_mtx_unlock(&cpu_lock);
17603
17604 /*
17605 * Lock ordering requires the dof mode lock be taken before
17606 * the dtrace_lock.
17607 */
17608 lck_rw_lock_exclusive(&dtrace_dof_mode_lock);
17609 lck_mtx_lock(&dtrace_lock);
17610
17611 if (dtrace_opens == 0) {
17612 /*
17613 * If we are currently lazy-off, and this is the last close, transition to
17614 * lazy state.
17615 */
17616 if (dtrace_dof_mode == DTRACE_DOF_MODE_LAZY_OFF) {
17617 dtrace_dof_mode = DTRACE_DOF_MODE_LAZY_ON;
17618 }
17619
17620 /*
17621 * If we are the last dtrace client, switch back to lazy (from userspace) symbols
17622 */
17623 if (dtrace_kernel_symbol_mode == DTRACE_KERNEL_SYMBOLS_FROM_KERNEL) {
17624 dtrace_kernel_symbol_mode = DTRACE_KERNEL_SYMBOLS_FROM_USERSPACE;
17625 }
17626 }
17627
17628 lck_mtx_unlock(&dtrace_lock);
17629 lck_rw_unlock_exclusive(&dtrace_dof_mode_lock);
17630
17631 /*
17632 * Kext probes may be retained past the end of the kext's lifespan. The
17633 * probes are kept until the last reference to them has been removed.
17634 * Since closing an active dtrace context is likely to drop that last reference,
17635 * lets take a shot at cleaning out the orphaned probes now.
17636 */
17637 dtrace_module_unloaded(NULL);
17638
17639 return (0);
17640 }
17641
17642 /*ARGSUSED*/
17643 static int
dtrace_ioctl_helper(u_long cmd,caddr_t arg,int * rv)17644 dtrace_ioctl_helper(u_long cmd, caddr_t arg, int *rv)
17645 {
17646 #pragma unused(rv)
17647 /*
17648 * Safe to check this outside the dof mode lock
17649 */
17650 if (dtrace_dof_mode == DTRACE_DOF_MODE_NEVER)
17651 return KERN_SUCCESS;
17652
17653 switch (cmd) {
17654 #if defined (__arm64__)
17655 case DTRACEHIOC_ADDDOF_U32:
17656 case DTRACEHIOC_ADDDOF_U64:
17657 #else
17658 case DTRACEHIOC_ADDDOF:
17659 #endif /* __arm64__*/
17660 {
17661 dof_helper_t *dhp = NULL;
17662 size_t dof_ioctl_data_size;
17663 dof_ioctl_data_t* multi_dof;
17664 unsigned int i;
17665 int rval = 0;
17666 user_addr_t user_address = *(user_addr_t*)arg;
17667 uint64_t dof_count;
17668 int multi_dof_claimed = 0;
17669 proc_t* p = current_proc();
17670
17671 /*
17672 * If this is a restricted process and dtrace is restricted,
17673 * do not allow DOFs to be registered
17674 */
17675 if (dtrace_is_restricted() &&
17676 !dtrace_are_restrictions_relaxed() &&
17677 !dtrace_can_attach_to_proc(current_proc())) {
17678 return (EACCES);
17679 }
17680
17681 /*
17682 * Read the number of DOF sections being passed in.
17683 */
17684 if (copyin(user_address + offsetof(dof_ioctl_data_t, dofiod_count),
17685 &dof_count,
17686 sizeof(dof_count))) {
17687 dtrace_dof_error(NULL, "failed to copyin dofiod_count");
17688 return (EFAULT);
17689 }
17690
17691 /*
17692 * Range check the count.
17693 */
17694 if (dof_count == 0 || dof_count > 1024) {
17695 dtrace_dof_error(NULL, "dofiod_count is not valid");
17696 return (EINVAL);
17697 }
17698
17699 /*
17700 * Allocate a correctly sized structure and copyin the data.
17701 */
17702 dof_ioctl_data_size = DOF_IOCTL_DATA_T_SIZE(dof_count);
17703 if ((multi_dof = kmem_alloc(dof_ioctl_data_size, KM_SLEEP)) == NULL)
17704 return (ENOMEM);
17705
17706 /* NOTE! We can no longer exit this method via return */
17707 if (copyin(user_address, multi_dof, dof_ioctl_data_size) != 0) {
17708 dtrace_dof_error(NULL, "failed copyin of dof_ioctl_data_t");
17709 rval = EFAULT;
17710 goto cleanup;
17711 }
17712
17713 /*
17714 * Check that the count didn't change between the first copyin and the second.
17715 */
17716 if (multi_dof->dofiod_count != dof_count) {
17717 rval = EINVAL;
17718 goto cleanup;
17719 }
17720
17721 /*
17722 * Try to process lazily first.
17723 */
17724 rval = dtrace_lazy_dofs_add(p, multi_dof, &multi_dof_claimed);
17725
17726 /*
17727 * If rval is EACCES, we must be non-lazy.
17728 */
17729 if (rval == EACCES) {
17730 rval = 0;
17731 /*
17732 * Process each dof_helper_t
17733 */
17734 i = 0;
17735 do {
17736 dhp = &multi_dof->dofiod_helpers[i];
17737
17738 dof_hdr_t *dof = dtrace_dof_copyin(dhp->dofhp_dof, &rval);
17739
17740 if (dof != NULL) {
17741 lck_mtx_lock(&dtrace_meta_lock);
17742 lck_mtx_lock(&dtrace_lock);
17743
17744 /*
17745 * dtrace_helper_slurp() takes responsibility for the dof --
17746 * it may free it now or it may save it and free it later.
17747 */
17748 if ((dhp->dofhp_dof = (uint64_t)dtrace_helper_slurp(p, dof, dhp)) == -1ULL) {
17749 rval = EINVAL;
17750 }
17751
17752 lck_mtx_unlock(&dtrace_lock);
17753 lck_mtx_unlock(&dtrace_meta_lock);
17754 }
17755 } while (++i < multi_dof->dofiod_count && rval == 0);
17756 }
17757
17758 /*
17759 * We need to copyout the multi_dof struct, because it contains
17760 * the generation (unique id) values needed to call DTRACEHIOC_REMOVE
17761 *
17762 * This could certainly be better optimized.
17763 */
17764 if (copyout(multi_dof, user_address, dof_ioctl_data_size) != 0) {
17765 dtrace_dof_error(NULL, "failed copyout of dof_ioctl_data_t");
17766 /* Don't overwrite pre-existing error code */
17767 if (rval == 0) rval = EFAULT;
17768 }
17769
17770 cleanup:
17771 /*
17772 * If we had to allocate struct memory, free it.
17773 */
17774 if (multi_dof != NULL && !multi_dof_claimed) {
17775 kmem_free(multi_dof, dof_ioctl_data_size);
17776 }
17777
17778 return rval;
17779 }
17780
17781 case DTRACEHIOC_REMOVE: {
17782 int generation = *(int*)arg;
17783 proc_t* p = current_proc();
17784
17785 /*
17786 * Try lazy first.
17787 */
17788 int rval = dtrace_lazy_dofs_remove(p, generation);
17789
17790 /*
17791 * EACCES means non-lazy
17792 */
17793 if (rval == EACCES) {
17794 lck_mtx_lock(&dtrace_meta_lock);
17795 lck_mtx_lock(&dtrace_lock);
17796 rval = dtrace_helper_destroygen(p, generation);
17797 lck_mtx_unlock(&dtrace_lock);
17798 lck_mtx_unlock(&dtrace_meta_lock);
17799 }
17800
17801 return (rval);
17802 }
17803
17804 default:
17805 break;
17806 }
17807
17808 return ENOTTY;
17809 }
17810
17811 /*ARGSUSED*/
17812 static int
dtrace_ioctl(dev_t dev,u_long cmd,user_addr_t arg,int md,cred_t * cr,int * rv)17813 dtrace_ioctl(dev_t dev, u_long cmd, user_addr_t arg, int md, cred_t *cr, int *rv)
17814 {
17815 #pragma unused(md)
17816 minor_t minor = getminor(dev);
17817 dtrace_state_t *state;
17818 int rval;
17819
17820 /* Darwin puts Helper on its own major device. */
17821
17822 state = dtrace_state_get(minor);
17823
17824 if (state->dts_anon) {
17825 ASSERT(dtrace_anon.dta_state == NULL);
17826 state = state->dts_anon;
17827 }
17828
17829 switch (cmd) {
17830 case DTRACEIOC_PROVIDER: {
17831 dtrace_providerdesc_t pvd;
17832 dtrace_provider_t *pvp;
17833
17834 if (copyin(arg, &pvd, sizeof (pvd)) != 0)
17835 return (EFAULT);
17836
17837 pvd.dtvd_name[DTRACE_PROVNAMELEN - 1] = '\0';
17838 lck_mtx_lock(&dtrace_provider_lock);
17839
17840 for (pvp = dtrace_provider; pvp != NULL; pvp = pvp->dtpv_next) {
17841 if (strncmp(pvp->dtpv_name, pvd.dtvd_name, DTRACE_PROVNAMELEN) == 0)
17842 break;
17843 }
17844
17845 lck_mtx_unlock(&dtrace_provider_lock);
17846
17847 if (pvp == NULL)
17848 return (ESRCH);
17849
17850 bcopy(&pvp->dtpv_priv, &pvd.dtvd_priv, sizeof (dtrace_ppriv_t));
17851 bcopy(&pvp->dtpv_attr, &pvd.dtvd_attr, sizeof (dtrace_pattr_t));
17852 if (copyout(&pvd, arg, sizeof (pvd)) != 0)
17853 return (EFAULT);
17854
17855 return (0);
17856 }
17857
17858 case DTRACEIOC_EPROBE: {
17859 dtrace_eprobedesc_t epdesc;
17860 dtrace_ecb_t *ecb;
17861 dtrace_action_t *act;
17862 void *buf;
17863 size_t size;
17864 uintptr_t dest;
17865 int nrecs;
17866
17867 if (copyin(arg, &epdesc, sizeof (epdesc)) != 0)
17868 return (EFAULT);
17869
17870 lck_mtx_lock(&dtrace_lock);
17871
17872 if ((ecb = dtrace_epid2ecb(state, epdesc.dtepd_epid)) == NULL) {
17873 lck_mtx_unlock(&dtrace_lock);
17874 return (EINVAL);
17875 }
17876
17877 if (ecb->dte_probe == NULL) {
17878 lck_mtx_unlock(&dtrace_lock);
17879 return (EINVAL);
17880 }
17881
17882 epdesc.dtepd_probeid = ecb->dte_probe->dtpr_id;
17883 epdesc.dtepd_uarg = ecb->dte_uarg;
17884 epdesc.dtepd_size = ecb->dte_size;
17885
17886 nrecs = epdesc.dtepd_nrecs;
17887 epdesc.dtepd_nrecs = 0;
17888 for (act = ecb->dte_action; act != NULL; act = act->dta_next) {
17889 if (DTRACEACT_ISAGG(act->dta_kind) || act->dta_intuple)
17890 continue;
17891
17892 epdesc.dtepd_nrecs++;
17893 }
17894
17895 /*
17896 * Now that we have the size, we need to allocate a temporary
17897 * buffer in which to store the complete description. We need
17898 * the temporary buffer to be able to drop dtrace_lock()
17899 * across the copyout(), below.
17900 */
17901 size = sizeof (dtrace_eprobedesc_t) +
17902 (epdesc.dtepd_nrecs * sizeof (dtrace_recdesc_t));
17903
17904 buf = kmem_alloc(size, KM_SLEEP);
17905 dest = (uintptr_t)buf;
17906
17907 bcopy(&epdesc, (void *)dest, sizeof (epdesc));
17908 dest += offsetof(dtrace_eprobedesc_t, dtepd_rec[0]);
17909
17910 for (act = ecb->dte_action; act != NULL; act = act->dta_next) {
17911 if (DTRACEACT_ISAGG(act->dta_kind) || act->dta_intuple)
17912 continue;
17913
17914 if (nrecs-- == 0)
17915 break;
17916
17917 bcopy(&act->dta_rec, (void *)dest,
17918 sizeof (dtrace_recdesc_t));
17919 dest += sizeof (dtrace_recdesc_t);
17920 }
17921
17922 lck_mtx_unlock(&dtrace_lock);
17923
17924 if (copyout(buf, arg, dest - (uintptr_t)buf) != 0) {
17925 kmem_free(buf, size);
17926 return (EFAULT);
17927 }
17928
17929 kmem_free(buf, size);
17930 return (0);
17931 }
17932
17933 case DTRACEIOC_AGGDESC: {
17934 dtrace_aggdesc_t aggdesc;
17935 dtrace_action_t *act;
17936 dtrace_aggregation_t *agg;
17937 int nrecs;
17938 uint32_t offs;
17939 dtrace_recdesc_t *lrec;
17940 void *buf;
17941 size_t size;
17942 uintptr_t dest;
17943
17944 if (copyin(arg, &aggdesc, sizeof (aggdesc)) != 0)
17945 return (EFAULT);
17946
17947 lck_mtx_lock(&dtrace_lock);
17948
17949 if ((agg = dtrace_aggid2agg(state, aggdesc.dtagd_id)) == NULL) {
17950 lck_mtx_unlock(&dtrace_lock);
17951 return (EINVAL);
17952 }
17953
17954 aggdesc.dtagd_epid = agg->dtag_ecb->dte_epid;
17955
17956 nrecs = aggdesc.dtagd_nrecs;
17957 aggdesc.dtagd_nrecs = 0;
17958
17959 offs = agg->dtag_base;
17960 lrec = &agg->dtag_action.dta_rec;
17961 aggdesc.dtagd_size = lrec->dtrd_offset + lrec->dtrd_size - offs;
17962
17963 for (act = agg->dtag_first; ; act = act->dta_next) {
17964 ASSERT(act->dta_intuple ||
17965 DTRACEACT_ISAGG(act->dta_kind));
17966
17967 /*
17968 * If this action has a record size of zero, it
17969 * denotes an argument to the aggregating action.
17970 * Because the presence of this record doesn't (or
17971 * shouldn't) affect the way the data is interpreted,
17972 * we don't copy it out to save user-level the
17973 * confusion of dealing with a zero-length record.
17974 */
17975 if (act->dta_rec.dtrd_size == 0) {
17976 ASSERT(agg->dtag_hasarg);
17977 continue;
17978 }
17979
17980 aggdesc.dtagd_nrecs++;
17981
17982 if (act == &agg->dtag_action)
17983 break;
17984 }
17985
17986 /*
17987 * Now that we have the size, we need to allocate a temporary
17988 * buffer in which to store the complete description. We need
17989 * the temporary buffer to be able to drop dtrace_lock()
17990 * across the copyout(), below.
17991 */
17992 size = sizeof (dtrace_aggdesc_t) +
17993 (aggdesc.dtagd_nrecs * sizeof (dtrace_recdesc_t));
17994
17995 buf = kmem_alloc(size, KM_SLEEP);
17996 dest = (uintptr_t)buf;
17997
17998 bcopy(&aggdesc, (void *)dest, sizeof (aggdesc));
17999 dest += offsetof(dtrace_aggdesc_t, dtagd_rec[0]);
18000
18001 for (act = agg->dtag_first; ; act = act->dta_next) {
18002 dtrace_recdesc_t rec = act->dta_rec;
18003
18004 /*
18005 * See the comment in the above loop for why we pass
18006 * over zero-length records.
18007 */
18008 if (rec.dtrd_size == 0) {
18009 ASSERT(agg->dtag_hasarg);
18010 continue;
18011 }
18012
18013 if (nrecs-- == 0)
18014 break;
18015
18016 rec.dtrd_offset -= offs;
18017 bcopy(&rec, (void *)dest, sizeof (rec));
18018 dest += sizeof (dtrace_recdesc_t);
18019
18020 if (act == &agg->dtag_action)
18021 break;
18022 }
18023
18024 lck_mtx_unlock(&dtrace_lock);
18025
18026 if (copyout(buf, arg, dest - (uintptr_t)buf) != 0) {
18027 kmem_free(buf, size);
18028 return (EFAULT);
18029 }
18030
18031 kmem_free(buf, size);
18032 return (0);
18033 }
18034
18035 case DTRACEIOC_ENABLE: {
18036 dof_hdr_t *dof;
18037 dtrace_enabling_t *enab = NULL;
18038 dtrace_vstate_t *vstate;
18039 int err = 0;
18040
18041 *rv = 0;
18042
18043 /*
18044 * If a NULL argument has been passed, we take this as our
18045 * cue to reevaluate our enablings.
18046 */
18047 if (arg == 0) {
18048 dtrace_enabling_matchall();
18049
18050 return (0);
18051 }
18052
18053 if ((dof = dtrace_dof_copyin(arg, &rval)) == NULL)
18054 return (rval);
18055
18056 lck_mtx_lock(&cpu_lock);
18057 lck_mtx_lock(&dtrace_lock);
18058 vstate = &state->dts_vstate;
18059
18060 if (state->dts_activity != DTRACE_ACTIVITY_INACTIVE) {
18061 lck_mtx_unlock(&dtrace_lock);
18062 lck_mtx_unlock(&cpu_lock);
18063 dtrace_dof_destroy(dof);
18064 return (EBUSY);
18065 }
18066
18067 if (dtrace_dof_slurp(dof, vstate, cr, &enab, 0, B_TRUE) != 0) {
18068 lck_mtx_unlock(&dtrace_lock);
18069 lck_mtx_unlock(&cpu_lock);
18070 dtrace_dof_destroy(dof);
18071 return (EINVAL);
18072 }
18073
18074 if ((rval = dtrace_dof_options(dof, state)) != 0) {
18075 dtrace_enabling_destroy(enab);
18076 lck_mtx_unlock(&dtrace_lock);
18077 lck_mtx_unlock(&cpu_lock);
18078 dtrace_dof_destroy(dof);
18079 return (rval);
18080 }
18081
18082 if ((err = dtrace_enabling_match(enab, rv, NULL)) == 0) {
18083 err = dtrace_enabling_retain(enab);
18084 } else {
18085 dtrace_enabling_destroy(enab);
18086 }
18087
18088 lck_mtx_unlock(&dtrace_lock);
18089 lck_mtx_unlock(&cpu_lock);
18090 dtrace_dof_destroy(dof);
18091
18092 return (err);
18093 }
18094
18095 case DTRACEIOC_REPLICATE: {
18096 dtrace_repldesc_t desc;
18097 dtrace_probedesc_t *match = &desc.dtrpd_match;
18098 dtrace_probedesc_t *create = &desc.dtrpd_create;
18099 int err;
18100
18101 if (copyin(arg, &desc, sizeof (desc)) != 0)
18102 return (EFAULT);
18103
18104 match->dtpd_provider[DTRACE_PROVNAMELEN - 1] = '\0';
18105 match->dtpd_mod[DTRACE_MODNAMELEN - 1] = '\0';
18106 match->dtpd_func[DTRACE_FUNCNAMELEN - 1] = '\0';
18107 match->dtpd_name[DTRACE_NAMELEN - 1] = '\0';
18108
18109 create->dtpd_provider[DTRACE_PROVNAMELEN - 1] = '\0';
18110 create->dtpd_mod[DTRACE_MODNAMELEN - 1] = '\0';
18111 create->dtpd_func[DTRACE_FUNCNAMELEN - 1] = '\0';
18112 create->dtpd_name[DTRACE_NAMELEN - 1] = '\0';
18113
18114 lck_mtx_lock(&dtrace_lock);
18115 err = dtrace_enabling_replicate(state, match, create);
18116 lck_mtx_unlock(&dtrace_lock);
18117
18118 return (err);
18119 }
18120
18121 case DTRACEIOC_PROBEMATCH:
18122 case DTRACEIOC_PROBES: {
18123 dtrace_probe_t *probe = NULL;
18124 dtrace_probedesc_t desc;
18125 dtrace_probekey_t pkey;
18126 dtrace_id_t i;
18127 int m = 0;
18128 uint32_t priv;
18129 uid_t uid;
18130 zoneid_t zoneid;
18131
18132 if (copyin(arg, &desc, sizeof (desc)) != 0)
18133 return (EFAULT);
18134
18135 desc.dtpd_provider[DTRACE_PROVNAMELEN - 1] = '\0';
18136 desc.dtpd_mod[DTRACE_MODNAMELEN - 1] = '\0';
18137 desc.dtpd_func[DTRACE_FUNCNAMELEN - 1] = '\0';
18138 desc.dtpd_name[DTRACE_NAMELEN - 1] = '\0';
18139
18140 /*
18141 * Before we attempt to match this probe, we want to give
18142 * all providers the opportunity to provide it.
18143 */
18144 if (desc.dtpd_id == DTRACE_IDNONE) {
18145 lck_mtx_lock(&dtrace_provider_lock);
18146 dtrace_probe_provide(&desc, NULL);
18147 lck_mtx_unlock(&dtrace_provider_lock);
18148 desc.dtpd_id++;
18149 }
18150
18151 dtrace_cred2priv(cr, &priv, &uid, &zoneid);
18152
18153 lck_mtx_lock(&dtrace_lock);
18154
18155 if (cmd == DTRACEIOC_PROBEMATCH) {
18156 dtrace_probekey(&desc, &pkey);
18157 pkey.dtpk_id = DTRACE_IDNONE;
18158
18159 /* Quiet compiler warning */
18160 for (i = desc.dtpd_id; i <= (dtrace_id_t)dtrace_nprobes; i++) {
18161 if ((probe = dtrace_probes[i - 1]) != NULL &&
18162 (m = dtrace_match_probe(probe, &pkey,
18163 priv, uid, zoneid)) != 0)
18164 break;
18165 }
18166
18167 if (m < 0) {
18168 lck_mtx_unlock(&dtrace_lock);
18169 return (EINVAL);
18170 }
18171 dtrace_probekey_release(&pkey);
18172
18173 } else {
18174 /* Quiet compiler warning */
18175 for (i = desc.dtpd_id; i <= (dtrace_id_t)dtrace_nprobes; i++) {
18176 if ((probe = dtrace_probes[i - 1]) != NULL &&
18177 dtrace_match_priv(probe, priv, uid, zoneid))
18178 break;
18179 }
18180 }
18181
18182 if (probe == NULL) {
18183 lck_mtx_unlock(&dtrace_lock);
18184 return (ESRCH);
18185 }
18186
18187 dtrace_probe_description(probe, &desc);
18188 lck_mtx_unlock(&dtrace_lock);
18189
18190 if (copyout(&desc, arg, sizeof (desc)) != 0)
18191 return (EFAULT);
18192
18193 return (0);
18194 }
18195
18196 case DTRACEIOC_PROBEARG: {
18197 dtrace_argdesc_t desc;
18198 dtrace_probe_t *probe;
18199 dtrace_provider_t *prov;
18200
18201 if (copyin(arg, &desc, sizeof (desc)) != 0)
18202 return (EFAULT);
18203
18204 if (desc.dtargd_id == DTRACE_IDNONE)
18205 return (EINVAL);
18206
18207 if (desc.dtargd_ndx == DTRACE_ARGNONE)
18208 return (EINVAL);
18209
18210 lck_mtx_lock(&dtrace_provider_lock);
18211 lck_mtx_lock(&mod_lock);
18212 lck_mtx_lock(&dtrace_lock);
18213
18214 /* Quiet compiler warning */
18215 if (desc.dtargd_id > (dtrace_id_t)dtrace_nprobes) {
18216 lck_mtx_unlock(&dtrace_lock);
18217 lck_mtx_unlock(&mod_lock);
18218 lck_mtx_unlock(&dtrace_provider_lock);
18219 return (EINVAL);
18220 }
18221
18222 if ((probe = dtrace_probes[desc.dtargd_id - 1]) == NULL) {
18223 lck_mtx_unlock(&dtrace_lock);
18224 lck_mtx_unlock(&mod_lock);
18225 lck_mtx_unlock(&dtrace_provider_lock);
18226 return (EINVAL);
18227 }
18228
18229 lck_mtx_unlock(&dtrace_lock);
18230
18231 prov = probe->dtpr_provider;
18232
18233 if (prov->dtpv_pops.dtps_getargdesc == NULL) {
18234 /*
18235 * There isn't any typed information for this probe.
18236 * Set the argument number to DTRACE_ARGNONE.
18237 */
18238 desc.dtargd_ndx = DTRACE_ARGNONE;
18239 } else {
18240 desc.dtargd_native[0] = '\0';
18241 desc.dtargd_xlate[0] = '\0';
18242 desc.dtargd_mapping = desc.dtargd_ndx;
18243
18244 prov->dtpv_pops.dtps_getargdesc(prov->dtpv_arg,
18245 probe->dtpr_id, probe->dtpr_arg, &desc);
18246 }
18247
18248 lck_mtx_unlock(&mod_lock);
18249 lck_mtx_unlock(&dtrace_provider_lock);
18250
18251 if (copyout(&desc, arg, sizeof (desc)) != 0)
18252 return (EFAULT);
18253
18254 return (0);
18255 }
18256
18257 case DTRACEIOC_GO: {
18258 processorid_t cpuid;
18259 rval = dtrace_state_go(state, &cpuid);
18260
18261 if (rval != 0)
18262 return (rval);
18263
18264 if (copyout(&cpuid, arg, sizeof (cpuid)) != 0)
18265 return (EFAULT);
18266
18267 return (0);
18268 }
18269
18270 case DTRACEIOC_STOP: {
18271 processorid_t cpuid;
18272
18273 lck_mtx_lock(&dtrace_lock);
18274 rval = dtrace_state_stop(state, &cpuid);
18275 lck_mtx_unlock(&dtrace_lock);
18276
18277 if (rval != 0)
18278 return (rval);
18279
18280 if (copyout(&cpuid, arg, sizeof (cpuid)) != 0)
18281 return (EFAULT);
18282
18283 return (0);
18284 }
18285
18286 case DTRACEIOC_DOFGET: {
18287 dof_hdr_t hdr, *dof;
18288 uint64_t len;
18289
18290 if (copyin(arg, &hdr, sizeof (hdr)) != 0)
18291 return (EFAULT);
18292
18293 lck_mtx_lock(&dtrace_lock);
18294 dof = dtrace_dof_create(state);
18295 lck_mtx_unlock(&dtrace_lock);
18296
18297 len = MIN(hdr.dofh_loadsz, dof->dofh_loadsz);
18298 rval = copyout(dof, arg, len);
18299 dtrace_dof_destroy(dof);
18300
18301 return (rval == 0 ? 0 : EFAULT);
18302 }
18303
18304 case DTRACEIOC_SLEEP: {
18305 int64_t time;
18306 uint64_t abstime;
18307 uint64_t rvalue = DTRACE_WAKE_TIMEOUT;
18308
18309 if (copyin(arg, &time, sizeof(time)) != 0)
18310 return (EFAULT);
18311
18312 nanoseconds_to_absolutetime((uint64_t)time, &abstime);
18313 clock_absolutetime_interval_to_deadline(abstime, &abstime);
18314
18315 if (assert_wait_deadline(state, THREAD_ABORTSAFE, abstime) == THREAD_WAITING) {
18316 if (state->dts_buf_over_limit > 0) {
18317 clear_wait(current_thread(), THREAD_INTERRUPTED);
18318 rvalue = DTRACE_WAKE_BUF_LIMIT;
18319 } else {
18320 thread_block(THREAD_CONTINUE_NULL);
18321 if (state->dts_buf_over_limit > 0) {
18322 rvalue = DTRACE_WAKE_BUF_LIMIT;
18323 }
18324 }
18325 }
18326
18327 if (copyout(&rvalue, arg, sizeof(rvalue)) != 0)
18328 return (EFAULT);
18329
18330 return (0);
18331 }
18332
18333 case DTRACEIOC_SIGNAL: {
18334 wakeup(state);
18335 return (0);
18336 }
18337
18338 case DTRACEIOC_AGGSNAP:
18339 case DTRACEIOC_BUFSNAP: {
18340 dtrace_bufdesc_t desc;
18341 caddr_t cached;
18342 boolean_t over_limit;
18343 dtrace_buffer_t *buf;
18344
18345 if (copyin(arg, &desc, sizeof (desc)) != 0)
18346 return (EFAULT);
18347
18348 if ((int)desc.dtbd_cpu < 0 || desc.dtbd_cpu >= NCPU)
18349 return (EINVAL);
18350
18351 lck_mtx_lock(&dtrace_lock);
18352
18353 if (cmd == DTRACEIOC_BUFSNAP) {
18354 buf = &state->dts_buffer[desc.dtbd_cpu];
18355 } else {
18356 buf = &state->dts_aggbuffer[desc.dtbd_cpu];
18357 }
18358
18359 if (buf->dtb_flags & (DTRACEBUF_RING | DTRACEBUF_FILL)) {
18360 size_t sz = buf->dtb_offset;
18361
18362 if (state->dts_activity != DTRACE_ACTIVITY_STOPPED) {
18363 lck_mtx_unlock(&dtrace_lock);
18364 return (EBUSY);
18365 }
18366
18367 /*
18368 * If this buffer has already been consumed, we're
18369 * going to indicate that there's nothing left here
18370 * to consume.
18371 */
18372 if (buf->dtb_flags & DTRACEBUF_CONSUMED) {
18373 lck_mtx_unlock(&dtrace_lock);
18374
18375 desc.dtbd_size = 0;
18376 desc.dtbd_drops = 0;
18377 desc.dtbd_errors = 0;
18378 desc.dtbd_oldest = 0;
18379 sz = sizeof (desc);
18380
18381 if (copyout(&desc, arg, sz) != 0)
18382 return (EFAULT);
18383
18384 return (0);
18385 }
18386
18387 /*
18388 * If this is a ring buffer that has wrapped, we want
18389 * to copy the whole thing out.
18390 */
18391 if (buf->dtb_flags & DTRACEBUF_WRAPPED) {
18392 dtrace_buffer_polish(buf);
18393 sz = buf->dtb_size;
18394 }
18395
18396 if (copyout(buf->dtb_tomax, (user_addr_t)desc.dtbd_data, sz) != 0) {
18397 lck_mtx_unlock(&dtrace_lock);
18398 return (EFAULT);
18399 }
18400
18401 desc.dtbd_size = sz;
18402 desc.dtbd_drops = buf->dtb_drops;
18403 desc.dtbd_errors = buf->dtb_errors;
18404 desc.dtbd_oldest = buf->dtb_xamot_offset;
18405 desc.dtbd_timestamp = dtrace_gethrtime();
18406
18407 lck_mtx_unlock(&dtrace_lock);
18408
18409 if (copyout(&desc, arg, sizeof (desc)) != 0)
18410 return (EFAULT);
18411
18412 buf->dtb_flags |= DTRACEBUF_CONSUMED;
18413
18414 return (0);
18415 }
18416
18417 if (buf->dtb_tomax == NULL) {
18418 ASSERT(buf->dtb_xamot == NULL);
18419 lck_mtx_unlock(&dtrace_lock);
18420 return (ENOENT);
18421 }
18422
18423 cached = buf->dtb_tomax;
18424 over_limit = buf->dtb_cur_limit == buf->dtb_size;
18425
18426 ASSERT(!(buf->dtb_flags & DTRACEBUF_NOSWITCH));
18427
18428 dtrace_xcall(desc.dtbd_cpu,
18429 (dtrace_xcall_t)dtrace_buffer_switch, buf);
18430
18431 state->dts_errors += buf->dtb_xamot_errors;
18432
18433 /*
18434 * If the buffers did not actually switch, then the cross call
18435 * did not take place -- presumably because the given CPU is
18436 * not in the ready set. If this is the case, we'll return
18437 * ENOENT.
18438 */
18439 if (buf->dtb_tomax == cached) {
18440 ASSERT(buf->dtb_xamot != cached);
18441 lck_mtx_unlock(&dtrace_lock);
18442 return (ENOENT);
18443 }
18444
18445 ASSERT(cached == buf->dtb_xamot);
18446 /*
18447 * At this point we know the buffer have switched, so we
18448 * can decrement the over limit count if the buffer was over
18449 * its limit. The new buffer might already be over its limit
18450 * yet, but we don't care since we're guaranteed not to be
18451 * checking the buffer over limit count at this point.
18452 */
18453 if (over_limit) {
18454 uint32_t old = os_atomic_dec_orig(&state->dts_buf_over_limit, relaxed);
18455 #pragma unused(old)
18456
18457 /*
18458 * Verify that we didn't underflow the value
18459 */
18460 ASSERT(old != 0);
18461 }
18462
18463 /*
18464 * We have our snapshot; now copy it out.
18465 */
18466 if (dtrace_buffer_copyout(buf->dtb_xamot,
18467 (user_addr_t)desc.dtbd_data,
18468 buf->dtb_xamot_offset) != 0) {
18469 lck_mtx_unlock(&dtrace_lock);
18470 return (EFAULT);
18471 }
18472
18473 desc.dtbd_size = buf->dtb_xamot_offset;
18474 desc.dtbd_drops = buf->dtb_xamot_drops;
18475 desc.dtbd_errors = buf->dtb_xamot_errors;
18476 desc.dtbd_oldest = 0;
18477 desc.dtbd_timestamp = buf->dtb_switched;
18478
18479 lck_mtx_unlock(&dtrace_lock);
18480
18481 /*
18482 * Finally, copy out the buffer description.
18483 */
18484 if (copyout(&desc, arg, sizeof (desc)) != 0)
18485 return (EFAULT);
18486
18487 return (0);
18488 }
18489
18490 case DTRACEIOC_CONF: {
18491 dtrace_conf_t conf;
18492
18493 bzero(&conf, sizeof (conf));
18494 conf.dtc_difversion = DIF_VERSION;
18495 conf.dtc_difintregs = DIF_DIR_NREGS;
18496 conf.dtc_diftupregs = DIF_DTR_NREGS;
18497 conf.dtc_ctfmodel = CTF_MODEL_NATIVE;
18498
18499 if (copyout(&conf, arg, sizeof (conf)) != 0)
18500 return (EFAULT);
18501
18502 return (0);
18503 }
18504
18505 case DTRACEIOC_STATUS: {
18506 dtrace_status_t stat;
18507 dtrace_dstate_t *dstate;
18508 int i, j;
18509 uint64_t nerrs;
18510
18511 /*
18512 * See the comment in dtrace_state_deadman() for the reason
18513 * for setting dts_laststatus to INT64_MAX before setting
18514 * it to the correct value.
18515 */
18516 state->dts_laststatus = INT64_MAX;
18517 dtrace_membar_producer();
18518 state->dts_laststatus = dtrace_gethrtime();
18519
18520 bzero(&stat, sizeof (stat));
18521
18522 lck_mtx_lock(&dtrace_lock);
18523
18524 if (state->dts_activity == DTRACE_ACTIVITY_INACTIVE) {
18525 lck_mtx_unlock(&dtrace_lock);
18526 return (ENOENT);
18527 }
18528
18529 if (state->dts_activity == DTRACE_ACTIVITY_DRAINING)
18530 stat.dtst_exiting = 1;
18531
18532 nerrs = state->dts_errors;
18533 dstate = &state->dts_vstate.dtvs_dynvars;
18534
18535 for (i = 0; i < (int)NCPU; i++) {
18536 dtrace_dstate_percpu_t *dcpu = &dstate->dtds_percpu[i];
18537
18538 stat.dtst_dyndrops += dcpu->dtdsc_drops;
18539 stat.dtst_dyndrops_dirty += dcpu->dtdsc_dirty_drops;
18540 stat.dtst_dyndrops_rinsing += dcpu->dtdsc_rinsing_drops;
18541
18542 if (state->dts_buffer[i].dtb_flags & DTRACEBUF_FULL)
18543 stat.dtst_filled++;
18544
18545 nerrs += state->dts_buffer[i].dtb_errors;
18546
18547 for (j = 0; j < state->dts_nspeculations; j++) {
18548 dtrace_speculation_t *spec;
18549 dtrace_buffer_t *buf;
18550
18551 spec = &state->dts_speculations[j];
18552 buf = &spec->dtsp_buffer[i];
18553 stat.dtst_specdrops += buf->dtb_xamot_drops;
18554 }
18555 }
18556
18557 stat.dtst_specdrops_busy = state->dts_speculations_busy;
18558 stat.dtst_specdrops_unavail = state->dts_speculations_unavail;
18559 stat.dtst_stkstroverflows = state->dts_stkstroverflows;
18560 stat.dtst_dblerrors = state->dts_dblerrors;
18561 stat.dtst_killed =
18562 (state->dts_activity == DTRACE_ACTIVITY_KILLED);
18563 stat.dtst_errors = nerrs;
18564
18565 lck_mtx_unlock(&dtrace_lock);
18566
18567 if (copyout(&stat, arg, sizeof (stat)) != 0)
18568 return (EFAULT);
18569
18570 return (0);
18571 }
18572
18573 case DTRACEIOC_FORMAT: {
18574 dtrace_fmtdesc_t fmt;
18575 char *str;
18576 int len;
18577
18578 if (copyin(arg, &fmt, sizeof (fmt)) != 0)
18579 return (EFAULT);
18580
18581 lck_mtx_lock(&dtrace_lock);
18582
18583 if (fmt.dtfd_format == 0 ||
18584 fmt.dtfd_format > state->dts_nformats) {
18585 lck_mtx_unlock(&dtrace_lock);
18586 return (EINVAL);
18587 }
18588
18589 /*
18590 * Format strings are allocated contiguously and they are
18591 * never freed; if a format index is less than the number
18592 * of formats, we can assert that the format map is non-NULL
18593 * and that the format for the specified index is non-NULL.
18594 */
18595 ASSERT(state->dts_formats != NULL);
18596 str = state->dts_formats[fmt.dtfd_format - 1]->dtf_str;
18597 ASSERT(str != NULL);
18598
18599 len = strlen(str) + 1;
18600
18601 if (len > fmt.dtfd_length) {
18602 fmt.dtfd_length = len;
18603
18604 if (copyout(&fmt, arg, sizeof (fmt)) != 0) {
18605 lck_mtx_unlock(&dtrace_lock);
18606 return (EINVAL);
18607 }
18608 } else {
18609 if (copyout(str, (user_addr_t)fmt.dtfd_string, len) != 0) {
18610 lck_mtx_unlock(&dtrace_lock);
18611 return (EINVAL);
18612 }
18613 }
18614
18615 lck_mtx_unlock(&dtrace_lock);
18616 return (0);
18617 }
18618
18619 case DTRACEIOC_MODUUIDSLIST: {
18620 size_t module_uuids_list_size;
18621 dtrace_module_uuids_list_t* uuids_list;
18622 uint64_t dtmul_count;
18623
18624 /*
18625 * Security restrictions make this operation illegal, if this is enabled DTrace
18626 * must refuse to provide any fbt probes.
18627 */
18628 if (dtrace_fbt_probes_restricted()) {
18629 cmn_err(CE_WARN, "security restrictions disallow DTRACEIOC_MODUUIDSLIST");
18630 return (EPERM);
18631 }
18632
18633 /*
18634 * Fail if the kernel symbol mode makes this operation illegal.
18635 * Both NEVER & ALWAYS_FROM_KERNEL are permanent states, it is legal to check
18636 * for them without holding the dtrace_lock.
18637 */
18638 if (dtrace_kernel_symbol_mode == DTRACE_KERNEL_SYMBOLS_NEVER ||
18639 dtrace_kernel_symbol_mode == DTRACE_KERNEL_SYMBOLS_ALWAYS_FROM_KERNEL) {
18640 cmn_err(CE_WARN, "dtrace_kernel_symbol_mode of %u disallows DTRACEIOC_MODUUIDSLIST", dtrace_kernel_symbol_mode);
18641 return (EPERM);
18642 }
18643
18644 /*
18645 * Read the number of symbolsdesc structs being passed in.
18646 */
18647 if (copyin(arg + offsetof(dtrace_module_uuids_list_t, dtmul_count),
18648 &dtmul_count,
18649 sizeof(dtmul_count))) {
18650 cmn_err(CE_WARN, "failed to copyin dtmul_count");
18651 return (EFAULT);
18652 }
18653
18654 /*
18655 * Range check the count. More than 2k kexts is probably an error.
18656 */
18657 if (dtmul_count > 2048) {
18658 cmn_err(CE_WARN, "dtmul_count is not valid");
18659 return (EINVAL);
18660 }
18661
18662 /*
18663 * For all queries, we return EINVAL when the user specified
18664 * count does not match the actual number of modules we find
18665 * available.
18666 *
18667 * If the user specified count is zero, then this serves as a
18668 * simple query to count the available modules in need of symbols.
18669 */
18670
18671 rval = 0;
18672
18673 if (dtmul_count == 0)
18674 {
18675 lck_mtx_lock(&mod_lock);
18676 struct modctl* ctl = dtrace_modctl_list;
18677 while (ctl) {
18678 ASSERT(!MOD_HAS_USERSPACE_SYMBOLS(ctl));
18679 if (!MOD_SYMBOLS_DONE(ctl) && !MOD_IS_STATIC_KEXT(ctl)) {
18680 dtmul_count++;
18681 rval = EINVAL;
18682 }
18683 ctl = ctl->mod_next;
18684 }
18685 lck_mtx_unlock(&mod_lock);
18686
18687 if (copyout(&dtmul_count, arg, sizeof (dtmul_count)) != 0)
18688 return (EFAULT);
18689 else
18690 return (rval);
18691 }
18692
18693 /*
18694 * If we reach this point, then we have a request for full list data.
18695 * Allocate a correctly sized structure and copyin the data.
18696 */
18697 module_uuids_list_size = DTRACE_MODULE_UUIDS_LIST_SIZE(dtmul_count);
18698 if ((uuids_list = kmem_alloc(module_uuids_list_size, KM_SLEEP)) == NULL)
18699 return (ENOMEM);
18700
18701 /* NOTE! We can no longer exit this method via return */
18702 if (copyin(arg, uuids_list, module_uuids_list_size) != 0) {
18703 cmn_err(CE_WARN, "failed copyin of dtrace_module_uuids_list_t");
18704 rval = EFAULT;
18705 goto moduuidslist_cleanup;
18706 }
18707
18708 /*
18709 * Check that the count didn't change between the first copyin and the second.
18710 */
18711 if (uuids_list->dtmul_count != dtmul_count) {
18712 rval = EINVAL;
18713 goto moduuidslist_cleanup;
18714 }
18715
18716 /*
18717 * Build the list of UUID's that need symbols
18718 */
18719 lck_mtx_lock(&mod_lock);
18720
18721 dtmul_count = 0;
18722
18723 struct modctl* ctl = dtrace_modctl_list;
18724 while (ctl) {
18725 /*
18726 * We assume that userspace symbols will be "better" than kernel level symbols,
18727 * as userspace can search for dSYM(s) and symbol'd binaries. Even if kernel syms
18728 * are available, add user syms if the module might use them.
18729 */
18730 ASSERT(!MOD_HAS_USERSPACE_SYMBOLS(ctl));
18731 if (!MOD_SYMBOLS_DONE(ctl) && !MOD_IS_STATIC_KEXT(ctl)) {
18732 UUID* uuid = &uuids_list->dtmul_uuid[dtmul_count];
18733 if (dtmul_count++ < uuids_list->dtmul_count) {
18734 memcpy(uuid, ctl->mod_uuid, sizeof(UUID));
18735 }
18736 }
18737 ctl = ctl->mod_next;
18738 }
18739
18740 lck_mtx_unlock(&mod_lock);
18741
18742 if (uuids_list->dtmul_count < dtmul_count)
18743 rval = EINVAL;
18744
18745 uuids_list->dtmul_count = dtmul_count;
18746
18747 /*
18748 * Copyout the symbols list (or at least the count!)
18749 */
18750 if (copyout(uuids_list, arg, module_uuids_list_size) != 0) {
18751 cmn_err(CE_WARN, "failed copyout of dtrace_symbolsdesc_list_t");
18752 rval = EFAULT;
18753 }
18754
18755 moduuidslist_cleanup:
18756 /*
18757 * If we had to allocate struct memory, free it.
18758 */
18759 if (uuids_list != NULL) {
18760 kmem_free(uuids_list, module_uuids_list_size);
18761 }
18762
18763 return rval;
18764 }
18765
18766 case DTRACEIOC_PROVMODSYMS: {
18767 size_t module_symbols_size;
18768 dtrace_module_symbols_t* module_symbols;
18769 uint64_t dtmodsyms_count;
18770
18771 /*
18772 * Security restrictions make this operation illegal, if this is enabled DTrace
18773 * must refuse to provide any fbt probes.
18774 */
18775 if (dtrace_fbt_probes_restricted()) {
18776 cmn_err(CE_WARN, "security restrictions disallow DTRACEIOC_MODUUIDSLIST");
18777 return (EPERM);
18778 }
18779
18780 /*
18781 * Fail if the kernel symbol mode makes this operation illegal.
18782 * Both NEVER & ALWAYS_FROM_KERNEL are permanent states, it is legal to check
18783 * for them without holding the dtrace_lock.
18784 */
18785 if (dtrace_kernel_symbol_mode == DTRACE_KERNEL_SYMBOLS_NEVER ||
18786 dtrace_kernel_symbol_mode == DTRACE_KERNEL_SYMBOLS_ALWAYS_FROM_KERNEL) {
18787 cmn_err(CE_WARN, "dtrace_kernel_symbol_mode of %u disallows DTRACEIOC_PROVMODSYMS", dtrace_kernel_symbol_mode);
18788 return (EPERM);
18789 }
18790
18791 /*
18792 * Read the number of module symbols structs being passed in.
18793 */
18794 if (copyin(arg + offsetof(dtrace_module_symbols_t, dtmodsyms_count),
18795 &dtmodsyms_count,
18796 sizeof(dtmodsyms_count))) {
18797 cmn_err(CE_WARN, "failed to copyin dtmodsyms_count");
18798 return (EFAULT);
18799 }
18800
18801 /* Ensure that we have at least one symbol. */
18802 if (dtmodsyms_count == 0) {
18803 cmn_err(CE_WARN, "Invalid dtmodsyms_count value");
18804 return (EINVAL);
18805 }
18806
18807 /* Safely calculate size we need for copyin buffer. */
18808 module_symbols_size = DTRACE_MODULE_SYMBOLS_SIZE(dtmodsyms_count);
18809 if (module_symbols_size == 0 || module_symbols_size > (size_t)dtrace_copy_maxsize()) {
18810 cmn_err(CE_WARN, "Invalid module_symbols_size %ld", module_symbols_size);
18811 return (EINVAL);
18812 }
18813
18814 if ((module_symbols = kmem_alloc(module_symbols_size, KM_SLEEP)) == NULL)
18815 return (ENOMEM);
18816
18817 rval = 0;
18818
18819 /* NOTE! We can no longer exit this method via return */
18820 if (copyin(arg, module_symbols, module_symbols_size) != 0) {
18821 cmn_err(CE_WARN, "failed copyin of dtrace_module_symbols_t");
18822 rval = EFAULT;
18823 goto module_symbols_cleanup;
18824 }
18825
18826 /*
18827 * Check that the count didn't change between the first copyin and the second.
18828 */
18829 if (module_symbols->dtmodsyms_count != dtmodsyms_count) {
18830 rval = EINVAL;
18831 goto module_symbols_cleanup;
18832 }
18833
18834 /*
18835 * Find the modctl to add symbols to.
18836 */
18837 lck_mtx_lock(&dtrace_provider_lock);
18838 lck_mtx_lock(&mod_lock);
18839
18840 struct modctl* ctl = dtrace_modctl_list;
18841 while (ctl) {
18842 ASSERT(!MOD_HAS_USERSPACE_SYMBOLS(ctl));
18843 if (MOD_HAS_UUID(ctl) && !MOD_SYMBOLS_DONE(ctl) && memcmp(module_symbols->dtmodsyms_uuid, ctl->mod_uuid, sizeof(UUID)) == 0) {
18844 dtrace_provider_t *prv;
18845 ctl->mod_user_symbols = module_symbols;
18846
18847 /*
18848 * We're going to call each providers per-module provide operation
18849 * specifying only this module.
18850 */
18851 for (prv = dtrace_provider; prv != NULL; prv = prv->dtpv_next)
18852 prv->dtpv_pops.dtps_provide_module(prv->dtpv_arg, ctl);
18853 /*
18854 * We gave every provider a chance to provide with the user syms, go ahead and clear them
18855 */
18856 ctl->mod_user_symbols = NULL; /* MUST reset this to clear HAS_USERSPACE_SYMBOLS */
18857 }
18858 ctl = ctl->mod_next;
18859 }
18860
18861 lck_mtx_unlock(&mod_lock);
18862 lck_mtx_unlock(&dtrace_provider_lock);
18863
18864 module_symbols_cleanup:
18865 /*
18866 * If we had to allocate struct memory, free it.
18867 */
18868 if (module_symbols != NULL) {
18869 kmem_free(module_symbols, module_symbols_size);
18870 }
18871
18872 return rval;
18873 }
18874
18875 case DTRACEIOC_PROCWAITFOR: {
18876 dtrace_procdesc_t pdesc = {
18877 .p_name = {0},
18878 .p_pid = -1
18879 };
18880
18881 if ((rval = copyin(arg, &pdesc, sizeof(pdesc))) != 0)
18882 goto proc_waitfor_error;
18883
18884 if ((rval = dtrace_proc_waitfor(&pdesc)) != 0)
18885 goto proc_waitfor_error;
18886
18887 if ((rval = copyout(&pdesc, arg, sizeof(pdesc))) != 0)
18888 goto proc_waitfor_error;
18889
18890 return 0;
18891
18892 proc_waitfor_error:
18893 /* The process was suspended, revert this since the client will not do it. */
18894 if (pdesc.p_pid != -1) {
18895 proc_t *proc = proc_find(pdesc.p_pid);
18896 if (proc != PROC_NULL) {
18897 task_pidresume(proc->task);
18898 proc_rele(proc);
18899 }
18900 }
18901
18902 return rval;
18903 }
18904
18905 default:
18906 break;
18907 }
18908
18909 return (ENOTTY);
18910 }
18911
18912 /*
18913 * APPLE NOTE: dtrace_detach not implemented
18914 */
18915 #if !defined(__APPLE__)
18916 /*ARGSUSED*/
18917 static int
dtrace_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)18918 dtrace_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
18919 {
18920 dtrace_state_t *state;
18921
18922 switch (cmd) {
18923 case DDI_DETACH:
18924 break;
18925
18926 case DDI_SUSPEND:
18927 return (DDI_SUCCESS);
18928
18929 default:
18930 return (DDI_FAILURE);
18931 }
18932
18933 lck_mtx_lock(&cpu_lock);
18934 lck_mtx_lock(&dtrace_provider_lock);
18935 lck_mtx_lock(&dtrace_lock);
18936
18937 ASSERT(dtrace_opens == 0);
18938
18939 if (dtrace_helpers > 0) {
18940 lck_mtx_unlock(&dtrace_lock);
18941 lck_mtx_unlock(&dtrace_provider_lock);
18942 lck_mtx_unlock(&cpu_lock);
18943 return (DDI_FAILURE);
18944 }
18945
18946 if (dtrace_unregister((dtrace_provider_id_t)dtrace_provider) != 0) {
18947 lck_mtx_unlock(&dtrace_lock);
18948 lck_mtx_unlock(&dtrace_provider_lock);
18949 lck_mtx_unlock(&cpu_lock);
18950 return (DDI_FAILURE);
18951 }
18952
18953 dtrace_provider = NULL;
18954
18955 if ((state = dtrace_anon_grab()) != NULL) {
18956 /*
18957 * If there were ECBs on this state, the provider should
18958 * have not been allowed to detach; assert that there is
18959 * none.
18960 */
18961 ASSERT(state->dts_necbs == 0);
18962 dtrace_state_destroy(state);
18963
18964 /*
18965 * If we're being detached with anonymous state, we need to
18966 * indicate to the kernel debugger that DTrace is now inactive.
18967 */
18968 (void) kdi_dtrace_set(KDI_DTSET_DTRACE_DEACTIVATE);
18969 }
18970
18971 bzero(&dtrace_anon, sizeof (dtrace_anon_t));
18972 unregister_cpu_setup_func((cpu_setup_func_t *)dtrace_cpu_setup, NULL);
18973 dtrace_cpu_init = NULL;
18974 dtrace_helpers_cleanup = NULL;
18975 dtrace_helpers_fork = NULL;
18976 dtrace_cpustart_init = NULL;
18977 dtrace_cpustart_fini = NULL;
18978 dtrace_debugger_init = NULL;
18979 dtrace_debugger_fini = NULL;
18980 dtrace_kreloc_init = NULL;
18981 dtrace_kreloc_fini = NULL;
18982 dtrace_modload = NULL;
18983 dtrace_modunload = NULL;
18984
18985 lck_mtx_unlock(&cpu_lock);
18986
18987 if (dtrace_helptrace_enabled) {
18988 kmem_free(dtrace_helptrace_buffer, dtrace_helptrace_bufsize);
18989 dtrace_helptrace_buffer = NULL;
18990 }
18991
18992 kmem_free(dtrace_probes, dtrace_nprobes * sizeof (dtrace_probe_t *));
18993 dtrace_probes = NULL;
18994 dtrace_nprobes = 0;
18995
18996 dtrace_hash_destroy(dtrace_strings);
18997 dtrace_hash_destroy(dtrace_byprov);
18998 dtrace_hash_destroy(dtrace_bymod);
18999 dtrace_hash_destroy(dtrace_byfunc);
19000 dtrace_hash_destroy(dtrace_byname);
19001 dtrace_strings = NULL;
19002 dtrace_byprov = NULL;
19003 dtrace_bymod = NULL;
19004 dtrace_byfunc = NULL;
19005 dtrace_byname = NULL;
19006
19007 kmem_cache_destroy(dtrace_state_cache);
19008 vmem_destroy(dtrace_arena);
19009
19010 if (dtrace_toxrange != NULL) {
19011 kmem_free(dtrace_toxrange,
19012 dtrace_toxranges_max * sizeof (dtrace_toxrange_t));
19013 dtrace_toxrange = NULL;
19014 dtrace_toxranges = 0;
19015 dtrace_toxranges_max = 0;
19016 }
19017
19018 ddi_remove_minor_node(dtrace_devi, NULL);
19019 dtrace_devi = NULL;
19020
19021 ddi_soft_state_fini(&dtrace_softstate);
19022
19023 ASSERT(dtrace_vtime_references == 0);
19024 ASSERT(dtrace_opens == 0);
19025 ASSERT(dtrace_retained == NULL);
19026
19027 lck_mtx_unlock(&dtrace_lock);
19028 lck_mtx_unlock(&dtrace_provider_lock);
19029
19030 #ifdef illumos
19031 /*
19032 * We don't destroy the task queue until after we have dropped our
19033 * locks (taskq_destroy() may block on running tasks). To prevent
19034 * attempting to do work after we have effectively detached but before
19035 * the task queue has been destroyed, all tasks dispatched via the
19036 * task queue must check that DTrace is still attached before
19037 * performing any operation.
19038 */
19039 taskq_destroy(dtrace_taskq);
19040 dtrace_taskq = NULL;
19041 #endif
19042
19043 return (DDI_SUCCESS);
19044 }
19045 #endif /* __APPLE__ */
19046
19047 d_open_t _dtrace_open, helper_open;
19048 d_close_t _dtrace_close, helper_close;
19049 d_ioctl_t _dtrace_ioctl, helper_ioctl;
19050
19051 int
_dtrace_open(dev_t dev,int flags,int devtype,struct proc * p)19052 _dtrace_open(dev_t dev, int flags, int devtype, struct proc *p)
19053 {
19054 #pragma unused(p)
19055 dev_t locdev = dev;
19056
19057 return dtrace_open( &locdev, flags, devtype, CRED());
19058 }
19059
19060 int
helper_open(dev_t dev,int flags,int devtype,struct proc * p)19061 helper_open(dev_t dev, int flags, int devtype, struct proc *p)
19062 {
19063 #pragma unused(dev,flags,devtype,p)
19064 return 0;
19065 }
19066
19067 int
_dtrace_close(dev_t dev,int flags,int devtype,struct proc * p)19068 _dtrace_close(dev_t dev, int flags, int devtype, struct proc *p)
19069 {
19070 #pragma unused(p)
19071 return dtrace_close( dev, flags, devtype, CRED());
19072 }
19073
19074 int
helper_close(dev_t dev,int flags,int devtype,struct proc * p)19075 helper_close(dev_t dev, int flags, int devtype, struct proc *p)
19076 {
19077 #pragma unused(dev,flags,devtype,p)
19078 return 0;
19079 }
19080
19081 int
_dtrace_ioctl(dev_t dev,u_long cmd,caddr_t data,int fflag,struct proc * p)19082 _dtrace_ioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p)
19083 {
19084 #pragma unused(p)
19085 int err, rv = 0;
19086 user_addr_t uaddrp;
19087
19088 if (proc_is64bit(p))
19089 uaddrp = *(user_addr_t *)data;
19090 else
19091 uaddrp = (user_addr_t) *(uint32_t *)data;
19092
19093 err = dtrace_ioctl(dev, cmd, uaddrp, fflag, CRED(), &rv);
19094
19095 /* Darwin's BSD ioctls only return -1 or zero. Overload errno to mimic Solaris. 20 bits suffice. */
19096 if (err != 0) {
19097 ASSERT( (err & 0xfffff000) == 0 );
19098 return (err & 0xfff); /* ioctl will return -1 and will set errno to an error code < 4096 */
19099 } else if (rv != 0) {
19100 ASSERT( (rv & 0xfff00000) == 0 );
19101 return (((rv & 0xfffff) << 12)); /* ioctl will return -1 and will set errno to a value >= 4096 */
19102 } else
19103 return 0;
19104 }
19105
19106 int
helper_ioctl(dev_t dev,u_long cmd,caddr_t data,int fflag,struct proc * p)19107 helper_ioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p)
19108 {
19109 #pragma unused(dev,fflag,p)
19110 int err, rv = 0;
19111
19112 err = dtrace_ioctl_helper(cmd, data, &rv);
19113 /* Darwin's BSD ioctls only return -1 or zero. Overload errno to mimic Solaris. 20 bits suffice. */
19114 if (err != 0) {
19115 ASSERT( (err & 0xfffff000) == 0 );
19116 return (err & 0xfff); /* ioctl will return -1 and will set errno to an error code < 4096 */
19117 } else if (rv != 0) {
19118 ASSERT( (rv & 0xfff00000) == 0 );
19119 return (((rv & 0xfffff) << 12)); /* ioctl will return -1 and will set errno to a value >= 4096 */
19120 } else
19121 return 0;
19122 }
19123
19124 #define HELPER_MAJOR -24 /* let the kernel pick the device number */
19125
19126 const static struct cdevsw helper_cdevsw =
19127 {
19128 .d_open = helper_open,
19129 .d_close = helper_close,
19130 .d_read = eno_rdwrt,
19131 .d_write = eno_rdwrt,
19132 .d_ioctl = helper_ioctl,
19133 .d_stop = (stop_fcn_t *)nulldev,
19134 .d_reset = (reset_fcn_t *)nulldev,
19135 .d_select = eno_select,
19136 .d_mmap = eno_mmap,
19137 .d_strategy = eno_strat,
19138 .d_reserved_1 = eno_getc,
19139 .d_reserved_2 = eno_putc,
19140 };
19141
19142 static int helper_majdevno = 0;
19143
19144 static int gDTraceInited = 0;
19145
19146 void
helper_init(void)19147 helper_init( void )
19148 {
19149 /*
19150 * Once the "helper" is initialized, it can take ioctl calls that use locks
19151 * and zones initialized in dtrace_init. Make certain dtrace_init was called
19152 * before us.
19153 */
19154
19155 if (!gDTraceInited) {
19156 panic("helper_init before dtrace_init");
19157 }
19158
19159 if (0 >= helper_majdevno)
19160 {
19161 helper_majdevno = cdevsw_add(HELPER_MAJOR, &helper_cdevsw);
19162
19163 if (helper_majdevno < 0) {
19164 printf("helper_init: failed to allocate a major number!\n");
19165 return;
19166 }
19167
19168 if (NULL == devfs_make_node( makedev(helper_majdevno, 0), DEVFS_CHAR, UID_ROOT, GID_WHEEL, 0666,
19169 DTRACEMNR_HELPER, 0 )) {
19170 printf("dtrace_init: failed to devfs_make_node for helper!\n");
19171 return;
19172 }
19173 } else
19174 panic("helper_init: called twice!");
19175 }
19176
19177 #undef HELPER_MAJOR
19178
19179 static int
dtrace_clone_func(dev_t dev,int action)19180 dtrace_clone_func(dev_t dev, int action)
19181 {
19182 #pragma unused(dev)
19183
19184 if (action == DEVFS_CLONE_ALLOC) {
19185 return dtrace_state_reserve();
19186 }
19187 else if (action == DEVFS_CLONE_FREE) {
19188 return 0;
19189 }
19190 else return -1;
19191 }
19192
19193 void dtrace_ast(void);
19194
19195 void
dtrace_ast(void)19196 dtrace_ast(void)
19197 {
19198 int i;
19199 uint32_t clients = os_atomic_xchg(&dtrace_wake_clients, 0, relaxed);
19200 if (clients == 0)
19201 return;
19202 /**
19203 * We disable preemption here to be sure that we won't get
19204 * interrupted by a wakeup to a thread that is higher
19205 * priority than us, so that we do issue all wakeups
19206 */
19207 disable_preemption();
19208 for (i = 0; i < DTRACE_NCLIENTS; i++) {
19209 if (clients & (1 << i)) {
19210 dtrace_state_t *state = dtrace_state_get(i);
19211 if (state) {
19212 wakeup(state);
19213 }
19214
19215 }
19216 }
19217 enable_preemption();
19218 }
19219
19220
19221 #define DTRACE_MAJOR -24 /* let the kernel pick the device number */
19222
19223 static const struct cdevsw dtrace_cdevsw =
19224 {
19225 .d_open = _dtrace_open,
19226 .d_close = _dtrace_close,
19227 .d_read = eno_rdwrt,
19228 .d_write = eno_rdwrt,
19229 .d_ioctl = _dtrace_ioctl,
19230 .d_stop = (stop_fcn_t *)nulldev,
19231 .d_reset = (reset_fcn_t *)nulldev,
19232 .d_select = eno_select,
19233 .d_mmap = eno_mmap,
19234 .d_strategy = eno_strat,
19235 .d_reserved_1 = eno_getc,
19236 .d_reserved_2 = eno_putc,
19237 };
19238
19239 LCK_ATTR_DECLARE(dtrace_lck_attr, 0, 0);
19240 LCK_GRP_DECLARE(dtrace_lck_grp, "dtrace");
19241
19242 static int gMajDevNo;
19243
dtrace_early_init(void)19244 void dtrace_early_init (void)
19245 {
19246 dtrace_restriction_policy_load();
19247
19248 /*
19249 * See dtrace_impl.h for a description of kernel symbol modes.
19250 * The default is to wait for symbols from userspace (lazy symbols).
19251 */
19252 if (!PE_parse_boot_argn("dtrace_kernel_symbol_mode", &dtrace_kernel_symbol_mode, sizeof (dtrace_kernel_symbol_mode))) {
19253 dtrace_kernel_symbol_mode = DTRACE_KERNEL_SYMBOLS_FROM_USERSPACE;
19254 }
19255 }
19256
19257 void
dtrace_init(void)19258 dtrace_init( void )
19259 {
19260 if (0 == gDTraceInited) {
19261 unsigned int i, ncpu;
19262 size_t size = sizeof(dtrace_buffer_memory_maxsize);
19263
19264 /*
19265 * Disable destructive actions when dtrace is running
19266 * in a restricted environment
19267 */
19268 dtrace_destructive_disallow = dtrace_is_restricted() &&
19269 !dtrace_are_restrictions_relaxed();
19270
19271 /*
19272 * DTrace allocates buffers based on the maximum number
19273 * of enabled cpus. This call avoids any race when finding
19274 * that count.
19275 */
19276 ASSERT(dtrace_max_cpus == 0);
19277 ncpu = dtrace_max_cpus = ml_wait_max_cpus();
19278
19279 /*
19280 * Retrieve the size of the physical memory in order to define
19281 * the state buffer memory maximal size. If we cannot retrieve
19282 * this value, we'll consider that we have 1Gb of memory per CPU, that's
19283 * still better than raising a kernel panic.
19284 */
19285 if (0 != kernel_sysctlbyname("hw.memsize", &dtrace_buffer_memory_maxsize,
19286 &size, NULL, 0))
19287 {
19288 dtrace_buffer_memory_maxsize = ncpu * 1024 * 1024 * 1024;
19289 printf("dtrace_init: failed to retrieve the hw.memsize, defaulted to %lld bytes\n",
19290 dtrace_buffer_memory_maxsize);
19291 }
19292
19293 /*
19294 * Finally, divide by three to prevent DTrace from eating too
19295 * much memory.
19296 */
19297 dtrace_buffer_memory_maxsize /= 3;
19298 ASSERT(dtrace_buffer_memory_maxsize > 0);
19299
19300 gMajDevNo = cdevsw_add(DTRACE_MAJOR, &dtrace_cdevsw);
19301
19302 if (gMajDevNo < 0) {
19303 printf("dtrace_init: failed to allocate a major number!\n");
19304 gDTraceInited = 0;
19305 return;
19306 }
19307
19308 if (NULL == devfs_make_node_clone( makedev(gMajDevNo, 0), DEVFS_CHAR, UID_ROOT, GID_WHEEL, 0666,
19309 dtrace_clone_func, DTRACEMNR_DTRACE, 0 )) {
19310 printf("dtrace_init: failed to devfs_make_node_clone for dtrace!\n");
19311 gDTraceInited = 0;
19312 return;
19313 }
19314
19315 /*
19316 * The cpu_core structure consists of per-CPU state available in any context.
19317 * On some architectures, this may mean that the page(s) containing the
19318 * NCPU-sized array of cpu_core structures must be locked in the TLB -- it
19319 * is up to the platform to assure that this is performed properly. Note that
19320 * the structure is sized to avoid false sharing.
19321 */
19322
19323 /*
19324 * Initialize the CPU offline/online hooks.
19325 */
19326 dtrace_install_cpu_hooks();
19327
19328 dtrace_modctl_list = NULL;
19329
19330 cpu_core = (cpu_core_t *)kmem_zalloc( ncpu * sizeof(cpu_core_t), KM_SLEEP );
19331 for (i = 0; i < ncpu; ++i) {
19332 lck_mtx_init(&cpu_core[i].cpuc_pid_lock, &dtrace_lck_grp, &dtrace_lck_attr);
19333 }
19334
19335 cpu_list = (dtrace_cpu_t *)kmem_zalloc( ncpu * sizeof(dtrace_cpu_t), KM_SLEEP );
19336 for (i = 0; i < ncpu; ++i) {
19337 cpu_list[i].cpu_id = (processorid_t)i;
19338 cpu_list[i].cpu_next = &(cpu_list[(i+1) % ncpu]);
19339 LIST_INIT(&cpu_list[i].cpu_cyc_list);
19340 lck_rw_init(&cpu_list[i].cpu_ft_lock, &dtrace_lck_grp, &dtrace_lck_attr);
19341 }
19342
19343 lck_mtx_lock(&cpu_lock);
19344 for (i = 0; i < ncpu; ++i)
19345 /* FIXME: track CPU configuration */
19346 dtrace_cpu_setup_initial( (processorid_t)i ); /* In lieu of register_cpu_setup_func() callback */
19347 lck_mtx_unlock(&cpu_lock);
19348
19349 (void)dtrace_abs_to_nano(0LL); /* Force once only call to clock_timebase_info (which can take a lock) */
19350
19351 dtrace_strings = dtrace_hash_create(dtrace_strkey_offset,
19352 offsetof(dtrace_string_t, dtst_str),
19353 offsetof(dtrace_string_t, dtst_next),
19354 offsetof(dtrace_string_t, dtst_prev));
19355
19356 /*
19357 * See dtrace_impl.h for a description of dof modes.
19358 * The default is lazy dof.
19359 *
19360 * FIXME: Warn if state is LAZY_OFF? It won't break anything, but
19361 * makes no sense...
19362 */
19363 if (!PE_parse_boot_argn("dtrace_dof_mode", &dtrace_dof_mode, sizeof (dtrace_dof_mode))) {
19364 #if defined(XNU_TARGET_OS_OSX)
19365 dtrace_dof_mode = DTRACE_DOF_MODE_LAZY_ON;
19366 #else
19367 dtrace_dof_mode = DTRACE_DOF_MODE_NEVER;
19368 #endif
19369 }
19370
19371 /*
19372 * Sanity check of dof mode value.
19373 */
19374 switch (dtrace_dof_mode) {
19375 case DTRACE_DOF_MODE_NEVER:
19376 case DTRACE_DOF_MODE_LAZY_ON:
19377 /* valid modes, but nothing else we need to do */
19378 break;
19379
19380 case DTRACE_DOF_MODE_LAZY_OFF:
19381 case DTRACE_DOF_MODE_NON_LAZY:
19382 /* Cannot wait for a dtrace_open to init fasttrap */
19383 fasttrap_init();
19384 break;
19385
19386 default:
19387 /* Invalid, clamp to non lazy */
19388 dtrace_dof_mode = DTRACE_DOF_MODE_NON_LAZY;
19389 fasttrap_init();
19390 break;
19391 }
19392
19393 #if CONFIG_DTRACE
19394 if (dtrace_dof_mode != DTRACE_DOF_MODE_NEVER)
19395 commpage_update_dof(true);
19396 #endif
19397
19398 gDTraceInited = 1;
19399
19400 } else
19401 panic("dtrace_init: called twice!");
19402 }
19403
19404 void
dtrace_postinit(void)19405 dtrace_postinit(void)
19406 {
19407 /*
19408 * Called from bsd_init after all provider's *_init() routines have been
19409 * run. That way, anonymous DOF enabled under dtrace_attach() is safe
19410 * to go.
19411 */
19412 dtrace_attach( (dev_info_t *)(uintptr_t)makedev(gMajDevNo, 0)); /* Punning a dev_t to a dev_info_t* */
19413
19414 /*
19415 * Add the mach_kernel to the module list for lazy processing
19416 */
19417 struct kmod_info fake_kernel_kmod;
19418 memset(&fake_kernel_kmod, 0, sizeof(fake_kernel_kmod));
19419
19420 strlcpy(fake_kernel_kmod.name, "mach_kernel", sizeof(fake_kernel_kmod.name));
19421 fake_kernel_kmod.id = 1;
19422 fake_kernel_kmod.address = g_kernel_kmod_info.address;
19423 fake_kernel_kmod.size = g_kernel_kmod_info.size;
19424
19425 /* Ensure we don't try to touch symbols if they are gone. */
19426 boolean_t keepsyms = false;
19427 PE_parse_boot_argn("keepsyms", &keepsyms, sizeof(keepsyms));
19428
19429 if (dtrace_module_loaded(&fake_kernel_kmod, (keepsyms) ? 0 : KMOD_DTRACE_NO_KERNEL_SYMS) != 0) {
19430 printf("dtrace_postinit: Could not register mach_kernel modctl\n");
19431 }
19432
19433 (void)OSKextRegisterKextsWithDTrace();
19434 }
19435 #undef DTRACE_MAJOR
19436
19437 /*
19438 * Routines used to register interest in cpu's being added to or removed
19439 * from the system.
19440 */
19441 void
register_cpu_setup_func(cpu_setup_func_t * ignore1,void * ignore2)19442 register_cpu_setup_func(cpu_setup_func_t *ignore1, void *ignore2)
19443 {
19444 #pragma unused(ignore1,ignore2)
19445 }
19446
19447 void
unregister_cpu_setup_func(cpu_setup_func_t * ignore1,void * ignore2)19448 unregister_cpu_setup_func(cpu_setup_func_t *ignore1, void *ignore2)
19449 {
19450 #pragma unused(ignore1,ignore2)
19451 }
19452