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 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/atomic.h> 30 #include <sys/errno.h> 31 #include <sys/stat.h> 32 #include <sys/modctl.h> 33 #include <sys/conf.h> 34 #include <sys/systm.h> 35 #include <sys/ddi.h> 36 #include <sys/sunddi.h> 37 #include <sys/cpuvar.h> 38 #include <sys/kmem.h> 39 #include <sys/strsubr.h> 40 #include <sys/fasttrap.h> 41 #include <sys/fasttrap_impl.h> 42 #include <sys/fasttrap_isa.h> 43 #include <sys/dtrace.h> 44 #include <sys/dtrace_impl.h> 45 #include <sys/sysmacros.h> 46 #include <sys/frame.h> 47 #include <sys/stack.h> 48 #include <sys/proc.h> 49 #include <sys/priv.h> 50 #include <sys/policy.h> 51 #include <sys/ontrap.h> 52 #include <sys/vmsystm.h> 53 #include <sys/prsystm.h> 54 55 #include <vm/as.h> 56 #include <vm/seg.h> 57 #include <vm/seg_dev.h> 58 #include <vm/seg_vn.h> 59 #include <vm/seg_spt.h> 60 #include <vm/seg_kmem.h> 61 62 /* 63 * User-Land Trap-Based Tracing 64 * ---------------------------- 65 * 66 * The fasttrap provider allows DTrace consumers to instrument any user-level 67 * instruction to gather data; this includes probes with semantic 68 * signifigance like entry and return as well as simple offsets into the 69 * function. While the specific techniques used are very ISA specific, the 70 * methodology is generalizable to any architecture. 71 * 72 * 73 * The General Methodology 74 * ----------------------- 75 * 76 * With the primary goal of tracing every user-land instruction and the 77 * limitation that we can't trust user space so don't want to rely on much 78 * information there, we begin by replacing the instructions we want to trace 79 * with trap instructions. Each instruction we overwrite is saved into a hash 80 * table keyed by process ID and pc address. When we enter the kernel due to 81 * this trap instruction, we need the effects of the replaced instruction to 82 * appear to have occurred before we proceed with the user thread's 83 * execution. 84 * 85 * Each user level thread is represented by a ulwp_t structure which is 86 * always easily accessible through a register. The most basic way to produce 87 * the effects of the instruction we replaced is to copy that instruction out 88 * to a bit of scratch space reserved in the user thread's ulwp_t structure 89 * (a sort of kernel-private thread local storage), set the PC to that 90 * scratch space and single step. When we reenter the kernel after single 91 * stepping the instruction we must then adjust the PC to point to what would 92 * normally be the next instruction. Of course, special care must be taken 93 * for branches and jumps, but these represent such a small fraction of any 94 * instruction set that writing the code to emulate these in the kernel is 95 * not too difficult. 96 * 97 * Return probes may require several tracepoints to trace every return site, 98 * and, conversely, each tracepoint may activate several probes (the entry 99 * and offset 0 probes, for example). To solve this muliplexing problem, 100 * tracepoints contain lists of probes to activate and probes contain lists 101 * of tracepoints to enable. If a probe is activated, it adds its ID to 102 * existing tracepoints or creates new ones as necessary. 103 * 104 * Most probes are activated _before_ the instruction is executed, but return 105 * probes are activated _after_ the effects of the last instruction of the 106 * function are visible. Return probes must be fired _after_ we have 107 * single-stepped the instruction whereas all other probes are fired 108 * beforehand. 109 * 110 * 111 * Lock Ordering 112 * ------------- 113 * 114 * The lock ordering below -- both internally and with respect to the DTrace 115 * framework -- is a little tricky and bears some explanation. Each provider 116 * has a lock (ftp_mtx) that protects its members including reference counts 117 * for enabled probes (ftp_rcount), consumers actively creating probes 118 * (ftp_ccount) and USDT consumers (ftp_mcount); all three prevent a provider 119 * from being freed. A provider is looked up by taking the bucket lock for the 120 * provider hash table, and is returned with its lock held. The provider lock 121 * may be taken in functions invoked by the DTrace framework, but may not be 122 * held while calling functions in the DTrace framework. 123 * 124 * To ensure consistency over multiple calls to the DTrace framework, the 125 * creation lock (ftp_cmtx) should be held. Naturally, the creation lock may 126 * not be taken when holding the provider lock as that would create a cyclic 127 * lock ordering. In situations where one would naturally take the provider 128 * lock and then the creation lock, we instead up a reference count to prevent 129 * the provider from disappearing, drop the provider lock, and acquire the 130 * creation lock. 131 * 132 * Briefly: 133 * bucket lock before provider lock 134 * DTrace before provider lock 135 * creation lock before DTrace 136 * never hold the provider lock and creation lock simultaneously 137 */ 138 139 static dev_info_t *fasttrap_devi; 140 static dtrace_meta_provider_id_t fasttrap_meta_id; 141 142 static timeout_id_t fasttrap_timeout; 143 static kmutex_t fasttrap_cleanup_mtx; 144 static uint_t fasttrap_cleanup_work; 145 146 /* 147 * Generation count on modifications to the global tracepoint lookup table. 148 */ 149 static volatile uint64_t fasttrap_mod_gen; 150 151 /* 152 * When the fasttrap provider is loaded, fasttrap_max is set to either 153 * FASTTRAP_MAX_DEFAULT or the value for fasttrap-max-probes in the 154 * fasttrap.conf file. Each time a probe is created, fasttrap_total is 155 * incremented by the number of tracepoints that may be associated with that 156 * probe; fasttrap_total is capped at fasttrap_max. 157 */ 158 #define FASTTRAP_MAX_DEFAULT 250000 159 static uint32_t fasttrap_max; 160 static uint32_t fasttrap_total; 161 162 163 #define FASTTRAP_TPOINTS_DEFAULT_SIZE 0x4000 164 #define FASTTRAP_PROVIDERS_DEFAULT_SIZE 0x100 165 #define FASTTRAP_PROCS_DEFAULT_SIZE 0x100 166 167 #define FASTTRAP_PID_NAME "pid" 168 169 fasttrap_hash_t fasttrap_tpoints; 170 static fasttrap_hash_t fasttrap_provs; 171 static fasttrap_hash_t fasttrap_procs; 172 173 static uint64_t fasttrap_pid_count; /* pid ref count */ 174 static kmutex_t fasttrap_count_mtx; /* lock on ref count */ 175 176 #define FASTTRAP_ENABLE_FAIL 1 177 #define FASTTRAP_ENABLE_PARTIAL 2 178 179 static int fasttrap_tracepoint_enable(proc_t *, fasttrap_probe_t *, uint_t); 180 static void fasttrap_tracepoint_disable(proc_t *, fasttrap_probe_t *, uint_t); 181 182 static fasttrap_provider_t *fasttrap_provider_lookup(pid_t, const char *, 183 const dtrace_pattr_t *); 184 static void fasttrap_provider_retire(pid_t, const char *, int); 185 static void fasttrap_provider_free(fasttrap_provider_t *); 186 187 static fasttrap_proc_t *fasttrap_proc_lookup(pid_t); 188 static void fasttrap_proc_release(fasttrap_proc_t *); 189 190 #define FASTTRAP_PROVS_INDEX(pid, name) \ 191 ((fasttrap_hash_str(name) + (pid)) & fasttrap_provs.fth_mask) 192 193 #define FASTTRAP_PROCS_INDEX(pid) ((pid) & fasttrap_procs.fth_mask) 194 195 static int 196 fasttrap_highbit(ulong_t i) 197 { 198 int h = 1; 199 200 if (i == 0) 201 return (0); 202 #ifdef _LP64 203 if (i & 0xffffffff00000000ul) { 204 h += 32; i >>= 32; 205 } 206 #endif 207 if (i & 0xffff0000) { 208 h += 16; i >>= 16; 209 } 210 if (i & 0xff00) { 211 h += 8; i >>= 8; 212 } 213 if (i & 0xf0) { 214 h += 4; i >>= 4; 215 } 216 if (i & 0xc) { 217 h += 2; i >>= 2; 218 } 219 if (i & 0x2) { 220 h += 1; 221 } 222 return (h); 223 } 224 225 static uint_t 226 fasttrap_hash_str(const char *p) 227 { 228 unsigned int g; 229 uint_t hval = 0; 230 231 while (*p) { 232 hval = (hval << 4) + *p++; 233 if ((g = (hval & 0xf0000000)) != 0) 234 hval ^= g >> 24; 235 hval &= ~g; 236 } 237 return (hval); 238 } 239 240 void 241 fasttrap_sigtrap(proc_t *p, kthread_t *t, uintptr_t pc) 242 { 243 sigqueue_t *sqp = kmem_zalloc(sizeof (sigqueue_t), KM_SLEEP); 244 245 sqp->sq_info.si_signo = SIGTRAP; 246 sqp->sq_info.si_code = TRAP_DTRACE; 247 sqp->sq_info.si_addr = (caddr_t)pc; 248 249 mutex_enter(&p->p_lock); 250 sigaddqa(p, t, sqp); 251 mutex_exit(&p->p_lock); 252 253 if (t != NULL) 254 aston(t); 255 } 256 257 /* 258 * This function ensures that no threads are actively using the memory 259 * associated with probes that were formerly live. 260 */ 261 static void 262 fasttrap_mod_barrier(uint64_t gen) 263 { 264 int i; 265 266 if (gen < fasttrap_mod_gen) 267 return; 268 269 fasttrap_mod_gen++; 270 271 for (i = 0; i < NCPU; i++) { 272 mutex_enter(&cpu_core[i].cpuc_pid_lock); 273 mutex_exit(&cpu_core[i].cpuc_pid_lock); 274 } 275 } 276 277 /* 278 * This is the timeout's callback for cleaning up the providers and their 279 * probes. 280 */ 281 /*ARGSUSED*/ 282 static void 283 fasttrap_pid_cleanup_cb(void *data) 284 { 285 fasttrap_provider_t **fpp, *fp; 286 fasttrap_bucket_t *bucket; 287 dtrace_provider_id_t provid; 288 int i, later; 289 290 static volatile int in = 0; 291 ASSERT(in == 0); 292 in = 1; 293 294 mutex_enter(&fasttrap_cleanup_mtx); 295 while (fasttrap_cleanup_work) { 296 fasttrap_cleanup_work = 0; 297 mutex_exit(&fasttrap_cleanup_mtx); 298 299 later = 0; 300 301 /* 302 * Iterate over all the providers trying to remove the marked 303 * ones. If a provider is marked but not retired, we just 304 * have to take a crack at removing it -- it's no big deal if 305 * we can't. 306 */ 307 for (i = 0; i < fasttrap_provs.fth_nent; i++) { 308 bucket = &fasttrap_provs.fth_table[i]; 309 mutex_enter(&bucket->ftb_mtx); 310 fpp = (fasttrap_provider_t **)&bucket->ftb_data; 311 312 while ((fp = *fpp) != NULL) { 313 if (!fp->ftp_marked) { 314 fpp = &fp->ftp_next; 315 continue; 316 } 317 318 mutex_enter(&fp->ftp_mtx); 319 320 /* 321 * If this provider has consumers actively 322 * creating probes (ftp_ccount) or is a USDT 323 * provider (ftp_mcount), we can't unregister 324 * or even condense. 325 */ 326 if (fp->ftp_ccount != 0 || 327 fp->ftp_mcount != 0) { 328 mutex_exit(&fp->ftp_mtx); 329 fp->ftp_marked = 0; 330 continue; 331 } 332 333 if (!fp->ftp_retired || fp->ftp_rcount != 0) 334 fp->ftp_marked = 0; 335 336 mutex_exit(&fp->ftp_mtx); 337 338 /* 339 * If we successfully unregister this 340 * provider we can remove it from the hash 341 * chain and free the memory. If our attempt 342 * to unregister fails and this is a retired 343 * provider, increment our flag to try again 344 * pretty soon. If we've consumed more than 345 * half of our total permitted number of 346 * probes call dtrace_condense() to try to 347 * clean out the unenabled probes. 348 */ 349 provid = fp->ftp_provid; 350 if (dtrace_unregister(provid) != 0) { 351 if (fasttrap_total > fasttrap_max / 2) 352 (void) dtrace_condense(provid); 353 later += fp->ftp_marked; 354 fpp = &fp->ftp_next; 355 } else { 356 *fpp = fp->ftp_next; 357 fasttrap_provider_free(fp); 358 } 359 } 360 mutex_exit(&bucket->ftb_mtx); 361 } 362 363 mutex_enter(&fasttrap_cleanup_mtx); 364 } 365 366 ASSERT(fasttrap_timeout != 0); 367 368 /* 369 * If we were unable to remove a retired provider, try again after 370 * a second. This situation can occur in certain circumstances where 371 * providers cannot be unregistered even though they have no probes 372 * enabled because of an execution of dtrace -l or something similar. 373 * If the timeout has been disabled (set to 1 because we're trying 374 * to detach), we set fasttrap_cleanup_work to ensure that we'll 375 * get a chance to do that work if and when the timeout is reenabled 376 * (if detach fails). 377 */ 378 if (later > 0 && fasttrap_timeout != (timeout_id_t)1) 379 fasttrap_timeout = timeout(&fasttrap_pid_cleanup_cb, NULL, hz); 380 else if (later > 0) 381 fasttrap_cleanup_work = 1; 382 else 383 fasttrap_timeout = 0; 384 385 mutex_exit(&fasttrap_cleanup_mtx); 386 in = 0; 387 } 388 389 /* 390 * Activates the asynchronous cleanup mechanism. 391 */ 392 static void 393 fasttrap_pid_cleanup(void) 394 { 395 mutex_enter(&fasttrap_cleanup_mtx); 396 fasttrap_cleanup_work = 1; 397 if (fasttrap_timeout == 0) 398 fasttrap_timeout = timeout(&fasttrap_pid_cleanup_cb, NULL, 1); 399 mutex_exit(&fasttrap_cleanup_mtx); 400 } 401 402 /* 403 * This is called from cfork() via dtrace_fasttrap_fork(). The child 404 * process's address space is a (roughly) a copy of the parent process's so 405 * we have to remove all the instrumentation we had previously enabled in the 406 * parent. 407 */ 408 static void 409 fasttrap_fork(proc_t *p, proc_t *cp) 410 { 411 pid_t ppid = p->p_pid; 412 int i; 413 414 ASSERT(curproc == p); 415 ASSERT(p->p_proc_flag & P_PR_LOCK); 416 ASSERT(p->p_dtrace_count > 0); 417 ASSERT(cp->p_dtrace_count == 0); 418 419 /* 420 * This would be simpler and faster if we maintained per-process 421 * hash tables of enabled tracepoints. It could, however, potentially 422 * slow down execution of a tracepoint since we'd need to go 423 * through two levels of indirection. In the future, we should 424 * consider either maintaining per-process ancillary lists of 425 * enabled tracepoints or hanging a pointer to a per-process hash 426 * table of enabled tracepoints off the proc structure. 427 */ 428 429 /* 430 * We don't have to worry about the child process disappearing 431 * because we're in fork(). 432 */ 433 mutex_enter(&cp->p_lock); 434 sprlock_proc(cp); 435 mutex_exit(&cp->p_lock); 436 437 /* 438 * Iterate over every tracepoint looking for ones that belong to the 439 * parent process, and remove each from the child process. 440 */ 441 for (i = 0; i < fasttrap_tpoints.fth_nent; i++) { 442 fasttrap_tracepoint_t *tp; 443 fasttrap_bucket_t *bucket = &fasttrap_tpoints.fth_table[i]; 444 445 mutex_enter(&bucket->ftb_mtx); 446 for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) { 447 if (tp->ftt_pid == ppid && 448 !tp->ftt_proc->ftpc_defunct) { 449 int ret = fasttrap_tracepoint_remove(cp, tp); 450 ASSERT(ret == 0); 451 } 452 } 453 mutex_exit(&bucket->ftb_mtx); 454 } 455 456 mutex_enter(&cp->p_lock); 457 sprunlock(cp); 458 } 459 460 /* 461 * This is called from proc_exit() or from exec_common() if p_dtrace_probes 462 * is set on the proc structure to indicate that there is a pid provider 463 * associated with this process. 464 */ 465 static void 466 fasttrap_exec_exit(proc_t *p) 467 { 468 ASSERT(p == curproc); 469 ASSERT(MUTEX_HELD(&p->p_lock)); 470 471 mutex_exit(&p->p_lock); 472 473 /* 474 * We clean up the pid provider for this process here; user-land 475 * static probes are handled by the meta-provider remove entry point. 476 */ 477 fasttrap_provider_retire(p->p_pid, FASTTRAP_PID_NAME, 0); 478 479 mutex_enter(&p->p_lock); 480 } 481 482 483 /*ARGSUSED*/ 484 static void 485 fasttrap_pid_provide(void *arg, const dtrace_probedesc_t *desc) 486 { 487 /* 488 * There are no "default" pid probes. 489 */ 490 } 491 492 static int 493 fasttrap_tracepoint_enable(proc_t *p, fasttrap_probe_t *probe, uint_t index) 494 { 495 fasttrap_tracepoint_t *tp, *new_tp = NULL; 496 fasttrap_bucket_t *bucket; 497 fasttrap_id_t *id; 498 pid_t pid; 499 uintptr_t pc; 500 501 ASSERT(index < probe->ftp_ntps); 502 503 pid = probe->ftp_pid; 504 pc = probe->ftp_tps[index].fit_tp->ftt_pc; 505 id = &probe->ftp_tps[index].fit_id; 506 507 ASSERT(probe->ftp_tps[index].fit_tp->ftt_pid == pid); 508 509 ASSERT(!(p->p_flag & SVFORK)); 510 511 /* 512 * Before we make any modifications, make sure we've imposed a barrier 513 * on the generation in which this probe was last modified. 514 */ 515 fasttrap_mod_barrier(probe->ftp_gen); 516 517 bucket = &fasttrap_tpoints.fth_table[FASTTRAP_TPOINTS_INDEX(pid, pc)]; 518 519 /* 520 * If the tracepoint has already been enabled, just add our id to the 521 * list of interested probes. This may be our second time through 522 * this path in which case we'll have constructed the tracepoint we'd 523 * like to install. If we can't find a match, and have an allocated 524 * tracepoint ready to go, enable that one now. 525 * 526 * A tracepoint whose process is defunct is also considered defunct. 527 */ 528 again: 529 mutex_enter(&bucket->ftb_mtx); 530 for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) { 531 if (tp->ftt_pid != pid || tp->ftt_pc != pc || 532 tp->ftt_proc->ftpc_defunct) 533 continue; 534 535 /* 536 * Now that we've found a matching tracepoint, it would be 537 * a decent idea to confirm that the tracepoint is still 538 * enabled and the trap instruction hasn't been overwritten. 539 * Since this is a little hairy, we'll punt for now. 540 */ 541 542 /* 543 * This can't be the first interested probe. We don't have 544 * to worry about another thread being in the midst of 545 * deleting this tracepoint (which would be the only valid 546 * reason for a tracepoint to have no interested probes) 547 * since we're holding P_PR_LOCK for this process. 548 */ 549 ASSERT(tp->ftt_ids != NULL || tp->ftt_retids != NULL); 550 551 switch (id->fti_ptype) { 552 case DTFTP_ENTRY: 553 case DTFTP_OFFSETS: 554 case DTFTP_IS_ENABLED: 555 id->fti_next = tp->ftt_ids; 556 membar_producer(); 557 tp->ftt_ids = id; 558 membar_producer(); 559 break; 560 561 case DTFTP_RETURN: 562 case DTFTP_POST_OFFSETS: 563 id->fti_next = tp->ftt_retids; 564 membar_producer(); 565 tp->ftt_retids = id; 566 membar_producer(); 567 break; 568 569 default: 570 ASSERT(0); 571 } 572 573 mutex_exit(&bucket->ftb_mtx); 574 575 if (new_tp != NULL) { 576 new_tp->ftt_ids = NULL; 577 new_tp->ftt_retids = NULL; 578 } 579 580 return (0); 581 } 582 583 /* 584 * If we have a good tracepoint ready to go, install it now while 585 * we have the lock held and no one can screw with us. 586 */ 587 if (new_tp != NULL) { 588 int rc = 0; 589 590 new_tp->ftt_next = bucket->ftb_data; 591 membar_producer(); 592 bucket->ftb_data = new_tp; 593 membar_producer(); 594 mutex_exit(&bucket->ftb_mtx); 595 596 /* 597 * Activate the tracepoint in the ISA-specific manner. 598 * If this fails, we need to report the failure, but 599 * indicate that this tracepoint must still be disabled 600 * by calling fasttrap_tracepoint_disable(). 601 */ 602 if (fasttrap_tracepoint_install(p, new_tp) != 0) 603 rc = FASTTRAP_ENABLE_PARTIAL; 604 605 /* 606 * Increment the count of the number of tracepoints active in 607 * the victim process. 608 */ 609 ASSERT(p->p_proc_flag & P_PR_LOCK); 610 p->p_dtrace_count++; 611 612 return (rc); 613 } 614 615 mutex_exit(&bucket->ftb_mtx); 616 617 /* 618 * Initialize the tracepoint that's been preallocated with the probe. 619 */ 620 new_tp = probe->ftp_tps[index].fit_tp; 621 622 ASSERT(new_tp->ftt_pid == pid); 623 ASSERT(new_tp->ftt_pc == pc); 624 ASSERT(new_tp->ftt_proc == probe->ftp_prov->ftp_proc); 625 ASSERT(new_tp->ftt_ids == NULL); 626 ASSERT(new_tp->ftt_retids == NULL); 627 628 switch (id->fti_ptype) { 629 case DTFTP_ENTRY: 630 case DTFTP_OFFSETS: 631 case DTFTP_IS_ENABLED: 632 id->fti_next = NULL; 633 new_tp->ftt_ids = id; 634 break; 635 636 case DTFTP_RETURN: 637 case DTFTP_POST_OFFSETS: 638 id->fti_next = NULL; 639 new_tp->ftt_retids = id; 640 break; 641 642 default: 643 ASSERT(0); 644 } 645 646 /* 647 * If the ISA-dependent initialization goes to plan, go back to the 648 * beginning and try to install this freshly made tracepoint. 649 */ 650 if (fasttrap_tracepoint_init(p, new_tp, pc, id->fti_ptype) == 0) 651 goto again; 652 653 new_tp->ftt_ids = NULL; 654 new_tp->ftt_retids = NULL; 655 656 return (FASTTRAP_ENABLE_FAIL); 657 } 658 659 static void 660 fasttrap_tracepoint_disable(proc_t *p, fasttrap_probe_t *probe, uint_t index) 661 { 662 fasttrap_bucket_t *bucket; 663 fasttrap_provider_t *provider = probe->ftp_prov; 664 fasttrap_tracepoint_t **pp, *tp; 665 fasttrap_id_t *id, **idp; 666 pid_t pid; 667 uintptr_t pc; 668 669 ASSERT(index < probe->ftp_ntps); 670 671 pid = probe->ftp_pid; 672 pc = probe->ftp_tps[index].fit_tp->ftt_pc; 673 id = &probe->ftp_tps[index].fit_id; 674 675 ASSERT(probe->ftp_tps[index].fit_tp->ftt_pid == pid); 676 677 /* 678 * Find the tracepoint and make sure that our id is one of the 679 * ones registered with it. 680 */ 681 bucket = &fasttrap_tpoints.fth_table[FASTTRAP_TPOINTS_INDEX(pid, pc)]; 682 mutex_enter(&bucket->ftb_mtx); 683 for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) { 684 if (tp->ftt_pid == pid && tp->ftt_pc == pc && 685 tp->ftt_proc == provider->ftp_proc) 686 break; 687 } 688 689 /* 690 * If we somehow lost this tracepoint, we're in a world of hurt. 691 */ 692 ASSERT(tp != NULL); 693 694 switch (id->fti_ptype) { 695 case DTFTP_ENTRY: 696 case DTFTP_OFFSETS: 697 case DTFTP_IS_ENABLED: 698 ASSERT(tp->ftt_ids != NULL); 699 idp = &tp->ftt_ids; 700 break; 701 702 case DTFTP_RETURN: 703 case DTFTP_POST_OFFSETS: 704 ASSERT(tp->ftt_retids != NULL); 705 idp = &tp->ftt_retids; 706 break; 707 708 default: 709 ASSERT(0); 710 } 711 712 while ((*idp)->fti_probe != probe) { 713 idp = &(*idp)->fti_next; 714 ASSERT(*idp != NULL); 715 } 716 717 id = *idp; 718 *idp = id->fti_next; 719 membar_producer(); 720 721 ASSERT(id->fti_probe == probe); 722 723 /* 724 * If there are other registered enablings of this tracepoint, we're 725 * all done, but if this was the last probe assocated with this 726 * this tracepoint, we need to remove and free it. 727 */ 728 if (tp->ftt_ids != NULL || tp->ftt_retids != NULL) { 729 730 /* 731 * If the current probe's tracepoint is in use, swap it 732 * for an unused tracepoint. 733 */ 734 if (tp == probe->ftp_tps[index].fit_tp) { 735 fasttrap_probe_t *tmp_probe; 736 fasttrap_tracepoint_t **tmp_tp; 737 uint_t tmp_index; 738 739 if (tp->ftt_ids != NULL) { 740 tmp_probe = tp->ftt_ids->fti_probe; 741 tmp_index = FASTTRAP_ID_INDEX(tp->ftt_ids); 742 tmp_tp = &tmp_probe->ftp_tps[tmp_index].fit_tp; 743 } else { 744 tmp_probe = tp->ftt_retids->fti_probe; 745 tmp_index = FASTTRAP_ID_INDEX(tp->ftt_retids); 746 tmp_tp = &tmp_probe->ftp_tps[tmp_index].fit_tp; 747 } 748 749 ASSERT(*tmp_tp != NULL); 750 ASSERT(*tmp_tp != probe->ftp_tps[index].fit_tp); 751 ASSERT((*tmp_tp)->ftt_ids == NULL); 752 ASSERT((*tmp_tp)->ftt_retids == NULL); 753 754 probe->ftp_tps[index].fit_tp = *tmp_tp; 755 *tmp_tp = tp; 756 757 } 758 759 mutex_exit(&bucket->ftb_mtx); 760 761 /* 762 * Tag the modified probe with the generation in which it was 763 * changed. 764 */ 765 probe->ftp_gen = fasttrap_mod_gen; 766 return; 767 } 768 769 mutex_exit(&bucket->ftb_mtx); 770 771 /* 772 * We can't safely remove the tracepoint from the set of active 773 * tracepoints until we've actually removed the fasttrap instruction 774 * from the process's text. We can, however, operate on this 775 * tracepoint secure in the knowledge that no other thread is going to 776 * be looking at it since we hold P_PR_LOCK on the process if it's 777 * live or we hold the provider lock on the process if it's dead and 778 * gone. 779 */ 780 781 /* 782 * We only need to remove the actual instruction if we're looking 783 * at an existing process 784 */ 785 if (p != NULL) { 786 /* 787 * If we fail to restore the instruction we need to kill 788 * this process since it's in a completely unrecoverable 789 * state. 790 */ 791 if (fasttrap_tracepoint_remove(p, tp) != 0) 792 fasttrap_sigtrap(p, NULL, pc); 793 794 /* 795 * Decrement the count of the number of tracepoints active 796 * in the victim process. 797 */ 798 ASSERT(p->p_proc_flag & P_PR_LOCK); 799 p->p_dtrace_count--; 800 } 801 802 /* 803 * Remove the probe from the hash table of active tracepoints. 804 */ 805 mutex_enter(&bucket->ftb_mtx); 806 pp = (fasttrap_tracepoint_t **)&bucket->ftb_data; 807 ASSERT(*pp != NULL); 808 while (*pp != tp) { 809 pp = &(*pp)->ftt_next; 810 ASSERT(*pp != NULL); 811 } 812 813 *pp = tp->ftt_next; 814 membar_producer(); 815 816 mutex_exit(&bucket->ftb_mtx); 817 818 /* 819 * Tag the modified probe with the generation in which it was changed. 820 */ 821 probe->ftp_gen = fasttrap_mod_gen; 822 } 823 824 static void 825 fasttrap_enable_callbacks(void) 826 { 827 /* 828 * We don't have to play the rw lock game here because we're 829 * providing something rather than taking something away -- 830 * we can be sure that no threads have tried to follow this 831 * function pointer yet. 832 */ 833 mutex_enter(&fasttrap_count_mtx); 834 if (fasttrap_pid_count == 0) { 835 ASSERT(dtrace_pid_probe_ptr == NULL); 836 ASSERT(dtrace_return_probe_ptr == NULL); 837 dtrace_pid_probe_ptr = &fasttrap_pid_probe; 838 dtrace_return_probe_ptr = &fasttrap_return_probe; 839 } 840 ASSERT(dtrace_pid_probe_ptr == &fasttrap_pid_probe); 841 ASSERT(dtrace_return_probe_ptr == &fasttrap_return_probe); 842 fasttrap_pid_count++; 843 mutex_exit(&fasttrap_count_mtx); 844 } 845 846 static void 847 fasttrap_disable_callbacks(void) 848 { 849 ASSERT(MUTEX_HELD(&cpu_lock)); 850 851 mutex_enter(&fasttrap_count_mtx); 852 ASSERT(fasttrap_pid_count > 0); 853 fasttrap_pid_count--; 854 if (fasttrap_pid_count == 0) { 855 cpu_t *cur, *cpu = CPU; 856 857 for (cur = cpu->cpu_next_onln; cur != cpu; 858 cur = cur->cpu_next_onln) { 859 rw_enter(&cur->cpu_ft_lock, RW_WRITER); 860 } 861 862 dtrace_pid_probe_ptr = NULL; 863 dtrace_return_probe_ptr = NULL; 864 865 for (cur = cpu->cpu_next_onln; cur != cpu; 866 cur = cur->cpu_next_onln) { 867 rw_exit(&cur->cpu_ft_lock); 868 } 869 } 870 mutex_exit(&fasttrap_count_mtx); 871 } 872 873 /*ARGSUSED*/ 874 static void 875 fasttrap_pid_enable(void *arg, dtrace_id_t id, void *parg) 876 { 877 fasttrap_probe_t *probe = parg; 878 proc_t *p; 879 int i, rc; 880 881 ASSERT(probe != NULL); 882 ASSERT(!probe->ftp_enabled); 883 ASSERT(id == probe->ftp_id); 884 ASSERT(MUTEX_HELD(&cpu_lock)); 885 886 /* 887 * Increment the count of enabled probes on this probe's provider; 888 * the provider can't go away while the probe still exists. We 889 * must increment this even if we aren't able to properly enable 890 * this probe. 891 */ 892 mutex_enter(&probe->ftp_prov->ftp_mtx); 893 probe->ftp_prov->ftp_rcount++; 894 mutex_exit(&probe->ftp_prov->ftp_mtx); 895 896 /* 897 * If this probe's provider is retired (meaning it was valid in a 898 * previously exec'ed incarnation of this address space), bail out. The 899 * provider can't go away while we're in this code path. 900 */ 901 if (probe->ftp_prov->ftp_retired) 902 return; 903 904 /* 905 * If we can't find the process, it may be that we're in the context of 906 * a fork in which the traced process is being born and we're copying 907 * USDT probes. Otherwise, the process is gone so bail. 908 */ 909 if ((p = sprlock(probe->ftp_pid)) == NULL) { 910 if ((curproc->p_flag & SFORKING) == 0) 911 return; 912 913 mutex_enter(&pidlock); 914 p = prfind(probe->ftp_pid); 915 916 /* 917 * Confirm that curproc is indeed forking the process in which 918 * we're trying to enable probes. 919 */ 920 ASSERT(p != NULL); 921 ASSERT(p->p_parent == curproc); 922 ASSERT(p->p_stat == SIDL); 923 924 mutex_enter(&p->p_lock); 925 mutex_exit(&pidlock); 926 927 sprlock_proc(p); 928 } 929 930 ASSERT(!(p->p_flag & SVFORK)); 931 mutex_exit(&p->p_lock); 932 933 /* 934 * We have to enable the trap entry point before any user threads have 935 * the chance to execute the trap instruction we're about to place 936 * in their process's text. 937 */ 938 fasttrap_enable_callbacks(); 939 940 /* 941 * Enable all the tracepoints and add this probe's id to each 942 * tracepoint's list of active probes. 943 */ 944 for (i = 0; i < probe->ftp_ntps; i++) { 945 if ((rc = fasttrap_tracepoint_enable(p, probe, i)) != 0) { 946 /* 947 * If enabling the tracepoint failed completely, 948 * we don't have to disable it; if the failure 949 * was only partial we must disable it. 950 */ 951 if (rc == FASTTRAP_ENABLE_FAIL) 952 i--; 953 else 954 ASSERT(rc == FASTTRAP_ENABLE_PARTIAL); 955 956 /* 957 * Back up and pull out all the tracepoints we've 958 * created so far for this probe. 959 */ 960 while (i >= 0) { 961 fasttrap_tracepoint_disable(p, probe, i); 962 i--; 963 } 964 965 mutex_enter(&p->p_lock); 966 sprunlock(p); 967 968 /* 969 * Since we're not actually enabling this probe, 970 * drop our reference on the trap table entry. 971 */ 972 fasttrap_disable_callbacks(); 973 return; 974 } 975 } 976 977 mutex_enter(&p->p_lock); 978 sprunlock(p); 979 980 probe->ftp_enabled = 1; 981 } 982 983 /*ARGSUSED*/ 984 static void 985 fasttrap_pid_disable(void *arg, dtrace_id_t id, void *parg) 986 { 987 fasttrap_probe_t *probe = parg; 988 fasttrap_provider_t *provider = probe->ftp_prov; 989 proc_t *p; 990 int i, whack = 0; 991 992 if (!probe->ftp_enabled) { 993 mutex_enter(&provider->ftp_mtx); 994 provider->ftp_rcount--; 995 ASSERT(provider->ftp_rcount >= 0); 996 mutex_exit(&provider->ftp_mtx); 997 return; 998 } 999 1000 ASSERT(id == probe->ftp_id); 1001 1002 /* 1003 * We won't be able to acquire a /proc-esque lock on the process 1004 * iff the process is dead and gone. In this case, we rely on the 1005 * provider lock as a point of mutual exclusion to prevent other 1006 * DTrace consumers from disabling this probe. 1007 */ 1008 if ((p = sprlock(probe->ftp_pid)) != NULL) { 1009 ASSERT(!(p->p_flag & SVFORK)); 1010 mutex_exit(&p->p_lock); 1011 } 1012 1013 mutex_enter(&provider->ftp_mtx); 1014 1015 /* 1016 * Disable all the associated tracepoints. 1017 */ 1018 for (i = 0; i < probe->ftp_ntps; i++) { 1019 fasttrap_tracepoint_disable(p, probe, i); 1020 } 1021 1022 ASSERT(provider->ftp_rcount > 0); 1023 provider->ftp_rcount--; 1024 1025 if (p != NULL) { 1026 /* 1027 * Even though we may not be able to remove it entirely, we 1028 * mark this retired provider to get a chance to remove some 1029 * of the associated probes. 1030 */ 1031 if (provider->ftp_retired && !provider->ftp_marked) 1032 whack = provider->ftp_marked = 1; 1033 mutex_exit(&provider->ftp_mtx); 1034 1035 mutex_enter(&p->p_lock); 1036 sprunlock(p); 1037 } else { 1038 /* 1039 * If the process is dead, we're just waiting for the 1040 * last probe to be disabled to be able to free it. 1041 */ 1042 if (provider->ftp_rcount == 0 && !provider->ftp_marked) 1043 whack = provider->ftp_marked = 1; 1044 mutex_exit(&provider->ftp_mtx); 1045 } 1046 1047 if (whack) 1048 fasttrap_pid_cleanup(); 1049 1050 probe->ftp_enabled = 0; 1051 1052 ASSERT(MUTEX_HELD(&cpu_lock)); 1053 fasttrap_disable_callbacks(); 1054 } 1055 1056 /*ARGSUSED*/ 1057 static void 1058 fasttrap_pid_getargdesc(void *arg, dtrace_id_t id, void *parg, 1059 dtrace_argdesc_t *desc) 1060 { 1061 fasttrap_probe_t *probe = parg; 1062 char *str; 1063 int i; 1064 1065 desc->dtargd_native[0] = '\0'; 1066 desc->dtargd_xlate[0] = '\0'; 1067 1068 if (probe->ftp_prov->ftp_retired != 0 || 1069 desc->dtargd_ndx >= probe->ftp_nargs) { 1070 desc->dtargd_ndx = DTRACE_ARGNONE; 1071 return; 1072 } 1073 1074 /* 1075 * We only need to set this member if the argument is remapped. 1076 */ 1077 if (probe->ftp_argmap != NULL) 1078 desc->dtargd_mapping = probe->ftp_argmap[desc->dtargd_ndx]; 1079 1080 str = probe->ftp_ntypes; 1081 for (i = 0; i < desc->dtargd_mapping; i++) { 1082 str += strlen(str) + 1; 1083 } 1084 1085 ASSERT(strlen(str + 1) < sizeof (desc->dtargd_native)); 1086 (void) strcpy(desc->dtargd_native, str); 1087 1088 if (probe->ftp_xtypes == NULL) 1089 return; 1090 1091 str = probe->ftp_xtypes; 1092 for (i = 0; i < desc->dtargd_ndx; i++) { 1093 str += strlen(str) + 1; 1094 } 1095 1096 ASSERT(strlen(str + 1) < sizeof (desc->dtargd_xlate)); 1097 (void) strcpy(desc->dtargd_xlate, str); 1098 } 1099 1100 /*ARGSUSED*/ 1101 static void 1102 fasttrap_pid_destroy(void *arg, dtrace_id_t id, void *parg) 1103 { 1104 fasttrap_probe_t *probe = parg; 1105 int i; 1106 size_t size; 1107 1108 ASSERT(probe != NULL); 1109 ASSERT(!probe->ftp_enabled); 1110 ASSERT(fasttrap_total >= probe->ftp_ntps); 1111 1112 atomic_add_32(&fasttrap_total, -probe->ftp_ntps); 1113 size = offsetof(fasttrap_probe_t, ftp_tps[probe->ftp_ntps]); 1114 1115 if (probe->ftp_gen + 1 >= fasttrap_mod_gen) 1116 fasttrap_mod_barrier(probe->ftp_gen); 1117 1118 for (i = 0; i < probe->ftp_ntps; i++) { 1119 kmem_free(probe->ftp_tps[i].fit_tp, 1120 sizeof (fasttrap_tracepoint_t)); 1121 } 1122 1123 kmem_free(probe, size); 1124 } 1125 1126 1127 static const dtrace_pattr_t pid_attr = { 1128 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_ISA }, 1129 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN }, 1130 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN }, 1131 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_ISA }, 1132 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN }, 1133 }; 1134 1135 static dtrace_pops_t pid_pops = { 1136 fasttrap_pid_provide, 1137 NULL, 1138 fasttrap_pid_enable, 1139 fasttrap_pid_disable, 1140 NULL, 1141 NULL, 1142 fasttrap_pid_getargdesc, 1143 fasttrap_pid_getarg, 1144 NULL, 1145 fasttrap_pid_destroy 1146 }; 1147 1148 static dtrace_pops_t usdt_pops = { 1149 fasttrap_pid_provide, 1150 NULL, 1151 fasttrap_pid_enable, 1152 fasttrap_pid_disable, 1153 NULL, 1154 NULL, 1155 fasttrap_pid_getargdesc, 1156 fasttrap_usdt_getarg, 1157 NULL, 1158 fasttrap_pid_destroy 1159 }; 1160 1161 static fasttrap_proc_t * 1162 fasttrap_proc_lookup(pid_t pid) 1163 { 1164 fasttrap_bucket_t *bucket; 1165 fasttrap_proc_t *fprc, *new_fprc; 1166 1167 bucket = &fasttrap_procs.fth_table[FASTTRAP_PROCS_INDEX(pid)]; 1168 mutex_enter(&bucket->ftb_mtx); 1169 1170 for (fprc = bucket->ftb_data; fprc != NULL; fprc = fprc->ftpc_next) { 1171 if (fprc->ftpc_pid == pid && !fprc->ftpc_defunct) { 1172 mutex_enter(&fprc->ftpc_mtx); 1173 mutex_exit(&bucket->ftb_mtx); 1174 fprc->ftpc_count++; 1175 mutex_exit(&fprc->ftpc_mtx); 1176 1177 return (fprc); 1178 } 1179 } 1180 1181 /* 1182 * Drop the bucket lock so we don't try to perform a sleeping 1183 * allocation under it. 1184 */ 1185 mutex_exit(&bucket->ftb_mtx); 1186 1187 new_fprc = kmem_zalloc(sizeof (fasttrap_proc_t), KM_SLEEP); 1188 new_fprc->ftpc_pid = pid; 1189 new_fprc->ftpc_count = 1; 1190 1191 mutex_enter(&bucket->ftb_mtx); 1192 1193 /* 1194 * Take another lap through the list to make sure a proc hasn't 1195 * been created for this pid while we weren't under the bucket lock. 1196 */ 1197 for (fprc = bucket->ftb_data; fprc != NULL; fprc = fprc->ftpc_next) { 1198 if (fprc->ftpc_pid == pid && !fprc->ftpc_defunct) { 1199 mutex_enter(&fprc->ftpc_mtx); 1200 mutex_exit(&bucket->ftb_mtx); 1201 fprc->ftpc_count++; 1202 mutex_exit(&fprc->ftpc_mtx); 1203 1204 kmem_free(new_fprc, sizeof (fasttrap_proc_t)); 1205 1206 return (fprc); 1207 } 1208 } 1209 1210 new_fprc->ftpc_next = bucket->ftb_data; 1211 bucket->ftb_data = new_fprc; 1212 1213 mutex_exit(&bucket->ftb_mtx); 1214 1215 return (new_fprc); 1216 } 1217 1218 static void 1219 fasttrap_proc_release(fasttrap_proc_t *proc) 1220 { 1221 fasttrap_bucket_t *bucket; 1222 fasttrap_proc_t *fprc, **fprcp; 1223 pid_t pid = proc->ftpc_pid; 1224 1225 mutex_enter(&proc->ftpc_mtx); 1226 1227 ASSERT(proc->ftpc_count != 0); 1228 1229 if (--proc->ftpc_count != 0) { 1230 mutex_exit(&proc->ftpc_mtx); 1231 return; 1232 } 1233 1234 mutex_exit(&proc->ftpc_mtx); 1235 1236 bucket = &fasttrap_procs.fth_table[FASTTRAP_PROCS_INDEX(pid)]; 1237 mutex_enter(&bucket->ftb_mtx); 1238 1239 fprcp = (fasttrap_proc_t **)&bucket->ftb_data; 1240 while ((fprc = *fprcp) != NULL) { 1241 if (fprc == proc) 1242 break; 1243 1244 fprcp = &fprc->ftpc_next; 1245 } 1246 1247 /* 1248 * Something strange has happened if we can't find the proc. 1249 */ 1250 ASSERT(fprc != NULL); 1251 1252 *fprcp = fprc->ftpc_next; 1253 1254 mutex_exit(&bucket->ftb_mtx); 1255 1256 kmem_free(fprc, sizeof (fasttrap_proc_t)); 1257 } 1258 1259 /* 1260 * Lookup a fasttrap-managed provider based on its name and associated pid. 1261 * If the pattr argument is non-NULL, this function instantiates the provider 1262 * if it doesn't exist otherwise it returns NULL. The provider is returned 1263 * with its lock held. 1264 */ 1265 static fasttrap_provider_t * 1266 fasttrap_provider_lookup(pid_t pid, const char *name, 1267 const dtrace_pattr_t *pattr) 1268 { 1269 fasttrap_provider_t *fp, *new_fp = NULL; 1270 fasttrap_bucket_t *bucket; 1271 char provname[DTRACE_PROVNAMELEN]; 1272 proc_t *p; 1273 cred_t *cred; 1274 1275 ASSERT(strlen(name) < sizeof (fp->ftp_name)); 1276 ASSERT(pattr != NULL); 1277 1278 bucket = &fasttrap_provs.fth_table[FASTTRAP_PROVS_INDEX(pid, name)]; 1279 mutex_enter(&bucket->ftb_mtx); 1280 1281 /* 1282 * Take a lap through the list and return the match if we find it. 1283 */ 1284 for (fp = bucket->ftb_data; fp != NULL; fp = fp->ftp_next) { 1285 if (fp->ftp_pid == pid && strcmp(fp->ftp_name, name) == 0 && 1286 !fp->ftp_retired) { 1287 mutex_enter(&fp->ftp_mtx); 1288 mutex_exit(&bucket->ftb_mtx); 1289 return (fp); 1290 } 1291 } 1292 1293 /* 1294 * Drop the bucket lock so we don't try to perform a sleeping 1295 * allocation under it. 1296 */ 1297 mutex_exit(&bucket->ftb_mtx); 1298 1299 /* 1300 * Make sure the process exists, isn't a child created as the result 1301 * of a vfork(2), and isn't a zombie (but may be in fork). 1302 */ 1303 mutex_enter(&pidlock); 1304 if ((p = prfind(pid)) == NULL) { 1305 mutex_exit(&pidlock); 1306 return (NULL); 1307 } 1308 mutex_enter(&p->p_lock); 1309 mutex_exit(&pidlock); 1310 if (p->p_flag & (SVFORK | SEXITING)) { 1311 mutex_exit(&p->p_lock); 1312 return (NULL); 1313 } 1314 1315 /* 1316 * Increment p_dtrace_probes so that the process knows to inform us 1317 * when it exits or execs. fasttrap_provider_free() decrements this 1318 * when we're done with this provider. 1319 */ 1320 p->p_dtrace_probes++; 1321 1322 /* 1323 * Grab the credentials for this process so we have 1324 * something to pass to dtrace_register(). 1325 */ 1326 mutex_enter(&p->p_crlock); 1327 crhold(p->p_cred); 1328 cred = p->p_cred; 1329 mutex_exit(&p->p_crlock); 1330 mutex_exit(&p->p_lock); 1331 1332 new_fp = kmem_zalloc(sizeof (fasttrap_provider_t), KM_SLEEP); 1333 new_fp->ftp_pid = pid; 1334 new_fp->ftp_proc = fasttrap_proc_lookup(pid); 1335 1336 ASSERT(new_fp->ftp_proc != NULL); 1337 1338 mutex_enter(&bucket->ftb_mtx); 1339 1340 /* 1341 * Take another lap through the list to make sure a provider hasn't 1342 * been created for this pid while we weren't under the bucket lock. 1343 */ 1344 for (fp = bucket->ftb_data; fp != NULL; fp = fp->ftp_next) { 1345 if (fp->ftp_pid == pid && strcmp(fp->ftp_name, name) == 0 && 1346 !fp->ftp_retired) { 1347 mutex_enter(&fp->ftp_mtx); 1348 mutex_exit(&bucket->ftb_mtx); 1349 fasttrap_provider_free(new_fp); 1350 crfree(cred); 1351 return (fp); 1352 } 1353 } 1354 1355 (void) strcpy(new_fp->ftp_name, name); 1356 1357 /* 1358 * Fail and return NULL if either the provider name is too long 1359 * or we fail to register this new provider with the DTrace 1360 * framework. Note that this is the only place we ever construct 1361 * the full provider name -- we keep it in pieces in the provider 1362 * structure. 1363 */ 1364 if (snprintf(provname, sizeof (provname), "%s%u", name, (uint_t)pid) >= 1365 sizeof (provname) || 1366 dtrace_register(provname, pattr, 1367 DTRACE_PRIV_PROC | DTRACE_PRIV_OWNER | DTRACE_PRIV_ZONEOWNER, cred, 1368 pattr == &pid_attr ? &pid_pops : &usdt_pops, new_fp, 1369 &new_fp->ftp_provid) != 0) { 1370 mutex_exit(&bucket->ftb_mtx); 1371 fasttrap_provider_free(new_fp); 1372 crfree(cred); 1373 return (NULL); 1374 } 1375 1376 new_fp->ftp_next = bucket->ftb_data; 1377 bucket->ftb_data = new_fp; 1378 1379 mutex_enter(&new_fp->ftp_mtx); 1380 mutex_exit(&bucket->ftb_mtx); 1381 1382 crfree(cred); 1383 return (new_fp); 1384 } 1385 1386 static void 1387 fasttrap_provider_free(fasttrap_provider_t *provider) 1388 { 1389 pid_t pid = provider->ftp_pid; 1390 proc_t *p; 1391 1392 /* 1393 * There need to be no associated enabled probes, no consumers 1394 * creating probes, and no meta providers referencing this provider. 1395 */ 1396 ASSERT(provider->ftp_rcount == 0); 1397 ASSERT(provider->ftp_ccount == 0); 1398 ASSERT(provider->ftp_mcount == 0); 1399 1400 fasttrap_proc_release(provider->ftp_proc); 1401 1402 kmem_free(provider, sizeof (fasttrap_provider_t)); 1403 1404 /* 1405 * Decrement p_dtrace_probes on the process whose provider we're 1406 * freeing. We don't have to worry about clobbering somone else's 1407 * modifications to it because we have locked the bucket that 1408 * corresponds to this process's hash chain in the provider hash 1409 * table. Don't sweat it if we can't find the process. 1410 */ 1411 mutex_enter(&pidlock); 1412 if ((p = prfind(pid)) == NULL) { 1413 mutex_exit(&pidlock); 1414 return; 1415 } 1416 1417 mutex_enter(&p->p_lock); 1418 mutex_exit(&pidlock); 1419 1420 p->p_dtrace_probes--; 1421 mutex_exit(&p->p_lock); 1422 } 1423 1424 static void 1425 fasttrap_provider_retire(pid_t pid, const char *name, int mprov) 1426 { 1427 fasttrap_provider_t *fp; 1428 fasttrap_bucket_t *bucket; 1429 dtrace_provider_id_t provid; 1430 1431 ASSERT(strlen(name) < sizeof (fp->ftp_name)); 1432 1433 bucket = &fasttrap_provs.fth_table[FASTTRAP_PROVS_INDEX(pid, name)]; 1434 mutex_enter(&bucket->ftb_mtx); 1435 1436 for (fp = bucket->ftb_data; fp != NULL; fp = fp->ftp_next) { 1437 if (fp->ftp_pid == pid && strcmp(fp->ftp_name, name) == 0 && 1438 !fp->ftp_retired) 1439 break; 1440 } 1441 1442 if (fp == NULL) { 1443 mutex_exit(&bucket->ftb_mtx); 1444 return; 1445 } 1446 1447 mutex_enter(&fp->ftp_mtx); 1448 ASSERT(!mprov || fp->ftp_mcount > 0); 1449 if (mprov && --fp->ftp_mcount != 0) { 1450 mutex_exit(&fp->ftp_mtx); 1451 mutex_exit(&bucket->ftb_mtx); 1452 return; 1453 } 1454 1455 /* 1456 * Mark the provider to be removed in our post-processing step, 1457 * mark it retired, and mark its proc as defunct (though it may 1458 * already be marked defunct by another provider that shares the 1459 * same proc). Marking it indicates that we should try to remove it; 1460 * setting the retired flag indicates that we're done with this 1461 * provider; setting the proc to be defunct indicates that all 1462 * tracepoints associated with the traced process should be ignored. 1463 * 1464 * We obviously need to take the bucket lock before the provider lock 1465 * to perform the lookup, but we need to drop the provider lock 1466 * before calling into the DTrace framework since we acquire the 1467 * provider lock in callbacks invoked from the DTrace framework. The 1468 * bucket lock therefore protects the integrity of the provider hash 1469 * table. 1470 */ 1471 fp->ftp_proc->ftpc_defunct = 1; 1472 fp->ftp_retired = 1; 1473 fp->ftp_marked = 1; 1474 provid = fp->ftp_provid; 1475 mutex_exit(&fp->ftp_mtx); 1476 1477 /* 1478 * We don't have to worry about invalidating the same provider twice 1479 * since fasttrap_provider_lookup() will ignore provider that have 1480 * been marked as retired. 1481 */ 1482 dtrace_invalidate(provid); 1483 1484 mutex_exit(&bucket->ftb_mtx); 1485 1486 fasttrap_pid_cleanup(); 1487 } 1488 1489 static int 1490 fasttrap_add_probe(fasttrap_probe_spec_t *pdata) 1491 { 1492 fasttrap_provider_t *provider; 1493 fasttrap_probe_t *pp; 1494 fasttrap_tracepoint_t *tp; 1495 char *name; 1496 int i, aframes, whack; 1497 1498 switch (pdata->ftps_type) { 1499 case DTFTP_ENTRY: 1500 name = "entry"; 1501 aframes = FASTTRAP_ENTRY_AFRAMES; 1502 break; 1503 case DTFTP_RETURN: 1504 name = "return"; 1505 aframes = FASTTRAP_RETURN_AFRAMES; 1506 break; 1507 case DTFTP_OFFSETS: 1508 name = NULL; 1509 break; 1510 default: 1511 return (EINVAL); 1512 } 1513 1514 if ((provider = fasttrap_provider_lookup(pdata->ftps_pid, 1515 FASTTRAP_PID_NAME, &pid_attr)) == NULL) 1516 return (ESRCH); 1517 1518 /* 1519 * Increment this reference count to indicate that a consumer is 1520 * actively adding a new probe associated with this provider. This 1521 * prevents the provider from being deleted -- we'll need to check 1522 * for pending deletions when we drop this reference count. 1523 */ 1524 provider->ftp_ccount++; 1525 mutex_exit(&provider->ftp_mtx); 1526 1527 /* 1528 * Grab the creation lock to ensure consistency between calls to 1529 * dtrace_probe_lookup() and dtrace_probe_create() in the face of 1530 * other threads creating probes. We must drop the provider lock 1531 * before taking this lock to avoid a three-way deadlock with the 1532 * DTrace framework. 1533 */ 1534 mutex_enter(&provider->ftp_cmtx); 1535 1536 if (name == NULL) { 1537 for (i = 0; i < pdata->ftps_noffs; i++) { 1538 char name_str[17]; 1539 1540 (void) sprintf(name_str, "%llx", 1541 (unsigned long long)pdata->ftps_offs[i]); 1542 1543 if (dtrace_probe_lookup(provider->ftp_provid, 1544 pdata->ftps_mod, pdata->ftps_func, name_str) != 0) 1545 continue; 1546 1547 atomic_add_32(&fasttrap_total, 1); 1548 1549 if (fasttrap_total > fasttrap_max) { 1550 atomic_add_32(&fasttrap_total, -1); 1551 goto no_mem; 1552 } 1553 1554 pp = kmem_zalloc(sizeof (fasttrap_probe_t), KM_SLEEP); 1555 1556 pp->ftp_prov = provider; 1557 pp->ftp_faddr = pdata->ftps_pc; 1558 pp->ftp_fsize = pdata->ftps_size; 1559 pp->ftp_pid = pdata->ftps_pid; 1560 pp->ftp_ntps = 1; 1561 1562 tp = kmem_zalloc(sizeof (fasttrap_tracepoint_t), 1563 KM_SLEEP); 1564 1565 tp->ftt_proc = provider->ftp_proc; 1566 tp->ftt_pc = pdata->ftps_offs[i] + pdata->ftps_pc; 1567 tp->ftt_pid = pdata->ftps_pid; 1568 1569 pp->ftp_tps[0].fit_tp = tp; 1570 pp->ftp_tps[0].fit_id.fti_probe = pp; 1571 pp->ftp_tps[0].fit_id.fti_ptype = pdata->ftps_type; 1572 1573 pp->ftp_id = dtrace_probe_create(provider->ftp_provid, 1574 pdata->ftps_mod, pdata->ftps_func, name_str, 1575 FASTTRAP_OFFSET_AFRAMES, pp); 1576 } 1577 1578 } else if (dtrace_probe_lookup(provider->ftp_provid, pdata->ftps_mod, 1579 pdata->ftps_func, name) == 0) { 1580 atomic_add_32(&fasttrap_total, pdata->ftps_noffs); 1581 1582 if (fasttrap_total > fasttrap_max) { 1583 atomic_add_32(&fasttrap_total, -pdata->ftps_noffs); 1584 goto no_mem; 1585 } 1586 1587 ASSERT(pdata->ftps_noffs > 0); 1588 pp = kmem_zalloc(offsetof(fasttrap_probe_t, 1589 ftp_tps[pdata->ftps_noffs]), KM_SLEEP); 1590 1591 pp->ftp_prov = provider; 1592 pp->ftp_faddr = pdata->ftps_pc; 1593 pp->ftp_fsize = pdata->ftps_size; 1594 pp->ftp_pid = pdata->ftps_pid; 1595 pp->ftp_ntps = pdata->ftps_noffs; 1596 1597 for (i = 0; i < pdata->ftps_noffs; i++) { 1598 tp = kmem_zalloc(sizeof (fasttrap_tracepoint_t), 1599 KM_SLEEP); 1600 1601 tp->ftt_proc = provider->ftp_proc; 1602 tp->ftt_pc = pdata->ftps_offs[i] + pdata->ftps_pc; 1603 tp->ftt_pid = pdata->ftps_pid; 1604 1605 pp->ftp_tps[i].fit_tp = tp; 1606 pp->ftp_tps[i].fit_id.fti_probe = pp; 1607 pp->ftp_tps[i].fit_id.fti_ptype = pdata->ftps_type; 1608 } 1609 1610 pp->ftp_id = dtrace_probe_create(provider->ftp_provid, 1611 pdata->ftps_mod, pdata->ftps_func, name, aframes, pp); 1612 } 1613 1614 mutex_exit(&provider->ftp_cmtx); 1615 1616 /* 1617 * We know that the provider is still valid since we incremented the 1618 * creation reference count. If someone tried to clean up this provider 1619 * while we were using it (e.g. because the process called exec(2) or 1620 * exit(2)), take note of that and try to clean it up now. 1621 */ 1622 mutex_enter(&provider->ftp_mtx); 1623 provider->ftp_ccount--; 1624 whack = provider->ftp_retired; 1625 mutex_exit(&provider->ftp_mtx); 1626 1627 if (whack) 1628 fasttrap_pid_cleanup(); 1629 1630 return (0); 1631 1632 no_mem: 1633 /* 1634 * If we've exhausted the allowable resources, we'll try to remove 1635 * this provider to free some up. This is to cover the case where 1636 * the user has accidentally created many more probes than was 1637 * intended (e.g. pid123:::). 1638 */ 1639 mutex_exit(&provider->ftp_cmtx); 1640 mutex_enter(&provider->ftp_mtx); 1641 provider->ftp_ccount--; 1642 provider->ftp_marked = 1; 1643 mutex_exit(&provider->ftp_mtx); 1644 1645 fasttrap_pid_cleanup(); 1646 1647 return (ENOMEM); 1648 } 1649 1650 /*ARGSUSED*/ 1651 static void * 1652 fasttrap_meta_provide(void *arg, dtrace_helper_provdesc_t *dhpv, pid_t pid) 1653 { 1654 fasttrap_provider_t *provider; 1655 1656 /* 1657 * A 32-bit unsigned integer (like a pid for example) can be 1658 * expressed in 10 or fewer decimal digits. Make sure that we'll 1659 * have enough space for the provider name. 1660 */ 1661 if (strlen(dhpv->dthpv_provname) + 10 >= 1662 sizeof (provider->ftp_name)) { 1663 cmn_err(CE_WARN, "failed to instantiate provider %s: " 1664 "name too long to accomodate pid", dhpv->dthpv_provname); 1665 return (NULL); 1666 } 1667 1668 /* 1669 * Don't let folks spoof the true pid provider. 1670 */ 1671 if (strcmp(dhpv->dthpv_provname, FASTTRAP_PID_NAME) == 0) { 1672 cmn_err(CE_WARN, "failed to instantiate provider %s: " 1673 "%s is an invalid name", dhpv->dthpv_provname, 1674 FASTTRAP_PID_NAME); 1675 return (NULL); 1676 } 1677 1678 /* 1679 * The highest stability class that fasttrap supports is ISA; cap 1680 * the stability of the new provider accordingly. 1681 */ 1682 if (dhpv->dthpv_pattr.dtpa_provider.dtat_class >= DTRACE_CLASS_COMMON) 1683 dhpv->dthpv_pattr.dtpa_provider.dtat_class = DTRACE_CLASS_ISA; 1684 if (dhpv->dthpv_pattr.dtpa_mod.dtat_class >= DTRACE_CLASS_COMMON) 1685 dhpv->dthpv_pattr.dtpa_mod.dtat_class = DTRACE_CLASS_ISA; 1686 if (dhpv->dthpv_pattr.dtpa_func.dtat_class >= DTRACE_CLASS_COMMON) 1687 dhpv->dthpv_pattr.dtpa_func.dtat_class = DTRACE_CLASS_ISA; 1688 if (dhpv->dthpv_pattr.dtpa_name.dtat_class >= DTRACE_CLASS_COMMON) 1689 dhpv->dthpv_pattr.dtpa_name.dtat_class = DTRACE_CLASS_ISA; 1690 if (dhpv->dthpv_pattr.dtpa_args.dtat_class >= DTRACE_CLASS_COMMON) 1691 dhpv->dthpv_pattr.dtpa_args.dtat_class = DTRACE_CLASS_ISA; 1692 1693 if ((provider = fasttrap_provider_lookup(pid, dhpv->dthpv_provname, 1694 &dhpv->dthpv_pattr)) == NULL) { 1695 cmn_err(CE_WARN, "failed to instantiate provider %s for " 1696 "process %u", dhpv->dthpv_provname, (uint_t)pid); 1697 return (NULL); 1698 } 1699 1700 /* 1701 * Up the meta provider count so this provider isn't removed until 1702 * the meta provider has been told to remove it. 1703 */ 1704 provider->ftp_mcount++; 1705 1706 mutex_exit(&provider->ftp_mtx); 1707 1708 return (provider); 1709 } 1710 1711 /*ARGSUSED*/ 1712 static void 1713 fasttrap_meta_create_probe(void *arg, void *parg, 1714 dtrace_helper_probedesc_t *dhpb) 1715 { 1716 fasttrap_provider_t *provider = parg; 1717 fasttrap_probe_t *pp; 1718 fasttrap_tracepoint_t *tp; 1719 int i, j; 1720 uint32_t ntps; 1721 1722 /* 1723 * Since the meta provider count is non-zero we don't have to worry 1724 * about this provider disappearing. 1725 */ 1726 ASSERT(provider->ftp_mcount > 0); 1727 1728 /* 1729 * Grab the creation lock to ensure consistency between calls to 1730 * dtrace_probe_lookup() and dtrace_probe_create() in the face of 1731 * other threads creating probes. 1732 */ 1733 mutex_enter(&provider->ftp_cmtx); 1734 1735 if (dtrace_probe_lookup(provider->ftp_provid, dhpb->dthpb_mod, 1736 dhpb->dthpb_func, dhpb->dthpb_name) != 0) { 1737 mutex_exit(&provider->ftp_cmtx); 1738 return; 1739 } 1740 1741 ntps = dhpb->dthpb_noffs + dhpb->dthpb_nenoffs; 1742 ASSERT(ntps > 0); 1743 1744 atomic_add_32(&fasttrap_total, ntps); 1745 1746 if (fasttrap_total > fasttrap_max) { 1747 atomic_add_32(&fasttrap_total, -ntps); 1748 mutex_exit(&provider->ftp_cmtx); 1749 return; 1750 } 1751 1752 pp = kmem_zalloc(offsetof(fasttrap_probe_t, ftp_tps[ntps]), KM_SLEEP); 1753 1754 pp->ftp_prov = provider; 1755 pp->ftp_pid = provider->ftp_pid; 1756 pp->ftp_ntps = ntps; 1757 pp->ftp_nargs = dhpb->dthpb_xargc; 1758 pp->ftp_xtypes = dhpb->dthpb_xtypes; 1759 pp->ftp_ntypes = dhpb->dthpb_ntypes; 1760 1761 /* 1762 * First create a tracepoint for each actual point of interest. 1763 */ 1764 for (i = 0; i < dhpb->dthpb_noffs; i++) { 1765 tp = kmem_zalloc(sizeof (fasttrap_tracepoint_t), KM_SLEEP); 1766 1767 tp->ftt_proc = provider->ftp_proc; 1768 tp->ftt_pc = dhpb->dthpb_base + dhpb->dthpb_offs[i]; 1769 tp->ftt_pid = provider->ftp_pid; 1770 1771 pp->ftp_tps[i].fit_tp = tp; 1772 pp->ftp_tps[i].fit_id.fti_probe = pp; 1773 #ifdef __sparc 1774 pp->ftp_tps[i].fit_id.fti_ptype = DTFTP_POST_OFFSETS; 1775 #else 1776 pp->ftp_tps[i].fit_id.fti_ptype = DTFTP_OFFSETS; 1777 #endif 1778 } 1779 1780 /* 1781 * Then create a tracepoint for each is-enabled point. 1782 */ 1783 for (j = 0; i < ntps; i++, j++) { 1784 tp = kmem_zalloc(sizeof (fasttrap_tracepoint_t), KM_SLEEP); 1785 1786 tp->ftt_proc = provider->ftp_proc; 1787 tp->ftt_pc = dhpb->dthpb_base + dhpb->dthpb_enoffs[j]; 1788 tp->ftt_pid = provider->ftp_pid; 1789 1790 pp->ftp_tps[i].fit_tp = tp; 1791 pp->ftp_tps[i].fit_id.fti_probe = pp; 1792 pp->ftp_tps[i].fit_id.fti_ptype = DTFTP_IS_ENABLED; 1793 } 1794 1795 /* 1796 * If the arguments are shuffled around we set the argument remapping 1797 * table. Later, when the probe fires, we only remap the arguments 1798 * if the table is non-NULL. 1799 */ 1800 for (i = 0; i < dhpb->dthpb_xargc; i++) { 1801 if (dhpb->dthpb_args[i] != i) { 1802 pp->ftp_argmap = dhpb->dthpb_args; 1803 break; 1804 } 1805 } 1806 1807 /* 1808 * The probe is fully constructed -- register it with DTrace. 1809 */ 1810 pp->ftp_id = dtrace_probe_create(provider->ftp_provid, dhpb->dthpb_mod, 1811 dhpb->dthpb_func, dhpb->dthpb_name, FASTTRAP_OFFSET_AFRAMES, pp); 1812 1813 mutex_exit(&provider->ftp_cmtx); 1814 } 1815 1816 /*ARGSUSED*/ 1817 static void 1818 fasttrap_meta_remove(void *arg, dtrace_helper_provdesc_t *dhpv, pid_t pid) 1819 { 1820 /* 1821 * Clean up the USDT provider. There may be active consumers of the 1822 * provider busy adding probes, no damage will actually befall the 1823 * provider until that count has dropped to zero. This just puts 1824 * the provider on death row. 1825 */ 1826 fasttrap_provider_retire(pid, dhpv->dthpv_provname, 1); 1827 } 1828 1829 static dtrace_mops_t fasttrap_mops = { 1830 fasttrap_meta_create_probe, 1831 fasttrap_meta_provide, 1832 fasttrap_meta_remove 1833 }; 1834 1835 /*ARGSUSED*/ 1836 static int 1837 fasttrap_open(dev_t *devp, int flag, int otyp, cred_t *cred_p) 1838 { 1839 return (0); 1840 } 1841 1842 /*ARGSUSED*/ 1843 static int 1844 fasttrap_ioctl(dev_t dev, int cmd, intptr_t arg, int md, cred_t *cr, int *rv) 1845 { 1846 if (!dtrace_attached()) 1847 return (EAGAIN); 1848 1849 if (cmd == FASTTRAPIOC_MAKEPROBE) { 1850 fasttrap_probe_spec_t *uprobe = (void *)arg; 1851 fasttrap_probe_spec_t *probe; 1852 uint64_t noffs; 1853 size_t size; 1854 int ret; 1855 char *c; 1856 1857 if (copyin(&uprobe->ftps_noffs, &noffs, 1858 sizeof (uprobe->ftps_noffs))) 1859 return (EFAULT); 1860 1861 /* 1862 * Probes must have at least one tracepoint. 1863 */ 1864 if (noffs == 0) 1865 return (EINVAL); 1866 1867 size = sizeof (fasttrap_probe_spec_t) + 1868 sizeof (probe->ftps_offs[0]) * (noffs - 1); 1869 1870 if (size > 1024 * 1024) 1871 return (ENOMEM); 1872 1873 probe = kmem_alloc(size, KM_SLEEP); 1874 1875 if (copyin(uprobe, probe, size) != 0) { 1876 kmem_free(probe, size); 1877 return (EFAULT); 1878 } 1879 1880 /* 1881 * Verify that the function and module strings contain no 1882 * funny characters. 1883 */ 1884 for (c = &probe->ftps_func[0]; *c != '\0'; c++) { 1885 if (*c < 0x20 || 0x7f <= *c) { 1886 ret = EINVAL; 1887 goto err; 1888 } 1889 } 1890 1891 for (c = &probe->ftps_mod[0]; *c != '\0'; c++) { 1892 if (*c < 0x20 || 0x7f <= *c) { 1893 ret = EINVAL; 1894 goto err; 1895 } 1896 } 1897 1898 if (!PRIV_POLICY_CHOICE(cr, PRIV_ALL, B_FALSE)) { 1899 proc_t *p; 1900 pid_t pid = probe->ftps_pid; 1901 1902 mutex_enter(&pidlock); 1903 /* 1904 * Report an error if the process doesn't exist 1905 * or is actively being birthed. 1906 */ 1907 if ((p = prfind(pid)) == NULL || p->p_stat == SIDL) { 1908 mutex_exit(&pidlock); 1909 return (ESRCH); 1910 } 1911 mutex_enter(&p->p_lock); 1912 mutex_exit(&pidlock); 1913 1914 if ((ret = priv_proc_cred_perm(cr, p, NULL, 1915 VREAD | VWRITE)) != 0) { 1916 mutex_exit(&p->p_lock); 1917 return (ret); 1918 } 1919 1920 mutex_exit(&p->p_lock); 1921 } 1922 1923 ret = fasttrap_add_probe(probe); 1924 err: 1925 kmem_free(probe, size); 1926 1927 return (ret); 1928 1929 } else if (cmd == FASTTRAPIOC_GETINSTR) { 1930 fasttrap_instr_query_t instr; 1931 fasttrap_tracepoint_t *tp; 1932 uint_t index; 1933 int ret; 1934 1935 if (copyin((void *)arg, &instr, sizeof (instr)) != 0) 1936 return (EFAULT); 1937 1938 if (!PRIV_POLICY_CHOICE(cr, PRIV_ALL, B_FALSE)) { 1939 proc_t *p; 1940 pid_t pid = instr.ftiq_pid; 1941 1942 mutex_enter(&pidlock); 1943 /* 1944 * Report an error if the process doesn't exist 1945 * or is actively being birthed. 1946 */ 1947 if ((p = prfind(pid)) == NULL || p->p_stat == SIDL) { 1948 mutex_exit(&pidlock); 1949 return (ESRCH); 1950 } 1951 mutex_enter(&p->p_lock); 1952 mutex_exit(&pidlock); 1953 1954 if ((ret = priv_proc_cred_perm(cr, p, NULL, 1955 VREAD)) != 0) { 1956 mutex_exit(&p->p_lock); 1957 return (ret); 1958 } 1959 1960 mutex_exit(&p->p_lock); 1961 } 1962 1963 index = FASTTRAP_TPOINTS_INDEX(instr.ftiq_pid, instr.ftiq_pc); 1964 1965 mutex_enter(&fasttrap_tpoints.fth_table[index].ftb_mtx); 1966 tp = fasttrap_tpoints.fth_table[index].ftb_data; 1967 while (tp != NULL) { 1968 if (instr.ftiq_pid == tp->ftt_pid && 1969 instr.ftiq_pc == tp->ftt_pc && 1970 !tp->ftt_proc->ftpc_defunct) 1971 break; 1972 1973 tp = tp->ftt_next; 1974 } 1975 1976 if (tp == NULL) { 1977 mutex_exit(&fasttrap_tpoints.fth_table[index].ftb_mtx); 1978 return (ENOENT); 1979 } 1980 1981 bcopy(&tp->ftt_instr, &instr.ftiq_instr, 1982 sizeof (instr.ftiq_instr)); 1983 mutex_exit(&fasttrap_tpoints.fth_table[index].ftb_mtx); 1984 1985 if (copyout(&instr, (void *)arg, sizeof (instr)) != 0) 1986 return (EFAULT); 1987 1988 return (0); 1989 } 1990 1991 return (EINVAL); 1992 } 1993 1994 static struct cb_ops fasttrap_cb_ops = { 1995 fasttrap_open, /* open */ 1996 nodev, /* close */ 1997 nulldev, /* strategy */ 1998 nulldev, /* print */ 1999 nodev, /* dump */ 2000 nodev, /* read */ 2001 nodev, /* write */ 2002 fasttrap_ioctl, /* ioctl */ 2003 nodev, /* devmap */ 2004 nodev, /* mmap */ 2005 nodev, /* segmap */ 2006 nochpoll, /* poll */ 2007 ddi_prop_op, /* cb_prop_op */ 2008 0, /* streamtab */ 2009 D_NEW | D_MP /* Driver compatibility flag */ 2010 }; 2011 2012 /*ARGSUSED*/ 2013 static int 2014 fasttrap_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 2015 { 2016 int error; 2017 2018 switch (infocmd) { 2019 case DDI_INFO_DEVT2DEVINFO: 2020 *result = (void *)fasttrap_devi; 2021 error = DDI_SUCCESS; 2022 break; 2023 case DDI_INFO_DEVT2INSTANCE: 2024 *result = (void *)0; 2025 error = DDI_SUCCESS; 2026 break; 2027 default: 2028 error = DDI_FAILURE; 2029 } 2030 return (error); 2031 } 2032 2033 static int 2034 fasttrap_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) 2035 { 2036 ulong_t nent; 2037 2038 switch (cmd) { 2039 case DDI_ATTACH: 2040 break; 2041 case DDI_RESUME: 2042 return (DDI_SUCCESS); 2043 default: 2044 return (DDI_FAILURE); 2045 } 2046 2047 if (ddi_create_minor_node(devi, "fasttrap", S_IFCHR, 0, 2048 DDI_PSEUDO, NULL) == DDI_FAILURE) { 2049 ddi_remove_minor_node(devi, NULL); 2050 return (DDI_FAILURE); 2051 } 2052 2053 ddi_report_dev(devi); 2054 fasttrap_devi = devi; 2055 2056 /* 2057 * Install our hooks into fork(2), exec(2), and exit(2). 2058 */ 2059 dtrace_fasttrap_fork_ptr = &fasttrap_fork; 2060 dtrace_fasttrap_exit_ptr = &fasttrap_exec_exit; 2061 dtrace_fasttrap_exec_ptr = &fasttrap_exec_exit; 2062 2063 fasttrap_max = ddi_getprop(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS, 2064 "fasttrap-max-probes", FASTTRAP_MAX_DEFAULT); 2065 fasttrap_total = 0; 2066 2067 /* 2068 * Conjure up the tracepoints hashtable... 2069 */ 2070 nent = ddi_getprop(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS, 2071 "fasttrap-hash-size", FASTTRAP_TPOINTS_DEFAULT_SIZE); 2072 2073 if (nent <= 0 || nent > 0x1000000) 2074 nent = FASTTRAP_TPOINTS_DEFAULT_SIZE; 2075 2076 if ((nent & (nent - 1)) == 0) 2077 fasttrap_tpoints.fth_nent = nent; 2078 else 2079 fasttrap_tpoints.fth_nent = 1 << fasttrap_highbit(nent); 2080 ASSERT(fasttrap_tpoints.fth_nent > 0); 2081 fasttrap_tpoints.fth_mask = fasttrap_tpoints.fth_nent - 1; 2082 fasttrap_tpoints.fth_table = kmem_zalloc(fasttrap_tpoints.fth_nent * 2083 sizeof (fasttrap_bucket_t), KM_SLEEP); 2084 2085 /* 2086 * ... and the providers hash table... 2087 */ 2088 nent = FASTTRAP_PROVIDERS_DEFAULT_SIZE; 2089 if ((nent & (nent - 1)) == 0) 2090 fasttrap_provs.fth_nent = nent; 2091 else 2092 fasttrap_provs.fth_nent = 1 << fasttrap_highbit(nent); 2093 ASSERT(fasttrap_provs.fth_nent > 0); 2094 fasttrap_provs.fth_mask = fasttrap_provs.fth_nent - 1; 2095 fasttrap_provs.fth_table = kmem_zalloc(fasttrap_provs.fth_nent * 2096 sizeof (fasttrap_bucket_t), KM_SLEEP); 2097 2098 /* 2099 * ... and the procs hash table. 2100 */ 2101 nent = FASTTRAP_PROCS_DEFAULT_SIZE; 2102 if ((nent & (nent - 1)) == 0) 2103 fasttrap_procs.fth_nent = nent; 2104 else 2105 fasttrap_procs.fth_nent = 1 << fasttrap_highbit(nent); 2106 ASSERT(fasttrap_procs.fth_nent > 0); 2107 fasttrap_procs.fth_mask = fasttrap_procs.fth_nent - 1; 2108 fasttrap_procs.fth_table = kmem_zalloc(fasttrap_procs.fth_nent * 2109 sizeof (fasttrap_bucket_t), KM_SLEEP); 2110 2111 (void) dtrace_meta_register("fasttrap", &fasttrap_mops, NULL, 2112 &fasttrap_meta_id); 2113 2114 return (DDI_SUCCESS); 2115 } 2116 2117 static int 2118 fasttrap_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) 2119 { 2120 int i, fail = 0; 2121 timeout_id_t tmp; 2122 2123 switch (cmd) { 2124 case DDI_DETACH: 2125 break; 2126 case DDI_SUSPEND: 2127 return (DDI_SUCCESS); 2128 default: 2129 return (DDI_FAILURE); 2130 } 2131 2132 /* 2133 * Unregister the meta-provider to make sure no new fasttrap- 2134 * managed providers come along while we're trying to close up 2135 * shop. If we fail to detach, we'll need to re-register as a 2136 * meta-provider. We can fail to unregister as a meta-provider 2137 * if providers we manage still exist. 2138 */ 2139 if (fasttrap_meta_id != DTRACE_METAPROVNONE && 2140 dtrace_meta_unregister(fasttrap_meta_id) != 0) 2141 return (DDI_FAILURE); 2142 2143 /* 2144 * Prevent any new timeouts from running by setting fasttrap_timeout 2145 * to a non-zero value, and wait for the current timeout to complete. 2146 */ 2147 mutex_enter(&fasttrap_cleanup_mtx); 2148 fasttrap_cleanup_work = 0; 2149 2150 while (fasttrap_timeout != (timeout_id_t)1) { 2151 tmp = fasttrap_timeout; 2152 fasttrap_timeout = (timeout_id_t)1; 2153 2154 if (tmp != 0) { 2155 mutex_exit(&fasttrap_cleanup_mtx); 2156 (void) untimeout(tmp); 2157 mutex_enter(&fasttrap_cleanup_mtx); 2158 } 2159 } 2160 2161 fasttrap_cleanup_work = 0; 2162 mutex_exit(&fasttrap_cleanup_mtx); 2163 2164 /* 2165 * Iterate over all of our providers. If there's still a process 2166 * that corresponds to that pid, fail to detach. 2167 */ 2168 for (i = 0; i < fasttrap_provs.fth_nent; i++) { 2169 fasttrap_provider_t **fpp, *fp; 2170 fasttrap_bucket_t *bucket = &fasttrap_provs.fth_table[i]; 2171 2172 mutex_enter(&bucket->ftb_mtx); 2173 fpp = (fasttrap_provider_t **)&bucket->ftb_data; 2174 while ((fp = *fpp) != NULL) { 2175 /* 2176 * Acquire and release the lock as a simple way of 2177 * waiting for any other consumer to finish with 2178 * this provider. A thread must first acquire the 2179 * bucket lock so there's no chance of another thread 2180 * blocking on the provider's lock. 2181 */ 2182 mutex_enter(&fp->ftp_mtx); 2183 mutex_exit(&fp->ftp_mtx); 2184 2185 if (dtrace_unregister(fp->ftp_provid) != 0) { 2186 fail = 1; 2187 fpp = &fp->ftp_next; 2188 } else { 2189 *fpp = fp->ftp_next; 2190 fasttrap_provider_free(fp); 2191 } 2192 } 2193 2194 mutex_exit(&bucket->ftb_mtx); 2195 } 2196 2197 if (fail) { 2198 uint_t work; 2199 /* 2200 * If we're failing to detach, we need to unblock timeouts 2201 * and start a new timeout if any work has accumulated while 2202 * we've been unsuccessfully trying to detach. 2203 */ 2204 mutex_enter(&fasttrap_cleanup_mtx); 2205 fasttrap_timeout = 0; 2206 work = fasttrap_cleanup_work; 2207 mutex_exit(&fasttrap_cleanup_mtx); 2208 2209 if (work) 2210 fasttrap_pid_cleanup(); 2211 2212 (void) dtrace_meta_register("fasttrap", &fasttrap_mops, NULL, 2213 &fasttrap_meta_id); 2214 2215 return (DDI_FAILURE); 2216 } 2217 2218 #ifdef DEBUG 2219 mutex_enter(&fasttrap_count_mtx); 2220 ASSERT(fasttrap_pid_count == 0); 2221 mutex_exit(&fasttrap_count_mtx); 2222 #endif 2223 2224 kmem_free(fasttrap_tpoints.fth_table, 2225 fasttrap_tpoints.fth_nent * sizeof (fasttrap_bucket_t)); 2226 fasttrap_tpoints.fth_nent = 0; 2227 2228 kmem_free(fasttrap_provs.fth_table, 2229 fasttrap_provs.fth_nent * sizeof (fasttrap_bucket_t)); 2230 fasttrap_provs.fth_nent = 0; 2231 2232 kmem_free(fasttrap_procs.fth_table, 2233 fasttrap_procs.fth_nent * sizeof (fasttrap_bucket_t)); 2234 fasttrap_procs.fth_nent = 0; 2235 2236 /* 2237 * We know there are no tracepoints in any process anywhere in 2238 * the system so there is no process which has its p_dtrace_count 2239 * greater than zero, therefore we know that no thread can actively 2240 * be executing code in fasttrap_fork(). Similarly for p_dtrace_probes 2241 * and fasttrap_exec() and fasttrap_exit(). 2242 */ 2243 ASSERT(dtrace_fasttrap_fork_ptr == &fasttrap_fork); 2244 dtrace_fasttrap_fork_ptr = NULL; 2245 2246 ASSERT(dtrace_fasttrap_exec_ptr == &fasttrap_exec_exit); 2247 dtrace_fasttrap_exec_ptr = NULL; 2248 2249 ASSERT(dtrace_fasttrap_exit_ptr == &fasttrap_exec_exit); 2250 dtrace_fasttrap_exit_ptr = NULL; 2251 2252 ddi_remove_minor_node(devi, NULL); 2253 2254 return (DDI_SUCCESS); 2255 } 2256 2257 static struct dev_ops fasttrap_ops = { 2258 DEVO_REV, /* devo_rev */ 2259 0, /* refcnt */ 2260 fasttrap_info, /* get_dev_info */ 2261 nulldev, /* identify */ 2262 nulldev, /* probe */ 2263 fasttrap_attach, /* attach */ 2264 fasttrap_detach, /* detach */ 2265 nodev, /* reset */ 2266 &fasttrap_cb_ops, /* driver operations */ 2267 NULL, /* bus operations */ 2268 nodev /* dev power */ 2269 }; 2270 2271 /* 2272 * Module linkage information for the kernel. 2273 */ 2274 static struct modldrv modldrv = { 2275 &mod_driverops, /* module type (this is a pseudo driver) */ 2276 "Fasttrap Tracing", /* name of module */ 2277 &fasttrap_ops, /* driver ops */ 2278 }; 2279 2280 static struct modlinkage modlinkage = { 2281 MODREV_1, 2282 (void *)&modldrv, 2283 NULL 2284 }; 2285 2286 int 2287 _init(void) 2288 { 2289 return (mod_install(&modlinkage)); 2290 } 2291 2292 int 2293 _info(struct modinfo *modinfop) 2294 { 2295 return (mod_info(&modlinkage, modinfop)); 2296 } 2297 2298 int 2299 _fini(void) 2300 { 2301 return (mod_remove(&modlinkage)); 2302 } 2303