xref: /freebsd/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c (revision 4e99f45480598189d49d45a825533a6c9e12f02c)
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  * Portions Copyright 2010 The FreeBSD Foundation
22  *
23  * $FreeBSD$
24  */
25 
26 /*
27  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
28  * Use is subject to license terms.
29  */
30 
31 /*
32  * Copyright (c) 2015, Joyent, Inc. All rights reserved.
33  */
34 
35 #include <sys/atomic.h>
36 #include <sys/errno.h>
37 #include <sys/stat.h>
38 #include <sys/modctl.h>
39 #include <sys/conf.h>
40 #include <sys/systm.h>
41 #ifdef illumos
42 #include <sys/ddi.h>
43 #endif
44 #include <sys/sunddi.h>
45 #include <sys/cpuvar.h>
46 #include <sys/kmem.h>
47 #ifdef illumos
48 #include <sys/strsubr.h>
49 #endif
50 #include <sys/fasttrap.h>
51 #include <sys/fasttrap_impl.h>
52 #include <sys/fasttrap_isa.h>
53 #include <sys/dtrace.h>
54 #include <sys/dtrace_impl.h>
55 #include <sys/sysmacros.h>
56 #include <sys/proc.h>
57 #include <sys/policy.h>
58 #ifdef illumos
59 #include <util/qsort.h>
60 #endif
61 #include <sys/mutex.h>
62 #include <sys/kernel.h>
63 #ifndef illumos
64 #include <sys/dtrace_bsd.h>
65 #include <sys/eventhandler.h>
66 #include <sys/rmlock.h>
67 #include <sys/sysent.h>
68 #include <sys/sysctl.h>
69 #include <sys/u8_textprep.h>
70 #include <sys/user.h>
71 
72 #include <vm/vm.h>
73 #include <vm/pmap.h>
74 #include <vm/vm_map.h>
75 #include <vm/vm_param.h>
76 
77 #include <cddl/dev/dtrace/dtrace_cddl.h>
78 #endif
79 
80 /*
81  * User-Land Trap-Based Tracing
82  * ----------------------------
83  *
84  * The fasttrap provider allows DTrace consumers to instrument any user-level
85  * instruction to gather data; this includes probes with semantic
86  * signifigance like entry and return as well as simple offsets into the
87  * function. While the specific techniques used are very ISA specific, the
88  * methodology is generalizable to any architecture.
89  *
90  *
91  * The General Methodology
92  * -----------------------
93  *
94  * With the primary goal of tracing every user-land instruction and the
95  * limitation that we can't trust user space so don't want to rely on much
96  * information there, we begin by replacing the instructions we want to trace
97  * with trap instructions. Each instruction we overwrite is saved into a hash
98  * table keyed by process ID and pc address. When we enter the kernel due to
99  * this trap instruction, we need the effects of the replaced instruction to
100  * appear to have occurred before we proceed with the user thread's
101  * execution.
102  *
103  * Each user level thread is represented by a ulwp_t structure which is
104  * always easily accessible through a register. The most basic way to produce
105  * the effects of the instruction we replaced is to copy that instruction out
106  * to a bit of scratch space reserved in the user thread's ulwp_t structure
107  * (a sort of kernel-private thread local storage), set the PC to that
108  * scratch space and single step. When we reenter the kernel after single
109  * stepping the instruction we must then adjust the PC to point to what would
110  * normally be the next instruction. Of course, special care must be taken
111  * for branches and jumps, but these represent such a small fraction of any
112  * instruction set that writing the code to emulate these in the kernel is
113  * not too difficult.
114  *
115  * Return probes may require several tracepoints to trace every return site,
116  * and, conversely, each tracepoint may activate several probes (the entry
117  * and offset 0 probes, for example). To solve this muliplexing problem,
118  * tracepoints contain lists of probes to activate and probes contain lists
119  * of tracepoints to enable. If a probe is activated, it adds its ID to
120  * existing tracepoints or creates new ones as necessary.
121  *
122  * Most probes are activated _before_ the instruction is executed, but return
123  * probes are activated _after_ the effects of the last instruction of the
124  * function are visible. Return probes must be fired _after_ we have
125  * single-stepped the instruction whereas all other probes are fired
126  * beforehand.
127  *
128  *
129  * Lock Ordering
130  * -------------
131  *
132  * The lock ordering below -- both internally and with respect to the DTrace
133  * framework -- is a little tricky and bears some explanation. Each provider
134  * has a lock (ftp_mtx) that protects its members including reference counts
135  * for enabled probes (ftp_rcount), consumers actively creating probes
136  * (ftp_ccount) and USDT consumers (ftp_mcount); all three prevent a provider
137  * from being freed. A provider is looked up by taking the bucket lock for the
138  * provider hash table, and is returned with its lock held. The provider lock
139  * may be taken in functions invoked by the DTrace framework, but may not be
140  * held while calling functions in the DTrace framework.
141  *
142  * To ensure consistency over multiple calls to the DTrace framework, the
143  * creation lock (ftp_cmtx) should be held. Naturally, the creation lock may
144  * not be taken when holding the provider lock as that would create a cyclic
145  * lock ordering. In situations where one would naturally take the provider
146  * lock and then the creation lock, we instead up a reference count to prevent
147  * the provider from disappearing, drop the provider lock, and acquire the
148  * creation lock.
149  *
150  * Briefly:
151  * 	bucket lock before provider lock
152  *	DTrace before provider lock
153  *	creation lock before DTrace
154  *	never hold the provider lock and creation lock simultaneously
155  */
156 
157 static d_open_t fasttrap_open;
158 static d_ioctl_t fasttrap_ioctl;
159 
160 static struct cdevsw fasttrap_cdevsw = {
161 	.d_version	= D_VERSION,
162 	.d_open		= fasttrap_open,
163 	.d_ioctl	= fasttrap_ioctl,
164 	.d_name		= "fasttrap",
165 };
166 static struct cdev *fasttrap_cdev;
167 static dtrace_meta_provider_id_t fasttrap_meta_id;
168 
169 static struct proc *fasttrap_cleanup_proc;
170 static struct mtx fasttrap_cleanup_mtx;
171 static uint_t fasttrap_cleanup_work, fasttrap_cleanup_drain, fasttrap_cleanup_cv;
172 
173 /*
174  * Generation count on modifications to the global tracepoint lookup table.
175  */
176 static volatile uint64_t fasttrap_mod_gen;
177 
178 /*
179  * When the fasttrap provider is loaded, fasttrap_max is set to either
180  * FASTTRAP_MAX_DEFAULT, or the value for fasttrap-max-probes in the
181  * fasttrap.conf file (Illumos), or the value provied in the loader.conf (FreeBSD).
182  * Each time a probe is created, fasttrap_total is incremented by the number
183  * of tracepoints that may be associated with that probe; fasttrap_total is capped
184  * at fasttrap_max.
185  */
186 #define	FASTTRAP_MAX_DEFAULT		250000
187 static uint32_t fasttrap_max = FASTTRAP_MAX_DEFAULT;
188 static uint32_t fasttrap_total;
189 
190 /*
191  * Copyright (c) 2011, Joyent, Inc. All rights reserved.
192  */
193 
194 #define	FASTTRAP_TPOINTS_DEFAULT_SIZE	0x4000
195 #define	FASTTRAP_PROVIDERS_DEFAULT_SIZE	0x100
196 #define	FASTTRAP_PROCS_DEFAULT_SIZE	0x100
197 
198 #define	FASTTRAP_PID_NAME		"pid"
199 
200 fasttrap_hash_t			fasttrap_tpoints;
201 static fasttrap_hash_t		fasttrap_provs;
202 static fasttrap_hash_t		fasttrap_procs;
203 
204 static uint64_t			fasttrap_pid_count;	/* pid ref count */
205 static kmutex_t			fasttrap_count_mtx;	/* lock on ref count */
206 
207 #define	FASTTRAP_ENABLE_FAIL	1
208 #define	FASTTRAP_ENABLE_PARTIAL	2
209 
210 static int fasttrap_tracepoint_enable(proc_t *, fasttrap_probe_t *, uint_t);
211 static void fasttrap_tracepoint_disable(proc_t *, fasttrap_probe_t *, uint_t);
212 
213 static fasttrap_provider_t *fasttrap_provider_lookup(pid_t, const char *,
214     const dtrace_pattr_t *);
215 static void fasttrap_provider_retire(pid_t, const char *, int);
216 static void fasttrap_provider_free(fasttrap_provider_t *);
217 
218 static fasttrap_proc_t *fasttrap_proc_lookup(pid_t);
219 static void fasttrap_proc_release(fasttrap_proc_t *);
220 
221 #ifndef illumos
222 static void fasttrap_thread_dtor(void *, struct thread *);
223 #endif
224 
225 #define	FASTTRAP_PROVS_INDEX(pid, name) \
226 	((fasttrap_hash_str(name) + (pid)) & fasttrap_provs.fth_mask)
227 
228 #define	FASTTRAP_PROCS_INDEX(pid) ((pid) & fasttrap_procs.fth_mask)
229 
230 #ifndef illumos
231 struct rmlock fasttrap_tp_lock;
232 static eventhandler_tag fasttrap_thread_dtor_tag;
233 #endif
234 
235 static unsigned long tpoints_hash_size = FASTTRAP_TPOINTS_DEFAULT_SIZE;
236 
237 #ifdef __FreeBSD__
238 SYSCTL_DECL(_kern_dtrace);
239 SYSCTL_NODE(_kern_dtrace, OID_AUTO, fasttrap, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
240     "DTrace fasttrap parameters");
241 SYSCTL_UINT(_kern_dtrace_fasttrap, OID_AUTO, max_probes, CTLFLAG_RWTUN, &fasttrap_max,
242     FASTTRAP_MAX_DEFAULT, "Maximum number of fasttrap probes");
243 SYSCTL_ULONG(_kern_dtrace_fasttrap, OID_AUTO, tpoints_hash_size, CTLFLAG_RDTUN, &tpoints_hash_size,
244     FASTTRAP_TPOINTS_DEFAULT_SIZE, "Size of the tracepoint hash table");
245 #endif
246 
247 static int
248 fasttrap_highbit(ulong_t i)
249 {
250 	int h = 1;
251 
252 	if (i == 0)
253 		return (0);
254 #ifdef _LP64
255 	if (i & 0xffffffff00000000ul) {
256 		h += 32; i >>= 32;
257 	}
258 #endif
259 	if (i & 0xffff0000) {
260 		h += 16; i >>= 16;
261 	}
262 	if (i & 0xff00) {
263 		h += 8; i >>= 8;
264 	}
265 	if (i & 0xf0) {
266 		h += 4; i >>= 4;
267 	}
268 	if (i & 0xc) {
269 		h += 2; i >>= 2;
270 	}
271 	if (i & 0x2) {
272 		h += 1;
273 	}
274 	return (h);
275 }
276 
277 static uint_t
278 fasttrap_hash_str(const char *p)
279 {
280 	unsigned int g;
281 	uint_t hval = 0;
282 
283 	while (*p) {
284 		hval = (hval << 4) + *p++;
285 		if ((g = (hval & 0xf0000000)) != 0)
286 			hval ^= g >> 24;
287 		hval &= ~g;
288 	}
289 	return (hval);
290 }
291 
292 void
293 fasttrap_sigtrap(proc_t *p, kthread_t *t, uintptr_t pc)
294 {
295 	ksiginfo_t ksi;
296 
297 	ksiginfo_init(&ksi);
298 	ksi.ksi_signo = SIGTRAP;
299 	ksi.ksi_code = TRAP_DTRACE;
300 	ksi.ksi_addr = (caddr_t)pc;
301 	PROC_LOCK(p);
302 	(void)tdsendsignal(p, t, SIGTRAP, &ksi);
303 	PROC_UNLOCK(p);
304 }
305 
306 #ifndef illumos
307 /*
308  * Obtain a chunk of scratch space in the address space of the target process.
309  */
310 fasttrap_scrspace_t *
311 fasttrap_scraddr(struct thread *td, fasttrap_proc_t *fprc)
312 {
313 	fasttrap_scrblock_t *scrblk;
314 	fasttrap_scrspace_t *scrspc;
315 	struct proc *p;
316 	vm_offset_t addr;
317 	int error, i;
318 
319 	scrspc = NULL;
320 	if (td->t_dtrace_sscr != NULL) {
321 		/* If the thread already has scratch space, we're done. */
322 		scrspc = (fasttrap_scrspace_t *)td->t_dtrace_sscr;
323 		return (scrspc);
324 	}
325 
326 	p = td->td_proc;
327 
328 	mutex_enter(&fprc->ftpc_mtx);
329 	if (LIST_EMPTY(&fprc->ftpc_fscr)) {
330 		/*
331 		 * No scratch space is available, so we'll map a new scratch
332 		 * space block into the traced process' address space.
333 		 */
334 		addr = 0;
335 		error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr,
336 		    FASTTRAP_SCRBLOCK_SIZE, 0, VMFS_ANY_SPACE, VM_PROT_ALL,
337 		    VM_PROT_ALL, 0);
338 		if (error != KERN_SUCCESS)
339 			goto done;
340 
341 		scrblk = malloc(sizeof(*scrblk), M_SOLARIS, M_WAITOK);
342 		scrblk->ftsb_addr = addr;
343 		LIST_INSERT_HEAD(&fprc->ftpc_scrblks, scrblk, ftsb_next);
344 
345 		/*
346 		 * Carve the block up into chunks and put them on the free list.
347 		 */
348 		for (i = 0;
349 		    i < FASTTRAP_SCRBLOCK_SIZE / FASTTRAP_SCRSPACE_SIZE; i++) {
350 			scrspc = malloc(sizeof(*scrspc), M_SOLARIS, M_WAITOK);
351 			scrspc->ftss_addr = addr +
352 			    i * FASTTRAP_SCRSPACE_SIZE;
353 			LIST_INSERT_HEAD(&fprc->ftpc_fscr, scrspc,
354 			    ftss_next);
355 		}
356 	}
357 
358 	/*
359 	 * Take the first scratch chunk off the free list, put it on the
360 	 * allocated list, and return its address.
361 	 */
362 	scrspc = LIST_FIRST(&fprc->ftpc_fscr);
363 	LIST_REMOVE(scrspc, ftss_next);
364 	LIST_INSERT_HEAD(&fprc->ftpc_ascr, scrspc, ftss_next);
365 
366 	/*
367 	 * This scratch space is reserved for use by td until the thread exits.
368 	 */
369 	td->t_dtrace_sscr = scrspc;
370 
371 done:
372 	mutex_exit(&fprc->ftpc_mtx);
373 
374 	return (scrspc);
375 }
376 
377 /*
378  * Return any allocated per-thread scratch space chunks back to the process'
379  * free list.
380  */
381 static void
382 fasttrap_thread_dtor(void *arg __unused, struct thread *td)
383 {
384 	fasttrap_bucket_t *bucket;
385 	fasttrap_proc_t *fprc;
386 	fasttrap_scrspace_t *scrspc;
387 	pid_t pid;
388 
389 	if (td->t_dtrace_sscr == NULL)
390 		return;
391 
392 	pid = td->td_proc->p_pid;
393 	bucket = &fasttrap_procs.fth_table[FASTTRAP_PROCS_INDEX(pid)];
394 	fprc = NULL;
395 
396 	/* Look up the fasttrap process handle for this process. */
397 	mutex_enter(&bucket->ftb_mtx);
398 	for (fprc = bucket->ftb_data; fprc != NULL; fprc = fprc->ftpc_next) {
399 		if (fprc->ftpc_pid == pid) {
400 			mutex_enter(&fprc->ftpc_mtx);
401 			mutex_exit(&bucket->ftb_mtx);
402 			break;
403 		}
404 	}
405 	if (fprc == NULL) {
406 		mutex_exit(&bucket->ftb_mtx);
407 		return;
408 	}
409 
410 	scrspc = (fasttrap_scrspace_t *)td->t_dtrace_sscr;
411 	LIST_REMOVE(scrspc, ftss_next);
412 	LIST_INSERT_HEAD(&fprc->ftpc_fscr, scrspc, ftss_next);
413 
414 	mutex_exit(&fprc->ftpc_mtx);
415 }
416 #endif
417 
418 /*
419  * This function ensures that no threads are actively using the memory
420  * associated with probes that were formerly live.
421  */
422 static void
423 fasttrap_mod_barrier(uint64_t gen)
424 {
425 	int i;
426 
427 	if (gen < fasttrap_mod_gen)
428 		return;
429 
430 	fasttrap_mod_gen++;
431 
432 #ifdef illumos
433 	CPU_FOREACH(i) {
434 		mutex_enter(&fasttrap_cpuc_pid_lock[i]);
435 		mutex_exit(&fasttrap_cpuc_pid_lock[i]);
436 	}
437 #else
438 	rm_wlock(&fasttrap_tp_lock);
439 	rm_wunlock(&fasttrap_tp_lock);
440 #endif
441 }
442 
443 /*
444  * This function performs asynchronous cleanup of fasttrap providers. The
445  * Solaris implementation of this mechanism use a timeout that's activated in
446  * fasttrap_pid_cleanup(), but this doesn't work in FreeBSD: one may sleep while
447  * holding the DTrace mutexes, but it is unsafe to sleep in a callout handler.
448  * Thus we use a dedicated process to perform the cleanup when requested.
449  */
450 /*ARGSUSED*/
451 static void
452 fasttrap_pid_cleanup_cb(void *data)
453 {
454 	fasttrap_provider_t **fpp, *fp;
455 	fasttrap_bucket_t *bucket;
456 	dtrace_provider_id_t provid;
457 	int i, later = 0, rval;
458 
459 	mtx_lock(&fasttrap_cleanup_mtx);
460 	while (!fasttrap_cleanup_drain || later > 0) {
461 		fasttrap_cleanup_work = 0;
462 		mtx_unlock(&fasttrap_cleanup_mtx);
463 
464 		later = 0;
465 
466 		/*
467 		 * Iterate over all the providers trying to remove the marked
468 		 * ones. If a provider is marked but not retired, we just
469 		 * have to take a crack at removing it -- it's no big deal if
470 		 * we can't.
471 		 */
472 		for (i = 0; i < fasttrap_provs.fth_nent; i++) {
473 			bucket = &fasttrap_provs.fth_table[i];
474 			mutex_enter(&bucket->ftb_mtx);
475 			fpp = (fasttrap_provider_t **)&bucket->ftb_data;
476 
477 			while ((fp = *fpp) != NULL) {
478 				if (!fp->ftp_marked) {
479 					fpp = &fp->ftp_next;
480 					continue;
481 				}
482 
483 				mutex_enter(&fp->ftp_mtx);
484 
485 				/*
486 				 * If this provider has consumers actively
487 				 * creating probes (ftp_ccount) or is a USDT
488 				 * provider (ftp_mcount), we can't unregister
489 				 * or even condense.
490 				 */
491 				if (fp->ftp_ccount != 0 ||
492 				    fp->ftp_mcount != 0) {
493 					mutex_exit(&fp->ftp_mtx);
494 					fp->ftp_marked = 0;
495 					continue;
496 				}
497 
498 				if (!fp->ftp_retired || fp->ftp_rcount != 0)
499 					fp->ftp_marked = 0;
500 
501 				mutex_exit(&fp->ftp_mtx);
502 
503 				/*
504 				 * If we successfully unregister this
505 				 * provider we can remove it from the hash
506 				 * chain and free the memory. If our attempt
507 				 * to unregister fails and this is a retired
508 				 * provider, increment our flag to try again
509 				 * pretty soon. If we've consumed more than
510 				 * half of our total permitted number of
511 				 * probes call dtrace_condense() to try to
512 				 * clean out the unenabled probes.
513 				 */
514 				provid = fp->ftp_provid;
515 				if ((rval = dtrace_unregister(provid)) != 0) {
516 					if (fasttrap_total > fasttrap_max / 2)
517 						(void) dtrace_condense(provid);
518 
519 					if (rval == EAGAIN)
520 						fp->ftp_marked = 1;
521 
522 					later += fp->ftp_marked;
523 					fpp = &fp->ftp_next;
524 				} else {
525 					*fpp = fp->ftp_next;
526 					fasttrap_provider_free(fp);
527 				}
528 			}
529 			mutex_exit(&bucket->ftb_mtx);
530 		}
531 		mtx_lock(&fasttrap_cleanup_mtx);
532 
533 		/*
534 		 * If we were unable to retire a provider, try again after a
535 		 * second. This situation can occur in certain circumstances
536 		 * where providers cannot be unregistered even though they have
537 		 * no probes enabled because of an execution of dtrace -l or
538 		 * something similar.
539 		 */
540 		if (later > 0 || fasttrap_cleanup_work ||
541 		    fasttrap_cleanup_drain) {
542 			mtx_unlock(&fasttrap_cleanup_mtx);
543 			pause("ftclean", hz);
544 			mtx_lock(&fasttrap_cleanup_mtx);
545 		} else
546 			mtx_sleep(&fasttrap_cleanup_cv, &fasttrap_cleanup_mtx,
547 			    0, "ftcl", 0);
548 	}
549 
550 	/*
551 	 * Wake up the thread in fasttrap_unload() now that we're done.
552 	 */
553 	wakeup(&fasttrap_cleanup_drain);
554 	mtx_unlock(&fasttrap_cleanup_mtx);
555 
556 	kthread_exit();
557 }
558 
559 /*
560  * Activates the asynchronous cleanup mechanism.
561  */
562 static void
563 fasttrap_pid_cleanup(void)
564 {
565 
566 	mtx_lock(&fasttrap_cleanup_mtx);
567 	if (!fasttrap_cleanup_work) {
568 		fasttrap_cleanup_work = 1;
569 		wakeup(&fasttrap_cleanup_cv);
570 	}
571 	mtx_unlock(&fasttrap_cleanup_mtx);
572 }
573 
574 /*
575  * This is called from cfork() via dtrace_fasttrap_fork(). The child
576  * process's address space is (roughly) a copy of the parent process's so
577  * we have to remove all the instrumentation we had previously enabled in the
578  * parent.
579  */
580 static void
581 fasttrap_fork(proc_t *p, proc_t *cp)
582 {
583 #ifndef illumos
584 	fasttrap_scrblock_t *scrblk;
585 	fasttrap_proc_t *fprc = NULL;
586 #endif
587 	pid_t ppid = p->p_pid;
588 	int i;
589 
590 	ASSERT(curproc == p);
591 #ifdef illumos
592 	ASSERT(p->p_proc_flag & P_PR_LOCK);
593 #else
594 	PROC_LOCK_ASSERT(p, MA_OWNED);
595 #endif
596 #ifdef illumos
597 	ASSERT(p->p_dtrace_count > 0);
598 #else
599 	/*
600 	 * This check is purposely here instead of in kern_fork.c because,
601 	 * for legal resons, we cannot include the dtrace_cddl.h header
602 	 * inside kern_fork.c and insert if-clause there.
603 	 */
604 	if (p->p_dtrace_count == 0 && p->p_dtrace_helpers == NULL)
605 		return;
606 #endif
607 
608 	ASSERT(cp->p_dtrace_count == 0);
609 
610 	/*
611 	 * This would be simpler and faster if we maintained per-process
612 	 * hash tables of enabled tracepoints. It could, however, potentially
613 	 * slow down execution of a tracepoint since we'd need to go
614 	 * through two levels of indirection. In the future, we should
615 	 * consider either maintaining per-process ancillary lists of
616 	 * enabled tracepoints or hanging a pointer to a per-process hash
617 	 * table of enabled tracepoints off the proc structure.
618 	 */
619 
620 	/*
621 	 * We don't have to worry about the child process disappearing
622 	 * because we're in fork().
623 	 */
624 #ifdef illumos
625 	mtx_lock_spin(&cp->p_slock);
626 	sprlock_proc(cp);
627 	mtx_unlock_spin(&cp->p_slock);
628 #else
629 	/*
630 	 * fasttrap_tracepoint_remove() expects the child process to be
631 	 * unlocked and the VM then expects curproc to be unlocked.
632 	 */
633 	_PHOLD(cp);
634 	PROC_UNLOCK(cp);
635 	PROC_UNLOCK(p);
636 	if (p->p_dtrace_count == 0)
637 		goto dup_helpers;
638 #endif
639 
640 	/*
641 	 * Iterate over every tracepoint looking for ones that belong to the
642 	 * parent process, and remove each from the child process.
643 	 */
644 	for (i = 0; i < fasttrap_tpoints.fth_nent; i++) {
645 		fasttrap_tracepoint_t *tp;
646 		fasttrap_bucket_t *bucket = &fasttrap_tpoints.fth_table[i];
647 
648 		mutex_enter(&bucket->ftb_mtx);
649 		for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) {
650 			if (tp->ftt_pid == ppid &&
651 			    tp->ftt_proc->ftpc_acount != 0) {
652 				int ret = fasttrap_tracepoint_remove(cp, tp);
653 				ASSERT(ret == 0);
654 
655 				/*
656 				 * The count of active providers can only be
657 				 * decremented (i.e. to zero) during exec,
658 				 * exit, and removal of a meta provider so it
659 				 * should be impossible to drop the count
660 				 * mid-fork.
661 				 */
662 				ASSERT(tp->ftt_proc->ftpc_acount != 0);
663 #ifndef illumos
664 				fprc = tp->ftt_proc;
665 #endif
666 			}
667 		}
668 		mutex_exit(&bucket->ftb_mtx);
669 
670 #ifndef illumos
671 		/*
672 		 * Unmap any scratch space inherited from the parent's address
673 		 * space.
674 		 */
675 		if (fprc != NULL) {
676 			mutex_enter(&fprc->ftpc_mtx);
677 			LIST_FOREACH(scrblk, &fprc->ftpc_scrblks, ftsb_next) {
678 				vm_map_remove(&cp->p_vmspace->vm_map,
679 				    scrblk->ftsb_addr,
680 				    scrblk->ftsb_addr + FASTTRAP_SCRBLOCK_SIZE);
681 			}
682 			mutex_exit(&fprc->ftpc_mtx);
683 		}
684 #endif
685 	}
686 
687 #ifdef illumos
688 	mutex_enter(&cp->p_lock);
689 	sprunlock(cp);
690 #else
691 dup_helpers:
692 	if (p->p_dtrace_helpers != NULL)
693 		dtrace_helpers_duplicate(p, cp);
694 	PROC_LOCK(p);
695 	PROC_LOCK(cp);
696 	_PRELE(cp);
697 #endif
698 }
699 
700 /*
701  * This is called from proc_exit() or from exec_common() if p_dtrace_probes
702  * is set on the proc structure to indicate that there is a pid provider
703  * associated with this process.
704  */
705 static void
706 fasttrap_exec_exit(proc_t *p)
707 {
708 #ifndef illumos
709 	struct thread *td;
710 #endif
711 
712 #ifdef illumos
713 	ASSERT(p == curproc);
714 #else
715 	PROC_LOCK_ASSERT(p, MA_OWNED);
716 	_PHOLD(p);
717 	/*
718 	 * Since struct threads may be recycled, we cannot rely on t_dtrace_sscr
719 	 * fields to be zeroed by kdtrace_thread_ctor. Thus we must zero it
720 	 * ourselves when a process exits.
721 	 */
722 	FOREACH_THREAD_IN_PROC(p, td)
723 		td->t_dtrace_sscr = NULL;
724 	PROC_UNLOCK(p);
725 #endif
726 
727 	/*
728 	 * We clean up the pid provider for this process here; user-land
729 	 * static probes are handled by the meta-provider remove entry point.
730 	 */
731 	fasttrap_provider_retire(p->p_pid, FASTTRAP_PID_NAME, 0);
732 #ifndef illumos
733 	if (p->p_dtrace_helpers)
734 		dtrace_helpers_destroy(p);
735 	PROC_LOCK(p);
736 	_PRELE(p);
737 #endif
738 }
739 
740 
741 /*ARGSUSED*/
742 static void
743 fasttrap_pid_provide(void *arg, dtrace_probedesc_t *desc)
744 {
745 	/*
746 	 * There are no "default" pid probes.
747 	 */
748 }
749 
750 static int
751 fasttrap_tracepoint_enable(proc_t *p, fasttrap_probe_t *probe, uint_t index)
752 {
753 	fasttrap_tracepoint_t *tp, *new_tp = NULL;
754 	fasttrap_bucket_t *bucket;
755 	fasttrap_id_t *id;
756 	pid_t pid;
757 	uintptr_t pc;
758 
759 	ASSERT(index < probe->ftp_ntps);
760 
761 	pid = probe->ftp_pid;
762 	pc = probe->ftp_tps[index].fit_tp->ftt_pc;
763 	id = &probe->ftp_tps[index].fit_id;
764 
765 	ASSERT(probe->ftp_tps[index].fit_tp->ftt_pid == pid);
766 
767 #ifdef illumos
768 	ASSERT(!(p->p_flag & SVFORK));
769 #endif
770 
771 	/*
772 	 * Before we make any modifications, make sure we've imposed a barrier
773 	 * on the generation in which this probe was last modified.
774 	 */
775 	fasttrap_mod_barrier(probe->ftp_gen);
776 
777 	bucket = &fasttrap_tpoints.fth_table[FASTTRAP_TPOINTS_INDEX(pid, pc)];
778 
779 	/*
780 	 * If the tracepoint has already been enabled, just add our id to the
781 	 * list of interested probes. This may be our second time through
782 	 * this path in which case we'll have constructed the tracepoint we'd
783 	 * like to install. If we can't find a match, and have an allocated
784 	 * tracepoint ready to go, enable that one now.
785 	 *
786 	 * A tracepoint whose process is defunct is also considered defunct.
787 	 */
788 again:
789 	mutex_enter(&bucket->ftb_mtx);
790 	for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) {
791 		/*
792 		 * Note that it's safe to access the active count on the
793 		 * associated proc structure because we know that at least one
794 		 * provider (this one) will still be around throughout this
795 		 * operation.
796 		 */
797 		if (tp->ftt_pid != pid || tp->ftt_pc != pc ||
798 		    tp->ftt_proc->ftpc_acount == 0)
799 			continue;
800 
801 		/*
802 		 * Now that we've found a matching tracepoint, it would be
803 		 * a decent idea to confirm that the tracepoint is still
804 		 * enabled and the trap instruction hasn't been overwritten.
805 		 * Since this is a little hairy, we'll punt for now.
806 		 */
807 
808 		/*
809 		 * This can't be the first interested probe. We don't have
810 		 * to worry about another thread being in the midst of
811 		 * deleting this tracepoint (which would be the only valid
812 		 * reason for a tracepoint to have no interested probes)
813 		 * since we're holding P_PR_LOCK for this process.
814 		 */
815 		ASSERT(tp->ftt_ids != NULL || tp->ftt_retids != NULL);
816 
817 		switch (id->fti_ptype) {
818 		case DTFTP_ENTRY:
819 		case DTFTP_OFFSETS:
820 		case DTFTP_IS_ENABLED:
821 			id->fti_next = tp->ftt_ids;
822 			membar_producer();
823 			tp->ftt_ids = id;
824 			membar_producer();
825 			break;
826 
827 		case DTFTP_RETURN:
828 		case DTFTP_POST_OFFSETS:
829 			id->fti_next = tp->ftt_retids;
830 			membar_producer();
831 			tp->ftt_retids = id;
832 			membar_producer();
833 			break;
834 
835 		default:
836 			ASSERT(0);
837 		}
838 
839 		mutex_exit(&bucket->ftb_mtx);
840 
841 		if (new_tp != NULL) {
842 			new_tp->ftt_ids = NULL;
843 			new_tp->ftt_retids = NULL;
844 		}
845 
846 		return (0);
847 	}
848 
849 	/*
850 	 * If we have a good tracepoint ready to go, install it now while
851 	 * we have the lock held and no one can screw with us.
852 	 */
853 	if (new_tp != NULL) {
854 		int rc = 0;
855 
856 		new_tp->ftt_next = bucket->ftb_data;
857 		membar_producer();
858 		bucket->ftb_data = new_tp;
859 		membar_producer();
860 		mutex_exit(&bucket->ftb_mtx);
861 
862 		/*
863 		 * Activate the tracepoint in the ISA-specific manner.
864 		 * If this fails, we need to report the failure, but
865 		 * indicate that this tracepoint must still be disabled
866 		 * by calling fasttrap_tracepoint_disable().
867 		 */
868 		if (fasttrap_tracepoint_install(p, new_tp) != 0)
869 			rc = FASTTRAP_ENABLE_PARTIAL;
870 
871 		/*
872 		 * Increment the count of the number of tracepoints active in
873 		 * the victim process.
874 		 */
875 #ifdef illumos
876 		ASSERT(p->p_proc_flag & P_PR_LOCK);
877 #endif
878 		p->p_dtrace_count++;
879 
880 		return (rc);
881 	}
882 
883 	mutex_exit(&bucket->ftb_mtx);
884 
885 	/*
886 	 * Initialize the tracepoint that's been preallocated with the probe.
887 	 */
888 	new_tp = probe->ftp_tps[index].fit_tp;
889 
890 	ASSERT(new_tp->ftt_pid == pid);
891 	ASSERT(new_tp->ftt_pc == pc);
892 	ASSERT(new_tp->ftt_proc == probe->ftp_prov->ftp_proc);
893 	ASSERT(new_tp->ftt_ids == NULL);
894 	ASSERT(new_tp->ftt_retids == NULL);
895 
896 	switch (id->fti_ptype) {
897 	case DTFTP_ENTRY:
898 	case DTFTP_OFFSETS:
899 	case DTFTP_IS_ENABLED:
900 		id->fti_next = NULL;
901 		new_tp->ftt_ids = id;
902 		break;
903 
904 	case DTFTP_RETURN:
905 	case DTFTP_POST_OFFSETS:
906 		id->fti_next = NULL;
907 		new_tp->ftt_retids = id;
908 		break;
909 
910 	default:
911 		ASSERT(0);
912 	}
913 
914 #ifdef __FreeBSD__
915 	if (SV_PROC_FLAG(p, SV_LP64))
916 		p->p_model = DATAMODEL_LP64;
917 	else
918 		p->p_model = DATAMODEL_ILP32;
919 #endif
920 
921 	/*
922 	 * If the ISA-dependent initialization goes to plan, go back to the
923 	 * beginning and try to install this freshly made tracepoint.
924 	 */
925 	if (fasttrap_tracepoint_init(p, new_tp, pc, id->fti_ptype) == 0)
926 		goto again;
927 
928 	new_tp->ftt_ids = NULL;
929 	new_tp->ftt_retids = NULL;
930 
931 	return (FASTTRAP_ENABLE_FAIL);
932 }
933 
934 static void
935 fasttrap_tracepoint_disable(proc_t *p, fasttrap_probe_t *probe, uint_t index)
936 {
937 	fasttrap_bucket_t *bucket;
938 	fasttrap_provider_t *provider = probe->ftp_prov;
939 	fasttrap_tracepoint_t **pp, *tp;
940 	fasttrap_id_t *id, **idp = NULL;
941 	pid_t pid;
942 	uintptr_t pc;
943 
944 	ASSERT(index < probe->ftp_ntps);
945 
946 	pid = probe->ftp_pid;
947 	pc = probe->ftp_tps[index].fit_tp->ftt_pc;
948 	id = &probe->ftp_tps[index].fit_id;
949 
950 	ASSERT(probe->ftp_tps[index].fit_tp->ftt_pid == pid);
951 
952 	/*
953 	 * Find the tracepoint and make sure that our id is one of the
954 	 * ones registered with it.
955 	 */
956 	bucket = &fasttrap_tpoints.fth_table[FASTTRAP_TPOINTS_INDEX(pid, pc)];
957 	mutex_enter(&bucket->ftb_mtx);
958 	for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) {
959 		if (tp->ftt_pid == pid && tp->ftt_pc == pc &&
960 		    tp->ftt_proc == provider->ftp_proc)
961 			break;
962 	}
963 
964 	/*
965 	 * If we somehow lost this tracepoint, we're in a world of hurt.
966 	 */
967 	ASSERT(tp != NULL);
968 
969 	switch (id->fti_ptype) {
970 	case DTFTP_ENTRY:
971 	case DTFTP_OFFSETS:
972 	case DTFTP_IS_ENABLED:
973 		ASSERT(tp->ftt_ids != NULL);
974 		idp = &tp->ftt_ids;
975 		break;
976 
977 	case DTFTP_RETURN:
978 	case DTFTP_POST_OFFSETS:
979 		ASSERT(tp->ftt_retids != NULL);
980 		idp = &tp->ftt_retids;
981 		break;
982 
983 	default:
984 		ASSERT(0);
985 	}
986 
987 	while ((*idp)->fti_probe != probe) {
988 		idp = &(*idp)->fti_next;
989 		ASSERT(*idp != NULL);
990 	}
991 
992 	id = *idp;
993 	*idp = id->fti_next;
994 	membar_producer();
995 
996 	ASSERT(id->fti_probe == probe);
997 
998 	/*
999 	 * If there are other registered enablings of this tracepoint, we're
1000 	 * all done, but if this was the last probe assocated with this
1001 	 * this tracepoint, we need to remove and free it.
1002 	 */
1003 	if (tp->ftt_ids != NULL || tp->ftt_retids != NULL) {
1004 
1005 		/*
1006 		 * If the current probe's tracepoint is in use, swap it
1007 		 * for an unused tracepoint.
1008 		 */
1009 		if (tp == probe->ftp_tps[index].fit_tp) {
1010 			fasttrap_probe_t *tmp_probe;
1011 			fasttrap_tracepoint_t **tmp_tp;
1012 			uint_t tmp_index;
1013 
1014 			if (tp->ftt_ids != NULL) {
1015 				tmp_probe = tp->ftt_ids->fti_probe;
1016 				/* LINTED - alignment */
1017 				tmp_index = FASTTRAP_ID_INDEX(tp->ftt_ids);
1018 				tmp_tp = &tmp_probe->ftp_tps[tmp_index].fit_tp;
1019 			} else {
1020 				tmp_probe = tp->ftt_retids->fti_probe;
1021 				/* LINTED - alignment */
1022 				tmp_index = FASTTRAP_ID_INDEX(tp->ftt_retids);
1023 				tmp_tp = &tmp_probe->ftp_tps[tmp_index].fit_tp;
1024 			}
1025 
1026 			ASSERT(*tmp_tp != NULL);
1027 			ASSERT(*tmp_tp != probe->ftp_tps[index].fit_tp);
1028 			ASSERT((*tmp_tp)->ftt_ids == NULL);
1029 			ASSERT((*tmp_tp)->ftt_retids == NULL);
1030 
1031 			probe->ftp_tps[index].fit_tp = *tmp_tp;
1032 			*tmp_tp = tp;
1033 		}
1034 
1035 		mutex_exit(&bucket->ftb_mtx);
1036 
1037 		/*
1038 		 * Tag the modified probe with the generation in which it was
1039 		 * changed.
1040 		 */
1041 		probe->ftp_gen = fasttrap_mod_gen;
1042 		return;
1043 	}
1044 
1045 	mutex_exit(&bucket->ftb_mtx);
1046 
1047 	/*
1048 	 * We can't safely remove the tracepoint from the set of active
1049 	 * tracepoints until we've actually removed the fasttrap instruction
1050 	 * from the process's text. We can, however, operate on this
1051 	 * tracepoint secure in the knowledge that no other thread is going to
1052 	 * be looking at it since we hold P_PR_LOCK on the process if it's
1053 	 * live or we hold the provider lock on the process if it's dead and
1054 	 * gone.
1055 	 */
1056 
1057 	/*
1058 	 * We only need to remove the actual instruction if we're looking
1059 	 * at an existing process
1060 	 */
1061 	if (p != NULL) {
1062 		/*
1063 		 * If we fail to restore the instruction we need to kill
1064 		 * this process since it's in a completely unrecoverable
1065 		 * state.
1066 		 */
1067 		if (fasttrap_tracepoint_remove(p, tp) != 0)
1068 			fasttrap_sigtrap(p, NULL, pc);
1069 
1070 		/*
1071 		 * Decrement the count of the number of tracepoints active
1072 		 * in the victim process.
1073 		 */
1074 #ifdef illumos
1075 		ASSERT(p->p_proc_flag & P_PR_LOCK);
1076 #endif
1077 		p->p_dtrace_count--;
1078 
1079 		atomic_add_rel_64(&p->p_fasttrap_tp_gen, 1);
1080 	}
1081 
1082 	/*
1083 	 * Remove the probe from the hash table of active tracepoints.
1084 	 */
1085 	mutex_enter(&bucket->ftb_mtx);
1086 	pp = (fasttrap_tracepoint_t **)&bucket->ftb_data;
1087 	ASSERT(*pp != NULL);
1088 	while (*pp != tp) {
1089 		pp = &(*pp)->ftt_next;
1090 		ASSERT(*pp != NULL);
1091 	}
1092 
1093 	*pp = tp->ftt_next;
1094 	membar_producer();
1095 
1096 	mutex_exit(&bucket->ftb_mtx);
1097 
1098 	/*
1099 	 * Tag the modified probe with the generation in which it was changed.
1100 	 */
1101 	probe->ftp_gen = fasttrap_mod_gen;
1102 }
1103 
1104 static void
1105 fasttrap_enable_callbacks(void)
1106 {
1107 	/*
1108 	 * We don't have to play the rw lock game here because we're
1109 	 * providing something rather than taking something away --
1110 	 * we can be sure that no threads have tried to follow this
1111 	 * function pointer yet.
1112 	 */
1113 	mutex_enter(&fasttrap_count_mtx);
1114 	if (fasttrap_pid_count == 0) {
1115 		ASSERT(dtrace_pid_probe_ptr == NULL);
1116 		ASSERT(dtrace_return_probe_ptr == NULL);
1117 		dtrace_pid_probe_ptr = &fasttrap_pid_probe;
1118 		dtrace_return_probe_ptr = &fasttrap_return_probe;
1119 	}
1120 	ASSERT(dtrace_pid_probe_ptr == &fasttrap_pid_probe);
1121 	ASSERT(dtrace_return_probe_ptr == &fasttrap_return_probe);
1122 	fasttrap_pid_count++;
1123 	mutex_exit(&fasttrap_count_mtx);
1124 }
1125 
1126 static void
1127 fasttrap_disable_callbacks(void)
1128 {
1129 	mutex_enter(&fasttrap_count_mtx);
1130 	ASSERT(fasttrap_pid_count > 0);
1131 	fasttrap_pid_count--;
1132 	if (fasttrap_pid_count == 0) {
1133 		/*
1134 		 * Synchronize with the breakpoint handler, which is careful to
1135 		 * enable interrupts only after loading the hook pointer.
1136 		 */
1137 		dtrace_sync();
1138 		dtrace_pid_probe_ptr = NULL;
1139 		dtrace_return_probe_ptr = NULL;
1140 	}
1141 	mutex_exit(&fasttrap_count_mtx);
1142 }
1143 
1144 /*ARGSUSED*/
1145 static void
1146 fasttrap_pid_enable(void *arg, dtrace_id_t id, void *parg)
1147 {
1148 	fasttrap_probe_t *probe = parg;
1149 	proc_t *p = NULL;
1150 	int i, rc;
1151 
1152 	ASSERT(probe != NULL);
1153 	ASSERT(!probe->ftp_enabled);
1154 	ASSERT(id == probe->ftp_id);
1155 #ifdef illumos
1156 	ASSERT(MUTEX_HELD(&cpu_lock));
1157 #endif
1158 
1159 	/*
1160 	 * Increment the count of enabled probes on this probe's provider;
1161 	 * the provider can't go away while the probe still exists. We
1162 	 * must increment this even if we aren't able to properly enable
1163 	 * this probe.
1164 	 */
1165 	mutex_enter(&probe->ftp_prov->ftp_mtx);
1166 	probe->ftp_prov->ftp_rcount++;
1167 	mutex_exit(&probe->ftp_prov->ftp_mtx);
1168 
1169 	/*
1170 	 * If this probe's provider is retired (meaning it was valid in a
1171 	 * previously exec'ed incarnation of this address space), bail out. The
1172 	 * provider can't go away while we're in this code path.
1173 	 */
1174 	if (probe->ftp_prov->ftp_retired)
1175 		return;
1176 
1177 	/*
1178 	 * If we can't find the process, it may be that we're in the context of
1179 	 * a fork in which the traced process is being born and we're copying
1180 	 * USDT probes. Otherwise, the process is gone so bail.
1181 	 */
1182 #ifdef illumos
1183 	if ((p = sprlock(probe->ftp_pid)) == NULL) {
1184 		if ((curproc->p_flag & SFORKING) == 0)
1185 			return;
1186 
1187 		mutex_enter(&pidlock);
1188 		p = prfind(probe->ftp_pid);
1189 
1190 		if (p == NULL) {
1191 			/*
1192 			 * So it's not that the target process is being born,
1193 			 * it's that it isn't there at all (and we simply
1194 			 * happen to be forking).  Anyway, we know that the
1195 			 * target is definitely gone, so bail out.
1196 			 */
1197 			mutex_exit(&pidlock);
1198 			return (0);
1199 		}
1200 
1201 		/*
1202 		 * Confirm that curproc is indeed forking the process in which
1203 		 * we're trying to enable probes.
1204 		 */
1205 		ASSERT(p->p_parent == curproc);
1206 		ASSERT(p->p_stat == SIDL);
1207 
1208 		mutex_enter(&p->p_lock);
1209 		mutex_exit(&pidlock);
1210 
1211 		sprlock_proc(p);
1212 	}
1213 
1214 	ASSERT(!(p->p_flag & SVFORK));
1215 	mutex_exit(&p->p_lock);
1216 #else
1217 	if (pget(probe->ftp_pid, PGET_HOLD | PGET_NOTWEXIT, &p) != 0)
1218 		return;
1219 #endif
1220 
1221 	/*
1222 	 * We have to enable the trap entry point before any user threads have
1223 	 * the chance to execute the trap instruction we're about to place
1224 	 * in their process's text.
1225 	 */
1226 	fasttrap_enable_callbacks();
1227 
1228 	/*
1229 	 * Enable all the tracepoints and add this probe's id to each
1230 	 * tracepoint's list of active probes.
1231 	 */
1232 	for (i = 0; i < probe->ftp_ntps; i++) {
1233 		if ((rc = fasttrap_tracepoint_enable(p, probe, i)) != 0) {
1234 			/*
1235 			 * If enabling the tracepoint failed completely,
1236 			 * we don't have to disable it; if the failure
1237 			 * was only partial we must disable it.
1238 			 */
1239 			if (rc == FASTTRAP_ENABLE_FAIL)
1240 				i--;
1241 			else
1242 				ASSERT(rc == FASTTRAP_ENABLE_PARTIAL);
1243 
1244 			/*
1245 			 * Back up and pull out all the tracepoints we've
1246 			 * created so far for this probe.
1247 			 */
1248 			while (i >= 0) {
1249 				fasttrap_tracepoint_disable(p, probe, i);
1250 				i--;
1251 			}
1252 
1253 #ifdef illumos
1254 			mutex_enter(&p->p_lock);
1255 			sprunlock(p);
1256 #else
1257 			PRELE(p);
1258 #endif
1259 
1260 			/*
1261 			 * Since we're not actually enabling this probe,
1262 			 * drop our reference on the trap table entry.
1263 			 */
1264 			fasttrap_disable_callbacks();
1265 			return;
1266 		}
1267 	}
1268 #ifdef illumos
1269 	mutex_enter(&p->p_lock);
1270 	sprunlock(p);
1271 #else
1272 	PRELE(p);
1273 #endif
1274 
1275 	probe->ftp_enabled = 1;
1276 }
1277 
1278 /*ARGSUSED*/
1279 static void
1280 fasttrap_pid_disable(void *arg, dtrace_id_t id, void *parg)
1281 {
1282 	fasttrap_probe_t *probe = parg;
1283 	fasttrap_provider_t *provider = probe->ftp_prov;
1284 	proc_t *p;
1285 	int i, whack = 0;
1286 
1287 	ASSERT(id == probe->ftp_id);
1288 
1289 	mutex_enter(&provider->ftp_mtx);
1290 
1291 	/*
1292 	 * We won't be able to acquire a /proc-esque lock on the process
1293 	 * iff the process is dead and gone. In this case, we rely on the
1294 	 * provider lock as a point of mutual exclusion to prevent other
1295 	 * DTrace consumers from disabling this probe.
1296 	 */
1297 	if (pget(probe->ftp_pid, PGET_HOLD | PGET_NOTWEXIT, &p) != 0)
1298 		p = NULL;
1299 
1300 	/*
1301 	 * Disable all the associated tracepoints (for fully enabled probes).
1302 	 */
1303 	if (probe->ftp_enabled) {
1304 		for (i = 0; i < probe->ftp_ntps; i++) {
1305 			fasttrap_tracepoint_disable(p, probe, i);
1306 		}
1307 	}
1308 
1309 	ASSERT(provider->ftp_rcount > 0);
1310 	provider->ftp_rcount--;
1311 
1312 	if (p != NULL) {
1313 		/*
1314 		 * Even though we may not be able to remove it entirely, we
1315 		 * mark this retired provider to get a chance to remove some
1316 		 * of the associated probes.
1317 		 */
1318 		if (provider->ftp_retired && !provider->ftp_marked)
1319 			whack = provider->ftp_marked = 1;
1320 		mutex_exit(&provider->ftp_mtx);
1321 	} else {
1322 		/*
1323 		 * If the process is dead, we're just waiting for the
1324 		 * last probe to be disabled to be able to free it.
1325 		 */
1326 		if (provider->ftp_rcount == 0 && !provider->ftp_marked)
1327 			whack = provider->ftp_marked = 1;
1328 		mutex_exit(&provider->ftp_mtx);
1329 	}
1330 
1331 	if (whack)
1332 		fasttrap_pid_cleanup();
1333 
1334 #ifdef __FreeBSD__
1335 	if (p != NULL)
1336 		PRELE(p);
1337 #endif
1338 	if (!probe->ftp_enabled)
1339 		return;
1340 
1341 	probe->ftp_enabled = 0;
1342 
1343 #ifdef illumos
1344 	ASSERT(MUTEX_HELD(&cpu_lock));
1345 #endif
1346 	fasttrap_disable_callbacks();
1347 }
1348 
1349 /*ARGSUSED*/
1350 static void
1351 fasttrap_pid_getargdesc(void *arg, dtrace_id_t id, void *parg,
1352     dtrace_argdesc_t *desc)
1353 {
1354 	fasttrap_probe_t *probe = parg;
1355 	char *str;
1356 	int i, ndx;
1357 
1358 	desc->dtargd_native[0] = '\0';
1359 	desc->dtargd_xlate[0] = '\0';
1360 
1361 	if (probe->ftp_prov->ftp_retired != 0 ||
1362 	    desc->dtargd_ndx >= probe->ftp_nargs) {
1363 		desc->dtargd_ndx = DTRACE_ARGNONE;
1364 		return;
1365 	}
1366 
1367 	ndx = (probe->ftp_argmap != NULL) ?
1368 	    probe->ftp_argmap[desc->dtargd_ndx] : desc->dtargd_ndx;
1369 
1370 	str = probe->ftp_ntypes;
1371 	for (i = 0; i < ndx; i++) {
1372 		str += strlen(str) + 1;
1373 	}
1374 
1375 	ASSERT(strlen(str + 1) < sizeof (desc->dtargd_native));
1376 	(void) strcpy(desc->dtargd_native, str);
1377 
1378 	if (probe->ftp_xtypes == NULL)
1379 		return;
1380 
1381 	str = probe->ftp_xtypes;
1382 	for (i = 0; i < desc->dtargd_ndx; i++) {
1383 		str += strlen(str) + 1;
1384 	}
1385 
1386 	ASSERT(strlen(str + 1) < sizeof (desc->dtargd_xlate));
1387 	(void) strcpy(desc->dtargd_xlate, str);
1388 }
1389 
1390 /*ARGSUSED*/
1391 static void
1392 fasttrap_pid_destroy(void *arg, dtrace_id_t id, void *parg)
1393 {
1394 	fasttrap_probe_t *probe = parg;
1395 	int i;
1396 	size_t size;
1397 
1398 	ASSERT(probe != NULL);
1399 	ASSERT(!probe->ftp_enabled);
1400 	ASSERT(fasttrap_total >= probe->ftp_ntps);
1401 
1402 	atomic_add_32(&fasttrap_total, -probe->ftp_ntps);
1403 	size = offsetof(fasttrap_probe_t, ftp_tps[probe->ftp_ntps]);
1404 
1405 	if (probe->ftp_gen + 1 >= fasttrap_mod_gen)
1406 		fasttrap_mod_barrier(probe->ftp_gen);
1407 
1408 	for (i = 0; i < probe->ftp_ntps; i++) {
1409 		kmem_free(probe->ftp_tps[i].fit_tp,
1410 		    sizeof (fasttrap_tracepoint_t));
1411 	}
1412 
1413 	kmem_free(probe, size);
1414 }
1415 
1416 
1417 static const dtrace_pattr_t pid_attr = {
1418 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_ISA },
1419 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
1420 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
1421 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_ISA },
1422 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
1423 };
1424 
1425 static dtrace_pops_t pid_pops = {
1426 	.dtps_provide =		fasttrap_pid_provide,
1427 	.dtps_provide_module =	NULL,
1428 	.dtps_enable =		fasttrap_pid_enable,
1429 	.dtps_disable =		fasttrap_pid_disable,
1430 	.dtps_suspend =		NULL,
1431 	.dtps_resume =		NULL,
1432 	.dtps_getargdesc =	fasttrap_pid_getargdesc,
1433 	.dtps_getargval =	fasttrap_pid_getarg,
1434 	.dtps_usermode =	NULL,
1435 	.dtps_destroy =		fasttrap_pid_destroy
1436 };
1437 
1438 static dtrace_pops_t usdt_pops = {
1439 	.dtps_provide =		fasttrap_pid_provide,
1440 	.dtps_provide_module =	NULL,
1441 	.dtps_enable =		fasttrap_pid_enable,
1442 	.dtps_disable =		fasttrap_pid_disable,
1443 	.dtps_suspend =		NULL,
1444 	.dtps_resume =		NULL,
1445 	.dtps_getargdesc =	fasttrap_pid_getargdesc,
1446 	.dtps_getargval =	fasttrap_usdt_getarg,
1447 	.dtps_usermode =	NULL,
1448 	.dtps_destroy =		fasttrap_pid_destroy
1449 };
1450 
1451 static fasttrap_proc_t *
1452 fasttrap_proc_lookup(pid_t pid)
1453 {
1454 	fasttrap_bucket_t *bucket;
1455 	fasttrap_proc_t *fprc, *new_fprc;
1456 
1457 
1458 	bucket = &fasttrap_procs.fth_table[FASTTRAP_PROCS_INDEX(pid)];
1459 	mutex_enter(&bucket->ftb_mtx);
1460 
1461 	for (fprc = bucket->ftb_data; fprc != NULL; fprc = fprc->ftpc_next) {
1462 		if (fprc->ftpc_pid == pid && fprc->ftpc_acount != 0) {
1463 			mutex_enter(&fprc->ftpc_mtx);
1464 			mutex_exit(&bucket->ftb_mtx);
1465 			fprc->ftpc_rcount++;
1466 			atomic_inc_64(&fprc->ftpc_acount);
1467 			ASSERT(fprc->ftpc_acount <= fprc->ftpc_rcount);
1468 			mutex_exit(&fprc->ftpc_mtx);
1469 
1470 			return (fprc);
1471 		}
1472 	}
1473 
1474 	/*
1475 	 * Drop the bucket lock so we don't try to perform a sleeping
1476 	 * allocation under it.
1477 	 */
1478 	mutex_exit(&bucket->ftb_mtx);
1479 
1480 	new_fprc = kmem_zalloc(sizeof (fasttrap_proc_t), KM_SLEEP);
1481 	new_fprc->ftpc_pid = pid;
1482 	new_fprc->ftpc_rcount = 1;
1483 	new_fprc->ftpc_acount = 1;
1484 #ifndef illumos
1485 	mutex_init(&new_fprc->ftpc_mtx, "fasttrap proc mtx", MUTEX_DEFAULT,
1486 	    NULL);
1487 #endif
1488 
1489 	mutex_enter(&bucket->ftb_mtx);
1490 
1491 	/*
1492 	 * Take another lap through the list to make sure a proc hasn't
1493 	 * been created for this pid while we weren't under the bucket lock.
1494 	 */
1495 	for (fprc = bucket->ftb_data; fprc != NULL; fprc = fprc->ftpc_next) {
1496 		if (fprc->ftpc_pid == pid && fprc->ftpc_acount != 0) {
1497 			mutex_enter(&fprc->ftpc_mtx);
1498 			mutex_exit(&bucket->ftb_mtx);
1499 			fprc->ftpc_rcount++;
1500 			atomic_inc_64(&fprc->ftpc_acount);
1501 			ASSERT(fprc->ftpc_acount <= fprc->ftpc_rcount);
1502 			mutex_exit(&fprc->ftpc_mtx);
1503 
1504 			kmem_free(new_fprc, sizeof (fasttrap_proc_t));
1505 
1506 			return (fprc);
1507 		}
1508 	}
1509 
1510 	new_fprc->ftpc_next = bucket->ftb_data;
1511 	bucket->ftb_data = new_fprc;
1512 
1513 	mutex_exit(&bucket->ftb_mtx);
1514 
1515 	return (new_fprc);
1516 }
1517 
1518 static void
1519 fasttrap_proc_release(fasttrap_proc_t *proc)
1520 {
1521 	fasttrap_bucket_t *bucket;
1522 	fasttrap_proc_t *fprc, **fprcp;
1523 	pid_t pid = proc->ftpc_pid;
1524 #ifndef illumos
1525 	fasttrap_scrblock_t *scrblk, *scrblktmp;
1526 	fasttrap_scrspace_t *scrspc, *scrspctmp;
1527 	struct proc *p;
1528 	struct thread *td;
1529 #endif
1530 
1531 	mutex_enter(&proc->ftpc_mtx);
1532 
1533 	ASSERT(proc->ftpc_rcount != 0);
1534 	ASSERT(proc->ftpc_acount <= proc->ftpc_rcount);
1535 
1536 	if (--proc->ftpc_rcount != 0) {
1537 		mutex_exit(&proc->ftpc_mtx);
1538 		return;
1539 	}
1540 
1541 #ifndef illumos
1542 	/*
1543 	 * Free all structures used to manage per-thread scratch space.
1544 	 */
1545 	LIST_FOREACH_SAFE(scrblk, &proc->ftpc_scrblks, ftsb_next,
1546 	    scrblktmp) {
1547 		LIST_REMOVE(scrblk, ftsb_next);
1548 		free(scrblk, M_SOLARIS);
1549 	}
1550 	LIST_FOREACH_SAFE(scrspc, &proc->ftpc_fscr, ftss_next, scrspctmp) {
1551 		LIST_REMOVE(scrspc, ftss_next);
1552 		free(scrspc, M_SOLARIS);
1553 	}
1554 	LIST_FOREACH_SAFE(scrspc, &proc->ftpc_ascr, ftss_next, scrspctmp) {
1555 		LIST_REMOVE(scrspc, ftss_next);
1556 		free(scrspc, M_SOLARIS);
1557 	}
1558 
1559 	if ((p = pfind(pid)) != NULL) {
1560 		FOREACH_THREAD_IN_PROC(p, td)
1561 			td->t_dtrace_sscr = NULL;
1562 		PROC_UNLOCK(p);
1563 	}
1564 #endif
1565 
1566 	mutex_exit(&proc->ftpc_mtx);
1567 
1568 	/*
1569 	 * There should definitely be no live providers associated with this
1570 	 * process at this point.
1571 	 */
1572 	ASSERT(proc->ftpc_acount == 0);
1573 
1574 	bucket = &fasttrap_procs.fth_table[FASTTRAP_PROCS_INDEX(pid)];
1575 	mutex_enter(&bucket->ftb_mtx);
1576 
1577 	fprcp = (fasttrap_proc_t **)&bucket->ftb_data;
1578 	while ((fprc = *fprcp) != NULL) {
1579 		if (fprc == proc)
1580 			break;
1581 
1582 		fprcp = &fprc->ftpc_next;
1583 	}
1584 
1585 	/*
1586 	 * Something strange has happened if we can't find the proc.
1587 	 */
1588 	ASSERT(fprc != NULL);
1589 
1590 	*fprcp = fprc->ftpc_next;
1591 
1592 	mutex_exit(&bucket->ftb_mtx);
1593 
1594 	kmem_free(fprc, sizeof (fasttrap_proc_t));
1595 }
1596 
1597 /*
1598  * Lookup a fasttrap-managed provider based on its name and associated pid.
1599  * If the pattr argument is non-NULL, this function instantiates the provider
1600  * if it doesn't exist otherwise it returns NULL. The provider is returned
1601  * with its lock held.
1602  */
1603 static fasttrap_provider_t *
1604 fasttrap_provider_lookup(pid_t pid, const char *name,
1605     const dtrace_pattr_t *pattr)
1606 {
1607 	fasttrap_provider_t *fp, *new_fp = NULL;
1608 	fasttrap_bucket_t *bucket;
1609 	char provname[DTRACE_PROVNAMELEN];
1610 	proc_t *p;
1611 	cred_t *cred;
1612 
1613 	ASSERT(strlen(name) < sizeof (fp->ftp_name));
1614 	ASSERT(pattr != NULL);
1615 
1616 	bucket = &fasttrap_provs.fth_table[FASTTRAP_PROVS_INDEX(pid, name)];
1617 	mutex_enter(&bucket->ftb_mtx);
1618 
1619 	/*
1620 	 * Take a lap through the list and return the match if we find it.
1621 	 */
1622 	for (fp = bucket->ftb_data; fp != NULL; fp = fp->ftp_next) {
1623 		if (fp->ftp_pid == pid && strcmp(fp->ftp_name, name) == 0 &&
1624 		    !fp->ftp_retired) {
1625 			mutex_enter(&fp->ftp_mtx);
1626 			mutex_exit(&bucket->ftb_mtx);
1627 			return (fp);
1628 		}
1629 	}
1630 
1631 	/*
1632 	 * Drop the bucket lock so we don't try to perform a sleeping
1633 	 * allocation under it.
1634 	 */
1635 	mutex_exit(&bucket->ftb_mtx);
1636 
1637 	/*
1638 	 * Make sure the process exists, isn't a child created as the result
1639 	 * of a vfork(2), and isn't a zombie (but may be in fork).
1640 	 */
1641 	if ((p = pfind(pid)) == NULL)
1642 		return (NULL);
1643 
1644 	/*
1645 	 * Increment p_dtrace_probes so that the process knows to inform us
1646 	 * when it exits or execs. fasttrap_provider_free() decrements this
1647 	 * when we're done with this provider.
1648 	 */
1649 	p->p_dtrace_probes++;
1650 
1651 	/*
1652 	 * Grab the credentials for this process so we have
1653 	 * something to pass to dtrace_register().
1654 	 */
1655 	PROC_LOCK_ASSERT(p, MA_OWNED);
1656 	crhold(p->p_ucred);
1657 	cred = p->p_ucred;
1658 	PROC_UNLOCK(p);
1659 
1660 	new_fp = kmem_zalloc(sizeof (fasttrap_provider_t), KM_SLEEP);
1661 	new_fp->ftp_pid = pid;
1662 	new_fp->ftp_proc = fasttrap_proc_lookup(pid);
1663 #ifndef illumos
1664 	mutex_init(&new_fp->ftp_mtx, "provider mtx", MUTEX_DEFAULT, NULL);
1665 	mutex_init(&new_fp->ftp_cmtx, "lock on creating", MUTEX_DEFAULT, NULL);
1666 #endif
1667 
1668 	ASSERT(new_fp->ftp_proc != NULL);
1669 
1670 	mutex_enter(&bucket->ftb_mtx);
1671 
1672 	/*
1673 	 * Take another lap through the list to make sure a provider hasn't
1674 	 * been created for this pid while we weren't under the bucket lock.
1675 	 */
1676 	for (fp = bucket->ftb_data; fp != NULL; fp = fp->ftp_next) {
1677 		if (fp->ftp_pid == pid && strcmp(fp->ftp_name, name) == 0 &&
1678 		    !fp->ftp_retired) {
1679 			mutex_enter(&fp->ftp_mtx);
1680 			mutex_exit(&bucket->ftb_mtx);
1681 			fasttrap_provider_free(new_fp);
1682 			crfree(cred);
1683 			return (fp);
1684 		}
1685 	}
1686 
1687 	(void) strcpy(new_fp->ftp_name, name);
1688 
1689 	/*
1690 	 * Fail and return NULL if either the provider name is too long
1691 	 * or we fail to register this new provider with the DTrace
1692 	 * framework. Note that this is the only place we ever construct
1693 	 * the full provider name -- we keep it in pieces in the provider
1694 	 * structure.
1695 	 */
1696 	if (snprintf(provname, sizeof (provname), "%s%u", name, (uint_t)pid) >=
1697 	    sizeof (provname) ||
1698 	    dtrace_register(provname, pattr,
1699 	    DTRACE_PRIV_PROC | DTRACE_PRIV_OWNER | DTRACE_PRIV_ZONEOWNER, cred,
1700 	    pattr == &pid_attr ? &pid_pops : &usdt_pops, new_fp,
1701 	    &new_fp->ftp_provid) != 0) {
1702 		mutex_exit(&bucket->ftb_mtx);
1703 		fasttrap_provider_free(new_fp);
1704 		crfree(cred);
1705 		return (NULL);
1706 	}
1707 
1708 	new_fp->ftp_next = bucket->ftb_data;
1709 	bucket->ftb_data = new_fp;
1710 
1711 	mutex_enter(&new_fp->ftp_mtx);
1712 	mutex_exit(&bucket->ftb_mtx);
1713 
1714 	crfree(cred);
1715 	return (new_fp);
1716 }
1717 
1718 static void
1719 fasttrap_provider_free(fasttrap_provider_t *provider)
1720 {
1721 	pid_t pid = provider->ftp_pid;
1722 	proc_t *p;
1723 
1724 	/*
1725 	 * There need to be no associated enabled probes, no consumers
1726 	 * creating probes, and no meta providers referencing this provider.
1727 	 */
1728 	ASSERT(provider->ftp_rcount == 0);
1729 	ASSERT(provider->ftp_ccount == 0);
1730 	ASSERT(provider->ftp_mcount == 0);
1731 
1732 	/*
1733 	 * If this provider hasn't been retired, we need to explicitly drop the
1734 	 * count of active providers on the associated process structure.
1735 	 */
1736 	if (!provider->ftp_retired) {
1737 		atomic_dec_64(&provider->ftp_proc->ftpc_acount);
1738 		ASSERT(provider->ftp_proc->ftpc_acount <
1739 		    provider->ftp_proc->ftpc_rcount);
1740 	}
1741 
1742 	fasttrap_proc_release(provider->ftp_proc);
1743 
1744 #ifndef illumos
1745 	mutex_destroy(&provider->ftp_mtx);
1746 	mutex_destroy(&provider->ftp_cmtx);
1747 #endif
1748 	kmem_free(provider, sizeof (fasttrap_provider_t));
1749 
1750 	/*
1751 	 * Decrement p_dtrace_probes on the process whose provider we're
1752 	 * freeing. We don't have to worry about clobbering somone else's
1753 	 * modifications to it because we have locked the bucket that
1754 	 * corresponds to this process's hash chain in the provider hash
1755 	 * table. Don't sweat it if we can't find the process.
1756 	 */
1757 	if ((p = pfind(pid)) == NULL) {
1758 		return;
1759 	}
1760 
1761 	p->p_dtrace_probes--;
1762 #ifndef illumos
1763 	PROC_UNLOCK(p);
1764 #endif
1765 }
1766 
1767 static void
1768 fasttrap_provider_retire(pid_t pid, const char *name, int mprov)
1769 {
1770 	fasttrap_provider_t *fp;
1771 	fasttrap_bucket_t *bucket;
1772 	dtrace_provider_id_t provid;
1773 
1774 	ASSERT(strlen(name) < sizeof (fp->ftp_name));
1775 
1776 	bucket = &fasttrap_provs.fth_table[FASTTRAP_PROVS_INDEX(pid, name)];
1777 	mutex_enter(&bucket->ftb_mtx);
1778 
1779 	for (fp = bucket->ftb_data; fp != NULL; fp = fp->ftp_next) {
1780 		if (fp->ftp_pid == pid && strcmp(fp->ftp_name, name) == 0 &&
1781 		    !fp->ftp_retired)
1782 			break;
1783 	}
1784 
1785 	if (fp == NULL) {
1786 		mutex_exit(&bucket->ftb_mtx);
1787 		return;
1788 	}
1789 
1790 	mutex_enter(&fp->ftp_mtx);
1791 	ASSERT(!mprov || fp->ftp_mcount > 0);
1792 	if (mprov && --fp->ftp_mcount != 0)  {
1793 		mutex_exit(&fp->ftp_mtx);
1794 		mutex_exit(&bucket->ftb_mtx);
1795 		return;
1796 	}
1797 
1798 	/*
1799 	 * Mark the provider to be removed in our post-processing step, mark it
1800 	 * retired, and drop the active count on its proc. Marking it indicates
1801 	 * that we should try to remove it; setting the retired flag indicates
1802 	 * that we're done with this provider; dropping the active the proc
1803 	 * releases our hold, and when this reaches zero (as it will during
1804 	 * exit or exec) the proc and associated providers become defunct.
1805 	 *
1806 	 * We obviously need to take the bucket lock before the provider lock
1807 	 * to perform the lookup, but we need to drop the provider lock
1808 	 * before calling into the DTrace framework since we acquire the
1809 	 * provider lock in callbacks invoked from the DTrace framework. The
1810 	 * bucket lock therefore protects the integrity of the provider hash
1811 	 * table.
1812 	 */
1813 	atomic_dec_64(&fp->ftp_proc->ftpc_acount);
1814 	ASSERT(fp->ftp_proc->ftpc_acount < fp->ftp_proc->ftpc_rcount);
1815 
1816 	fp->ftp_retired = 1;
1817 	fp->ftp_marked = 1;
1818 	provid = fp->ftp_provid;
1819 	mutex_exit(&fp->ftp_mtx);
1820 
1821 	/*
1822 	 * We don't have to worry about invalidating the same provider twice
1823 	 * since fasttrap_provider_lookup() will ignore provider that have
1824 	 * been marked as retired.
1825 	 */
1826 	dtrace_invalidate(provid);
1827 
1828 	mutex_exit(&bucket->ftb_mtx);
1829 
1830 	fasttrap_pid_cleanup();
1831 }
1832 
1833 static int
1834 fasttrap_uint32_cmp(const void *ap, const void *bp)
1835 {
1836 	return (*(const uint32_t *)ap - *(const uint32_t *)bp);
1837 }
1838 
1839 static int
1840 fasttrap_uint64_cmp(const void *ap, const void *bp)
1841 {
1842 	return (*(const uint64_t *)ap - *(const uint64_t *)bp);
1843 }
1844 
1845 static int
1846 fasttrap_add_probe(fasttrap_probe_spec_t *pdata)
1847 {
1848 	fasttrap_provider_t *provider;
1849 	fasttrap_probe_t *pp;
1850 	fasttrap_tracepoint_t *tp;
1851 	char *name;
1852 	int i, aframes = 0, whack;
1853 
1854 	/*
1855 	 * There needs to be at least one desired trace point.
1856 	 */
1857 	if (pdata->ftps_noffs == 0)
1858 		return (EINVAL);
1859 
1860 	switch (pdata->ftps_type) {
1861 	case DTFTP_ENTRY:
1862 		name = "entry";
1863 		aframes = FASTTRAP_ENTRY_AFRAMES;
1864 		break;
1865 	case DTFTP_RETURN:
1866 		name = "return";
1867 		aframes = FASTTRAP_RETURN_AFRAMES;
1868 		break;
1869 	case DTFTP_OFFSETS:
1870 		name = NULL;
1871 		break;
1872 	default:
1873 		return (EINVAL);
1874 	}
1875 
1876 	if ((provider = fasttrap_provider_lookup(pdata->ftps_pid,
1877 	    FASTTRAP_PID_NAME, &pid_attr)) == NULL)
1878 		return (ESRCH);
1879 
1880 	/*
1881 	 * Increment this reference count to indicate that a consumer is
1882 	 * actively adding a new probe associated with this provider. This
1883 	 * prevents the provider from being deleted -- we'll need to check
1884 	 * for pending deletions when we drop this reference count.
1885 	 */
1886 	provider->ftp_ccount++;
1887 	mutex_exit(&provider->ftp_mtx);
1888 
1889 	/*
1890 	 * Grab the creation lock to ensure consistency between calls to
1891 	 * dtrace_probe_lookup() and dtrace_probe_create() in the face of
1892 	 * other threads creating probes. We must drop the provider lock
1893 	 * before taking this lock to avoid a three-way deadlock with the
1894 	 * DTrace framework.
1895 	 */
1896 	mutex_enter(&provider->ftp_cmtx);
1897 
1898 	if (name == NULL) {
1899 		for (i = 0; i < pdata->ftps_noffs; i++) {
1900 			char name_str[17];
1901 
1902 			(void) sprintf(name_str, "%llx",
1903 			    (unsigned long long)pdata->ftps_offs[i]);
1904 
1905 			if (dtrace_probe_lookup(provider->ftp_provid,
1906 			    pdata->ftps_mod, pdata->ftps_func, name_str) != 0)
1907 				continue;
1908 
1909 			atomic_inc_32(&fasttrap_total);
1910 
1911 			if (fasttrap_total > fasttrap_max) {
1912 				atomic_dec_32(&fasttrap_total);
1913 				goto no_mem;
1914 			}
1915 
1916 			pp = kmem_zalloc(sizeof (fasttrap_probe_t), KM_SLEEP);
1917 
1918 			pp->ftp_prov = provider;
1919 			pp->ftp_faddr = pdata->ftps_pc;
1920 			pp->ftp_fsize = pdata->ftps_size;
1921 			pp->ftp_pid = pdata->ftps_pid;
1922 			pp->ftp_ntps = 1;
1923 
1924 			tp = kmem_zalloc(sizeof (fasttrap_tracepoint_t),
1925 			    KM_SLEEP);
1926 
1927 			tp->ftt_proc = provider->ftp_proc;
1928 			tp->ftt_pc = pdata->ftps_offs[i] + pdata->ftps_pc;
1929 			tp->ftt_pid = pdata->ftps_pid;
1930 
1931 			pp->ftp_tps[0].fit_tp = tp;
1932 			pp->ftp_tps[0].fit_id.fti_probe = pp;
1933 			pp->ftp_tps[0].fit_id.fti_ptype = pdata->ftps_type;
1934 
1935 			pp->ftp_id = dtrace_probe_create(provider->ftp_provid,
1936 			    pdata->ftps_mod, pdata->ftps_func, name_str,
1937 			    FASTTRAP_OFFSET_AFRAMES, pp);
1938 		}
1939 
1940 	} else if (dtrace_probe_lookup(provider->ftp_provid, pdata->ftps_mod,
1941 	    pdata->ftps_func, name) == 0) {
1942 		atomic_add_32(&fasttrap_total, pdata->ftps_noffs);
1943 
1944 		if (fasttrap_total > fasttrap_max) {
1945 			atomic_add_32(&fasttrap_total, -pdata->ftps_noffs);
1946 			goto no_mem;
1947 		}
1948 
1949 		/*
1950 		 * Make sure all tracepoint program counter values are unique.
1951 		 * We later assume that each probe has exactly one tracepoint
1952 		 * for a given pc.
1953 		 */
1954 		qsort(pdata->ftps_offs, pdata->ftps_noffs,
1955 		    sizeof (uint64_t), fasttrap_uint64_cmp);
1956 		for (i = 1; i < pdata->ftps_noffs; i++) {
1957 			if (pdata->ftps_offs[i] > pdata->ftps_offs[i - 1])
1958 				continue;
1959 
1960 			atomic_add_32(&fasttrap_total, -pdata->ftps_noffs);
1961 			goto no_mem;
1962 		}
1963 
1964 		ASSERT(pdata->ftps_noffs > 0);
1965 		pp = kmem_zalloc(offsetof(fasttrap_probe_t,
1966 		    ftp_tps[pdata->ftps_noffs]), KM_SLEEP);
1967 
1968 		pp->ftp_prov = provider;
1969 		pp->ftp_faddr = pdata->ftps_pc;
1970 		pp->ftp_fsize = pdata->ftps_size;
1971 		pp->ftp_pid = pdata->ftps_pid;
1972 		pp->ftp_ntps = pdata->ftps_noffs;
1973 
1974 		for (i = 0; i < pdata->ftps_noffs; i++) {
1975 			tp = kmem_zalloc(sizeof (fasttrap_tracepoint_t),
1976 			    KM_SLEEP);
1977 
1978 			tp->ftt_proc = provider->ftp_proc;
1979 			tp->ftt_pc = pdata->ftps_offs[i] + pdata->ftps_pc;
1980 			tp->ftt_pid = pdata->ftps_pid;
1981 
1982 			pp->ftp_tps[i].fit_tp = tp;
1983 			pp->ftp_tps[i].fit_id.fti_probe = pp;
1984 			pp->ftp_tps[i].fit_id.fti_ptype = pdata->ftps_type;
1985 		}
1986 
1987 		pp->ftp_id = dtrace_probe_create(provider->ftp_provid,
1988 		    pdata->ftps_mod, pdata->ftps_func, name, aframes, pp);
1989 	}
1990 
1991 	mutex_exit(&provider->ftp_cmtx);
1992 
1993 	/*
1994 	 * We know that the provider is still valid since we incremented the
1995 	 * creation reference count. If someone tried to clean up this provider
1996 	 * while we were using it (e.g. because the process called exec(2) or
1997 	 * exit(2)), take note of that and try to clean it up now.
1998 	 */
1999 	mutex_enter(&provider->ftp_mtx);
2000 	provider->ftp_ccount--;
2001 	whack = provider->ftp_retired;
2002 	mutex_exit(&provider->ftp_mtx);
2003 
2004 	if (whack)
2005 		fasttrap_pid_cleanup();
2006 
2007 	return (0);
2008 
2009 no_mem:
2010 	/*
2011 	 * If we've exhausted the allowable resources, we'll try to remove
2012 	 * this provider to free some up. This is to cover the case where
2013 	 * the user has accidentally created many more probes than was
2014 	 * intended (e.g. pid123:::).
2015 	 */
2016 	mutex_exit(&provider->ftp_cmtx);
2017 	mutex_enter(&provider->ftp_mtx);
2018 	provider->ftp_ccount--;
2019 	provider->ftp_marked = 1;
2020 	mutex_exit(&provider->ftp_mtx);
2021 
2022 	fasttrap_pid_cleanup();
2023 
2024 	return (ENOMEM);
2025 }
2026 
2027 /*ARGSUSED*/
2028 static void *
2029 fasttrap_meta_provide(void *arg, dtrace_helper_provdesc_t *dhpv, pid_t pid)
2030 {
2031 	fasttrap_provider_t *provider;
2032 
2033 	/*
2034 	 * A 32-bit unsigned integer (like a pid for example) can be
2035 	 * expressed in 10 or fewer decimal digits. Make sure that we'll
2036 	 * have enough space for the provider name.
2037 	 */
2038 	if (strlen(dhpv->dthpv_provname) + 10 >=
2039 	    sizeof (provider->ftp_name)) {
2040 		printf("failed to instantiate provider %s: "
2041 		    "name too long to accomodate pid", dhpv->dthpv_provname);
2042 		return (NULL);
2043 	}
2044 
2045 	/*
2046 	 * Don't let folks spoof the true pid provider.
2047 	 */
2048 	if (strcmp(dhpv->dthpv_provname, FASTTRAP_PID_NAME) == 0) {
2049 		printf("failed to instantiate provider %s: "
2050 		    "%s is an invalid name", dhpv->dthpv_provname,
2051 		    FASTTRAP_PID_NAME);
2052 		return (NULL);
2053 	}
2054 
2055 	/*
2056 	 * The highest stability class that fasttrap supports is ISA; cap
2057 	 * the stability of the new provider accordingly.
2058 	 */
2059 	if (dhpv->dthpv_pattr.dtpa_provider.dtat_class > DTRACE_CLASS_ISA)
2060 		dhpv->dthpv_pattr.dtpa_provider.dtat_class = DTRACE_CLASS_ISA;
2061 	if (dhpv->dthpv_pattr.dtpa_mod.dtat_class > DTRACE_CLASS_ISA)
2062 		dhpv->dthpv_pattr.dtpa_mod.dtat_class = DTRACE_CLASS_ISA;
2063 	if (dhpv->dthpv_pattr.dtpa_func.dtat_class > DTRACE_CLASS_ISA)
2064 		dhpv->dthpv_pattr.dtpa_func.dtat_class = DTRACE_CLASS_ISA;
2065 	if (dhpv->dthpv_pattr.dtpa_name.dtat_class > DTRACE_CLASS_ISA)
2066 		dhpv->dthpv_pattr.dtpa_name.dtat_class = DTRACE_CLASS_ISA;
2067 	if (dhpv->dthpv_pattr.dtpa_args.dtat_class > DTRACE_CLASS_ISA)
2068 		dhpv->dthpv_pattr.dtpa_args.dtat_class = DTRACE_CLASS_ISA;
2069 
2070 	if ((provider = fasttrap_provider_lookup(pid, dhpv->dthpv_provname,
2071 	    &dhpv->dthpv_pattr)) == NULL) {
2072 		printf("failed to instantiate provider %s for "
2073 		    "process %u",  dhpv->dthpv_provname, (uint_t)pid);
2074 		return (NULL);
2075 	}
2076 
2077 	/*
2078 	 * Up the meta provider count so this provider isn't removed until
2079 	 * the meta provider has been told to remove it.
2080 	 */
2081 	provider->ftp_mcount++;
2082 
2083 	mutex_exit(&provider->ftp_mtx);
2084 
2085 	return (provider);
2086 }
2087 
2088 /*
2089  * We know a few things about our context here:  we know that the probe being
2090  * created doesn't already exist (DTrace won't load DOF at the same address
2091  * twice, even if explicitly told to do so) and we know that we are
2092  * single-threaded with respect to the meta provider machinery. Knowing that
2093  * this is a new probe and that there is no way for us to race with another
2094  * operation on this provider allows us an important optimization: we need not
2095  * lookup a probe before adding it.  Saving this lookup is important because
2096  * this code is in the fork path for processes with USDT probes, and lookups
2097  * here are potentially very expensive because of long hash conflicts on
2098  * module, function and name (DTrace doesn't hash on provider name).
2099  */
2100 /*ARGSUSED*/
2101 static void
2102 fasttrap_meta_create_probe(void *arg, void *parg,
2103     dtrace_helper_probedesc_t *dhpb)
2104 {
2105 	fasttrap_provider_t *provider = parg;
2106 	fasttrap_probe_t *pp;
2107 	fasttrap_tracepoint_t *tp;
2108 	int i, j;
2109 	uint32_t ntps;
2110 
2111 	/*
2112 	 * Since the meta provider count is non-zero we don't have to worry
2113 	 * about this provider disappearing.
2114 	 */
2115 	ASSERT(provider->ftp_mcount > 0);
2116 
2117 	/*
2118 	 * The offsets must be unique.
2119 	 */
2120 	qsort(dhpb->dthpb_offs, dhpb->dthpb_noffs, sizeof (uint32_t),
2121 	    fasttrap_uint32_cmp);
2122 	for (i = 1; i < dhpb->dthpb_noffs; i++) {
2123 		if (dhpb->dthpb_base + dhpb->dthpb_offs[i] <=
2124 		    dhpb->dthpb_base + dhpb->dthpb_offs[i - 1])
2125 			return;
2126 	}
2127 
2128 	qsort(dhpb->dthpb_enoffs, dhpb->dthpb_nenoffs, sizeof (uint32_t),
2129 	    fasttrap_uint32_cmp);
2130 	for (i = 1; i < dhpb->dthpb_nenoffs; i++) {
2131 		if (dhpb->dthpb_base + dhpb->dthpb_enoffs[i] <=
2132 		    dhpb->dthpb_base + dhpb->dthpb_enoffs[i - 1])
2133 			return;
2134 	}
2135 
2136 	ntps = dhpb->dthpb_noffs + dhpb->dthpb_nenoffs;
2137 	ASSERT(ntps > 0);
2138 
2139 	atomic_add_32(&fasttrap_total, ntps);
2140 
2141 	if (fasttrap_total > fasttrap_max) {
2142 		atomic_add_32(&fasttrap_total, -ntps);
2143 		return;
2144 	}
2145 
2146 	pp = kmem_zalloc(offsetof(fasttrap_probe_t, ftp_tps[ntps]), KM_SLEEP);
2147 
2148 	pp->ftp_prov = provider;
2149 	pp->ftp_pid = provider->ftp_pid;
2150 	pp->ftp_ntps = ntps;
2151 	pp->ftp_nargs = dhpb->dthpb_xargc;
2152 	pp->ftp_xtypes = dhpb->dthpb_xtypes;
2153 	pp->ftp_ntypes = dhpb->dthpb_ntypes;
2154 
2155 	/*
2156 	 * First create a tracepoint for each actual point of interest.
2157 	 */
2158 	for (i = 0; i < dhpb->dthpb_noffs; i++) {
2159 		tp = kmem_zalloc(sizeof (fasttrap_tracepoint_t), KM_SLEEP);
2160 
2161 		tp->ftt_proc = provider->ftp_proc;
2162 		tp->ftt_pc = dhpb->dthpb_base + dhpb->dthpb_offs[i];
2163 		tp->ftt_pid = provider->ftp_pid;
2164 
2165 		pp->ftp_tps[i].fit_tp = tp;
2166 		pp->ftp_tps[i].fit_id.fti_probe = pp;
2167 #ifdef __sparc
2168 		pp->ftp_tps[i].fit_id.fti_ptype = DTFTP_POST_OFFSETS;
2169 #else
2170 		pp->ftp_tps[i].fit_id.fti_ptype = DTFTP_OFFSETS;
2171 #endif
2172 	}
2173 
2174 	/*
2175 	 * Then create a tracepoint for each is-enabled point.
2176 	 */
2177 	for (j = 0; i < ntps; i++, j++) {
2178 		tp = kmem_zalloc(sizeof (fasttrap_tracepoint_t), KM_SLEEP);
2179 
2180 		tp->ftt_proc = provider->ftp_proc;
2181 		tp->ftt_pc = dhpb->dthpb_base + dhpb->dthpb_enoffs[j];
2182 		tp->ftt_pid = provider->ftp_pid;
2183 
2184 		pp->ftp_tps[i].fit_tp = tp;
2185 		pp->ftp_tps[i].fit_id.fti_probe = pp;
2186 		pp->ftp_tps[i].fit_id.fti_ptype = DTFTP_IS_ENABLED;
2187 	}
2188 
2189 	/*
2190 	 * If the arguments are shuffled around we set the argument remapping
2191 	 * table. Later, when the probe fires, we only remap the arguments
2192 	 * if the table is non-NULL.
2193 	 */
2194 	for (i = 0; i < dhpb->dthpb_xargc; i++) {
2195 		if (dhpb->dthpb_args[i] != i) {
2196 			pp->ftp_argmap = dhpb->dthpb_args;
2197 			break;
2198 		}
2199 	}
2200 
2201 	/*
2202 	 * The probe is fully constructed -- register it with DTrace.
2203 	 */
2204 	pp->ftp_id = dtrace_probe_create(provider->ftp_provid, dhpb->dthpb_mod,
2205 	    dhpb->dthpb_func, dhpb->dthpb_name, FASTTRAP_OFFSET_AFRAMES, pp);
2206 }
2207 
2208 /*ARGSUSED*/
2209 static void
2210 fasttrap_meta_remove(void *arg, dtrace_helper_provdesc_t *dhpv, pid_t pid)
2211 {
2212 	/*
2213 	 * Clean up the USDT provider. There may be active consumers of the
2214 	 * provider busy adding probes, no damage will actually befall the
2215 	 * provider until that count has dropped to zero. This just puts
2216 	 * the provider on death row.
2217 	 */
2218 	fasttrap_provider_retire(pid, dhpv->dthpv_provname, 1);
2219 }
2220 
2221 static dtrace_mops_t fasttrap_mops = {
2222 	.dtms_create_probe =	fasttrap_meta_create_probe,
2223 	.dtms_provide_pid =	fasttrap_meta_provide,
2224 	.dtms_remove_pid =	fasttrap_meta_remove
2225 };
2226 
2227 /*ARGSUSED*/
2228 static int
2229 fasttrap_open(struct cdev *dev __unused, int oflags __unused,
2230     int devtype __unused, struct thread *td __unused)
2231 {
2232 	return (0);
2233 }
2234 
2235 /*ARGSUSED*/
2236 static int
2237 fasttrap_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int fflag,
2238     struct thread *td)
2239 {
2240 	if (!dtrace_attached())
2241 		return (EAGAIN);
2242 
2243 	if (cmd == FASTTRAPIOC_MAKEPROBE) {
2244 		fasttrap_probe_spec_t *uprobe = *(fasttrap_probe_spec_t **)arg;
2245 		fasttrap_probe_spec_t *probe;
2246 		uint64_t noffs;
2247 		size_t size;
2248 		int ret, err;
2249 
2250 		if (copyin(&uprobe->ftps_noffs, &noffs,
2251 		    sizeof (uprobe->ftps_noffs)))
2252 			return (EFAULT);
2253 
2254 		/*
2255 		 * Probes must have at least one tracepoint.
2256 		 */
2257 		if (noffs == 0)
2258 			return (EINVAL);
2259 
2260 		size = sizeof (fasttrap_probe_spec_t) +
2261 		    sizeof (probe->ftps_offs[0]) * (noffs - 1);
2262 
2263 		if (size > 1024 * 1024)
2264 			return (ENOMEM);
2265 
2266 		probe = kmem_alloc(size, KM_SLEEP);
2267 
2268 		if (copyin(uprobe, probe, size) != 0 ||
2269 		    probe->ftps_noffs != noffs) {
2270 			kmem_free(probe, size);
2271 			return (EFAULT);
2272 		}
2273 
2274 		/*
2275 		 * Verify that the function and module strings contain no
2276 		 * funny characters.
2277 		 */
2278 		if (u8_validate(probe->ftps_func, strlen(probe->ftps_func),
2279 		    NULL, U8_VALIDATE_ENTIRE, &err) < 0) {
2280 			ret = EINVAL;
2281 			goto err;
2282 		}
2283 
2284 		if (u8_validate(probe->ftps_mod, strlen(probe->ftps_mod),
2285 		    NULL, U8_VALIDATE_ENTIRE, &err) < 0) {
2286 			ret = EINVAL;
2287 			goto err;
2288 		}
2289 
2290 #ifdef notyet
2291 		if (!PRIV_POLICY_CHOICE(cr, PRIV_ALL, B_FALSE)) {
2292 			proc_t *p;
2293 			pid_t pid = probe->ftps_pid;
2294 
2295 			mutex_enter(&pidlock);
2296 			/*
2297 			 * Report an error if the process doesn't exist
2298 			 * or is actively being birthed.
2299 			 */
2300 			if ((p = pfind(pid)) == NULL || p->p_stat == SIDL) {
2301 				mutex_exit(&pidlock);
2302 				return (ESRCH);
2303 			}
2304 			mutex_enter(&p->p_lock);
2305 			mutex_exit(&pidlock);
2306 
2307 			if ((ret = priv_proc_cred_perm(cr, p, NULL,
2308 			    VREAD | VWRITE)) != 0) {
2309 				mutex_exit(&p->p_lock);
2310 				return (ret);
2311 			}
2312 			mutex_exit(&p->p_lock);
2313 		}
2314 #endif /* notyet */
2315 
2316 		ret = fasttrap_add_probe(probe);
2317 err:
2318 		kmem_free(probe, size);
2319 
2320 		return (ret);
2321 
2322 	} else if (cmd == FASTTRAPIOC_GETINSTR) {
2323 		fasttrap_instr_query_t instr;
2324 		fasttrap_tracepoint_t *tp;
2325 		uint_t index;
2326 #ifdef notyet
2327 		int ret;
2328 #endif
2329 
2330 		if (copyin((void *)arg, &instr, sizeof (instr)) != 0)
2331 			return (EFAULT);
2332 
2333 #ifdef notyet
2334 		if (!PRIV_POLICY_CHOICE(cr, PRIV_ALL, B_FALSE)) {
2335 			proc_t *p;
2336 			pid_t pid = instr.ftiq_pid;
2337 
2338 			mutex_enter(&pidlock);
2339 			/*
2340 			 * Report an error if the process doesn't exist
2341 			 * or is actively being birthed.
2342 			 */
2343 			if ((p == pfind(pid)) == NULL || p->p_stat == SIDL) {
2344 				mutex_exit(&pidlock);
2345 				return (ESRCH);
2346 			}
2347 			mutex_enter(&p->p_lock);
2348 			mutex_exit(&pidlock);
2349 
2350 			if ((ret = priv_proc_cred_perm(cr, p, NULL,
2351 			    VREAD)) != 0) {
2352 				mutex_exit(&p->p_lock);
2353 				return (ret);
2354 			}
2355 
2356 			mutex_exit(&p->p_lock);
2357 		}
2358 #endif /* notyet */
2359 
2360 		index = FASTTRAP_TPOINTS_INDEX(instr.ftiq_pid, instr.ftiq_pc);
2361 
2362 		mutex_enter(&fasttrap_tpoints.fth_table[index].ftb_mtx);
2363 		tp = fasttrap_tpoints.fth_table[index].ftb_data;
2364 		while (tp != NULL) {
2365 			if (instr.ftiq_pid == tp->ftt_pid &&
2366 			    instr.ftiq_pc == tp->ftt_pc &&
2367 			    tp->ftt_proc->ftpc_acount != 0)
2368 				break;
2369 
2370 			tp = tp->ftt_next;
2371 		}
2372 
2373 		if (tp == NULL) {
2374 			mutex_exit(&fasttrap_tpoints.fth_table[index].ftb_mtx);
2375 			return (ENOENT);
2376 		}
2377 
2378 		bcopy(&tp->ftt_instr, &instr.ftiq_instr,
2379 		    sizeof (instr.ftiq_instr));
2380 		mutex_exit(&fasttrap_tpoints.fth_table[index].ftb_mtx);
2381 
2382 		if (copyout(&instr, (void *)arg, sizeof (instr)) != 0)
2383 			return (EFAULT);
2384 
2385 		return (0);
2386 	}
2387 
2388 	return (EINVAL);
2389 }
2390 
2391 static int
2392 fasttrap_load(void)
2393 {
2394 	ulong_t nent;
2395 	int i, ret;
2396 
2397         /* Create the /dev/dtrace/fasttrap entry. */
2398         fasttrap_cdev = make_dev(&fasttrap_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
2399             "dtrace/fasttrap");
2400 
2401 	mtx_init(&fasttrap_cleanup_mtx, "fasttrap clean", "dtrace", MTX_DEF);
2402 	mutex_init(&fasttrap_count_mtx, "fasttrap count mtx", MUTEX_DEFAULT,
2403 	    NULL);
2404 
2405 #ifdef illumos
2406 	fasttrap_max = ddi_getprop(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS,
2407 	    "fasttrap-max-probes", FASTTRAP_MAX_DEFAULT);
2408 #endif
2409 	fasttrap_total = 0;
2410 
2411 	/*
2412 	 * Conjure up the tracepoints hashtable...
2413 	 */
2414 #ifdef illumos
2415 	nent = ddi_getprop(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS,
2416 	    "fasttrap-hash-size", FASTTRAP_TPOINTS_DEFAULT_SIZE);
2417 #else
2418 	nent = tpoints_hash_size;
2419 #endif
2420 
2421 	if (nent == 0 || nent > 0x1000000)
2422 		nent = FASTTRAP_TPOINTS_DEFAULT_SIZE;
2423 
2424 	tpoints_hash_size = nent;
2425 
2426 	if (ISP2(nent))
2427 		fasttrap_tpoints.fth_nent = nent;
2428 	else
2429 		fasttrap_tpoints.fth_nent = 1 << fasttrap_highbit(nent);
2430 	ASSERT(fasttrap_tpoints.fth_nent > 0);
2431 	fasttrap_tpoints.fth_mask = fasttrap_tpoints.fth_nent - 1;
2432 	fasttrap_tpoints.fth_table = kmem_zalloc(fasttrap_tpoints.fth_nent *
2433 	    sizeof (fasttrap_bucket_t), KM_SLEEP);
2434 #ifndef illumos
2435 	for (i = 0; i < fasttrap_tpoints.fth_nent; i++)
2436 		mutex_init(&fasttrap_tpoints.fth_table[i].ftb_mtx,
2437 		    "tracepoints bucket mtx", MUTEX_DEFAULT, NULL);
2438 #endif
2439 
2440 	/*
2441 	 * ... and the providers hash table...
2442 	 */
2443 	nent = FASTTRAP_PROVIDERS_DEFAULT_SIZE;
2444 	if (ISP2(nent))
2445 		fasttrap_provs.fth_nent = nent;
2446 	else
2447 		fasttrap_provs.fth_nent = 1 << fasttrap_highbit(nent);
2448 	ASSERT(fasttrap_provs.fth_nent > 0);
2449 	fasttrap_provs.fth_mask = fasttrap_provs.fth_nent - 1;
2450 	fasttrap_provs.fth_table = kmem_zalloc(fasttrap_provs.fth_nent *
2451 	    sizeof (fasttrap_bucket_t), KM_SLEEP);
2452 #ifndef illumos
2453 	for (i = 0; i < fasttrap_provs.fth_nent; i++)
2454 		mutex_init(&fasttrap_provs.fth_table[i].ftb_mtx,
2455 		    "providers bucket mtx", MUTEX_DEFAULT, NULL);
2456 #endif
2457 
2458 	ret = kproc_create(fasttrap_pid_cleanup_cb, NULL,
2459 	    &fasttrap_cleanup_proc, 0, 0, "ftcleanup");
2460 	if (ret != 0) {
2461 		destroy_dev(fasttrap_cdev);
2462 #ifndef illumos
2463 		for (i = 0; i < fasttrap_provs.fth_nent; i++)
2464 			mutex_destroy(&fasttrap_provs.fth_table[i].ftb_mtx);
2465 		for (i = 0; i < fasttrap_tpoints.fth_nent; i++)
2466 			mutex_destroy(&fasttrap_tpoints.fth_table[i].ftb_mtx);
2467 #endif
2468 		kmem_free(fasttrap_provs.fth_table, fasttrap_provs.fth_nent *
2469 		    sizeof (fasttrap_bucket_t));
2470 		mtx_destroy(&fasttrap_cleanup_mtx);
2471 		mutex_destroy(&fasttrap_count_mtx);
2472 		return (ret);
2473 	}
2474 
2475 
2476 	/*
2477 	 * ... and the procs hash table.
2478 	 */
2479 	nent = FASTTRAP_PROCS_DEFAULT_SIZE;
2480 	if (ISP2(nent))
2481 		fasttrap_procs.fth_nent = nent;
2482 	else
2483 		fasttrap_procs.fth_nent = 1 << fasttrap_highbit(nent);
2484 	ASSERT(fasttrap_procs.fth_nent > 0);
2485 	fasttrap_procs.fth_mask = fasttrap_procs.fth_nent - 1;
2486 	fasttrap_procs.fth_table = kmem_zalloc(fasttrap_procs.fth_nent *
2487 	    sizeof (fasttrap_bucket_t), KM_SLEEP);
2488 #ifndef illumos
2489 	for (i = 0; i < fasttrap_procs.fth_nent; i++)
2490 		mutex_init(&fasttrap_procs.fth_table[i].ftb_mtx,
2491 		    "processes bucket mtx", MUTEX_DEFAULT, NULL);
2492 
2493 	rm_init(&fasttrap_tp_lock, "fasttrap tracepoint");
2494 
2495 	/*
2496 	 * This event handler must run before kdtrace_thread_dtor() since it
2497 	 * accesses the thread's struct kdtrace_thread.
2498 	 */
2499 	fasttrap_thread_dtor_tag = EVENTHANDLER_REGISTER(thread_dtor,
2500 	    fasttrap_thread_dtor, NULL, EVENTHANDLER_PRI_FIRST);
2501 #endif
2502 
2503 	/*
2504 	 * Install our hooks into fork(2), exec(2), and exit(2).
2505 	 */
2506 	dtrace_fasttrap_fork = &fasttrap_fork;
2507 	dtrace_fasttrap_exit = &fasttrap_exec_exit;
2508 	dtrace_fasttrap_exec = &fasttrap_exec_exit;
2509 
2510 	(void) dtrace_meta_register("fasttrap", &fasttrap_mops, NULL,
2511 	    &fasttrap_meta_id);
2512 
2513 	return (0);
2514 }
2515 
2516 static int
2517 fasttrap_unload(void)
2518 {
2519 	int i, fail = 0;
2520 
2521 	/*
2522 	 * Unregister the meta-provider to make sure no new fasttrap-
2523 	 * managed providers come along while we're trying to close up
2524 	 * shop. If we fail to detach, we'll need to re-register as a
2525 	 * meta-provider. We can fail to unregister as a meta-provider
2526 	 * if providers we manage still exist.
2527 	 */
2528 	if (fasttrap_meta_id != DTRACE_METAPROVNONE &&
2529 	    dtrace_meta_unregister(fasttrap_meta_id) != 0)
2530 		return (-1);
2531 
2532 	/*
2533 	 * Iterate over all of our providers. If there's still a process
2534 	 * that corresponds to that pid, fail to detach.
2535 	 */
2536 	for (i = 0; i < fasttrap_provs.fth_nent; i++) {
2537 		fasttrap_provider_t **fpp, *fp;
2538 		fasttrap_bucket_t *bucket = &fasttrap_provs.fth_table[i];
2539 
2540 		mutex_enter(&bucket->ftb_mtx);
2541 		fpp = (fasttrap_provider_t **)&bucket->ftb_data;
2542 		while ((fp = *fpp) != NULL) {
2543 			/*
2544 			 * Acquire and release the lock as a simple way of
2545 			 * waiting for any other consumer to finish with
2546 			 * this provider. A thread must first acquire the
2547 			 * bucket lock so there's no chance of another thread
2548 			 * blocking on the provider's lock.
2549 			 */
2550 			mutex_enter(&fp->ftp_mtx);
2551 			mutex_exit(&fp->ftp_mtx);
2552 
2553 			if (dtrace_unregister(fp->ftp_provid) != 0) {
2554 				fail = 1;
2555 				fpp = &fp->ftp_next;
2556 			} else {
2557 				*fpp = fp->ftp_next;
2558 				fasttrap_provider_free(fp);
2559 			}
2560 		}
2561 
2562 		mutex_exit(&bucket->ftb_mtx);
2563 	}
2564 
2565 	if (fail) {
2566 		(void) dtrace_meta_register("fasttrap", &fasttrap_mops, NULL,
2567 		    &fasttrap_meta_id);
2568 
2569 		return (-1);
2570 	}
2571 
2572 	/*
2573 	 * Stop new processes from entering these hooks now, before the
2574 	 * fasttrap_cleanup thread runs.  That way all processes will hopefully
2575 	 * be out of these hooks before we free fasttrap_provs.fth_table
2576 	 */
2577 	ASSERT(dtrace_fasttrap_fork == &fasttrap_fork);
2578 	dtrace_fasttrap_fork = NULL;
2579 
2580 	ASSERT(dtrace_fasttrap_exec == &fasttrap_exec_exit);
2581 	dtrace_fasttrap_exec = NULL;
2582 
2583 	ASSERT(dtrace_fasttrap_exit == &fasttrap_exec_exit);
2584 	dtrace_fasttrap_exit = NULL;
2585 
2586 	mtx_lock(&fasttrap_cleanup_mtx);
2587 	fasttrap_cleanup_drain = 1;
2588 	/* Wait for the cleanup thread to finish up and signal us. */
2589 	wakeup(&fasttrap_cleanup_cv);
2590 	mtx_sleep(&fasttrap_cleanup_drain, &fasttrap_cleanup_mtx, 0, "ftcld",
2591 	    0);
2592 	fasttrap_cleanup_proc = NULL;
2593 	mtx_destroy(&fasttrap_cleanup_mtx);
2594 
2595 #ifdef DEBUG
2596 	mutex_enter(&fasttrap_count_mtx);
2597 	ASSERT(fasttrap_pid_count == 0);
2598 	mutex_exit(&fasttrap_count_mtx);
2599 #endif
2600 
2601 #ifndef illumos
2602 	EVENTHANDLER_DEREGISTER(thread_dtor, fasttrap_thread_dtor_tag);
2603 
2604 	for (i = 0; i < fasttrap_tpoints.fth_nent; i++)
2605 		mutex_destroy(&fasttrap_tpoints.fth_table[i].ftb_mtx);
2606 	for (i = 0; i < fasttrap_provs.fth_nent; i++)
2607 		mutex_destroy(&fasttrap_provs.fth_table[i].ftb_mtx);
2608 	for (i = 0; i < fasttrap_procs.fth_nent; i++)
2609 		mutex_destroy(&fasttrap_procs.fth_table[i].ftb_mtx);
2610 #endif
2611 	kmem_free(fasttrap_tpoints.fth_table,
2612 	    fasttrap_tpoints.fth_nent * sizeof (fasttrap_bucket_t));
2613 	fasttrap_tpoints.fth_nent = 0;
2614 
2615 	kmem_free(fasttrap_provs.fth_table,
2616 	    fasttrap_provs.fth_nent * sizeof (fasttrap_bucket_t));
2617 	fasttrap_provs.fth_nent = 0;
2618 
2619 	kmem_free(fasttrap_procs.fth_table,
2620 	    fasttrap_procs.fth_nent * sizeof (fasttrap_bucket_t));
2621 	fasttrap_procs.fth_nent = 0;
2622 
2623 #ifndef illumos
2624 	destroy_dev(fasttrap_cdev);
2625 	mutex_destroy(&fasttrap_count_mtx);
2626 	rm_destroy(&fasttrap_tp_lock);
2627 #endif
2628 
2629 	return (0);
2630 }
2631 
2632 /* ARGSUSED */
2633 static int
2634 fasttrap_modevent(module_t mod __unused, int type, void *data __unused)
2635 {
2636 	int error = 0;
2637 
2638 	switch (type) {
2639 	case MOD_LOAD:
2640 		break;
2641 
2642 	case MOD_UNLOAD:
2643 		break;
2644 
2645 	case MOD_SHUTDOWN:
2646 		break;
2647 
2648 	default:
2649 		error = EOPNOTSUPP;
2650 		break;
2651 	}
2652 	return (error);
2653 }
2654 
2655 SYSINIT(fasttrap_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, fasttrap_load,
2656     NULL);
2657 SYSUNINIT(fasttrap_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY,
2658     fasttrap_unload, NULL);
2659 
2660 DEV_MODULE(fasttrap, fasttrap_modevent, NULL);
2661 MODULE_VERSION(fasttrap, 1);
2662 MODULE_DEPEND(fasttrap, dtrace, 1, 1, 1);
2663 MODULE_DEPEND(fasttrap, opensolaris, 1, 1, 1);
2664