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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 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/modctl.h> 30 #include <sys/sunddi.h> 31 #include <sys/dtrace.h> 32 #include <sys/kobj.h> 33 #include <sys/stat.h> 34 #include <sys/conf.h> 35 #include <vm/seg_kmem.h> 36 #include <sys/stack.h> 37 #include <sys/sdt_impl.h> 38 39 static dev_info_t *sdt_devi; 40 41 int sdt_verbose = 0; 42 43 #define SDT_REG_G0 0 44 #define SDT_REG_O0 8 45 #define SDT_REG_O1 9 46 #define SDT_REG_O2 10 47 #define SDT_REG_O3 11 48 #define SDT_REG_O4 12 49 #define SDT_REG_O5 13 50 #define SDT_REG_I0 24 51 #define SDT_REG_I1 25 52 #define SDT_REG_I2 26 53 #define SDT_REG_I3 27 54 #define SDT_REG_I4 28 55 #define SDT_REG_I5 29 56 57 #define SDT_SIMM13_MASK 0x1fff 58 #define SDT_SIMM13_MAX ((int32_t)0xfff) 59 #define SDT_CALL(from, to) (((uint32_t)1 << 30) | \ 60 (((uintptr_t)(to) - (uintptr_t)(from) >> 2) & \ 61 0x3fffffff)) 62 #define SDT_SAVE (0x9de3a000 | (-SA(MINFRAME) & SDT_SIMM13_MASK)) 63 #define SDT_RET 0x81c7e008 64 #define SDT_RESTORE 0x81e80000 65 66 #define SDT_OP_SETHI 0x1000000 67 #define SDT_OP_OR 0x80100000 68 69 #define SDT_FMT2_RD_SHIFT 25 70 #define SDT_IMM22_SHIFT 10 71 #define SDT_IMM22_MASK 0x3fffff 72 #define SDT_IMM10_MASK 0x3ff 73 74 #define SDT_FMT3_RD_SHIFT 25 75 #define SDT_FMT3_RS1_SHIFT 14 76 #define SDT_FMT3_RS2_SHIFT 0 77 #define SDT_FMT3_IMM (1 << 13) 78 79 #define SDT_MOV(rs, rd) \ 80 (SDT_OP_OR | (SDT_REG_G0 << SDT_FMT3_RS1_SHIFT) | \ 81 ((rs) << SDT_FMT3_RS2_SHIFT) | ((rd) << SDT_FMT3_RD_SHIFT)) 82 83 #define SDT_ORLO(rs, val, rd) \ 84 (SDT_OP_OR | ((rs) << SDT_FMT3_RS1_SHIFT) | \ 85 ((rd) << SDT_FMT3_RD_SHIFT) | SDT_FMT3_IMM | ((val) & SDT_IMM10_MASK)) 86 87 #define SDT_ORSIMM13(rs, val, rd) \ 88 (SDT_OP_OR | ((rs) << SDT_FMT3_RS1_SHIFT) | \ 89 ((rd) << SDT_FMT3_RD_SHIFT) | SDT_FMT3_IMM | ((val) & SDT_SIMM13_MASK)) 90 91 #define SDT_SETHI(val, reg) \ 92 (SDT_OP_SETHI | (reg << SDT_FMT2_RD_SHIFT) | \ 93 ((val >> SDT_IMM22_SHIFT) & SDT_IMM22_MASK)) 94 95 #define SDT_ENTRY_SIZE (11 * sizeof (uint32_t)) 96 97 static void 98 sdt_initialize(sdt_probe_t *sdp, uint32_t **trampoline) 99 { 100 uint32_t *instr = *trampoline; 101 102 *instr++ = SDT_SAVE; 103 104 if (sdp->sdp_id > (uint32_t)SDT_SIMM13_MAX) { 105 *instr++ = SDT_SETHI(sdp->sdp_id, SDT_REG_O0); 106 *instr++ = SDT_ORLO(SDT_REG_O0, sdp->sdp_id, SDT_REG_O0); 107 } else { 108 *instr++ = SDT_ORSIMM13(SDT_REG_G0, sdp->sdp_id, SDT_REG_O0); 109 } 110 111 *instr++ = SDT_MOV(SDT_REG_I0, SDT_REG_O1); 112 *instr++ = SDT_MOV(SDT_REG_I1, SDT_REG_O2); 113 *instr++ = SDT_MOV(SDT_REG_I2, SDT_REG_O3); 114 *instr++ = SDT_MOV(SDT_REG_I3, SDT_REG_O4); 115 *instr = SDT_CALL(instr, dtrace_probe); 116 instr++; 117 *instr++ = SDT_MOV(SDT_REG_I4, SDT_REG_O5); 118 119 *instr++ = SDT_RET; 120 *instr++ = SDT_RESTORE; 121 *trampoline = instr; 122 } 123 124 /*ARGSUSED*/ 125 static void 126 sdt_provide_module(void *arg, struct modctl *ctl) 127 { 128 struct module *mp = ctl->mod_mp; 129 char *modname = ctl->mod_modname; 130 int primary, nprobes = 0; 131 sdt_probedesc_t *sdpd; 132 sdt_probe_t *sdp, *old; 133 uint32_t *tab; 134 sdt_provider_t *prov; 135 int len; 136 137 /* 138 * One for all, and all for one: if we haven't yet registered all of 139 * our providers, we'll refuse to provide anything. 140 */ 141 for (prov = sdt_providers; prov->sdtp_name != NULL; prov++) { 142 if (prov->sdtp_id == DTRACE_PROVNONE) 143 return; 144 } 145 146 if (mp->sdt_nprobes != 0 || (sdpd = mp->sdt_probes) == NULL) 147 return; 148 149 kobj_textwin_alloc(mp); 150 151 /* 152 * Hack to identify unix/genunix/krtld. 153 */ 154 primary = vmem_contains(heap_arena, (void *)ctl, 155 sizeof (struct modctl)) == 0; 156 157 /* 158 * If there hasn't been an sdt table allocated, we'll do so now. 159 */ 160 if (mp->sdt_tab == NULL) { 161 for (; sdpd != NULL; sdpd = sdpd->sdpd_next) { 162 nprobes++; 163 } 164 165 /* 166 * We could (should?) determine precisely the size of the 167 * table -- but a reasonable maximum will suffice. 168 */ 169 mp->sdt_size = nprobes * SDT_ENTRY_SIZE; 170 mp->sdt_tab = kobj_texthole_alloc(mp->text, mp->sdt_size); 171 172 if (mp->sdt_tab == NULL) { 173 cmn_err(CE_WARN, "couldn't allocate SDT table " 174 "for module %s", modname); 175 return; 176 } 177 } 178 179 tab = (uint32_t *)mp->sdt_tab; 180 181 for (sdpd = mp->sdt_probes; sdpd != NULL; sdpd = sdpd->sdpd_next) { 182 char *name = sdpd->sdpd_name, *func, *nname; 183 int i, j; 184 sdt_provider_t *prov; 185 ulong_t offs; 186 dtrace_id_t id; 187 188 for (prov = sdt_providers; prov->sdtp_prefix != NULL; prov++) { 189 char *prefix = prov->sdtp_prefix; 190 191 if (strncmp(name, prefix, strlen(prefix)) == 0) { 192 name += strlen(prefix); 193 break; 194 } 195 } 196 197 nname = kmem_alloc(len = strlen(name) + 1, KM_SLEEP); 198 199 for (i = 0, j = 0; name[j] != '\0'; i++) { 200 if (name[j] == '_' && name[j + 1] == '_') { 201 nname[i] = '-'; 202 j += 2; 203 } else { 204 nname[i] = name[j++]; 205 } 206 } 207 208 nname[i] = '\0'; 209 210 sdp = kmem_zalloc(sizeof (sdt_probe_t), KM_SLEEP); 211 sdp->sdp_loadcnt = ctl->mod_loadcnt; 212 sdp->sdp_primary = primary; 213 sdp->sdp_ctl = ctl; 214 sdp->sdp_name = nname; 215 sdp->sdp_namelen = len; 216 sdp->sdp_provider = prov; 217 218 func = kobj_searchsym(mp, sdpd->sdpd_offset + 219 (uintptr_t)mp->text, &offs); 220 221 if (func == NULL) 222 func = "<unknown>"; 223 224 /* 225 * We have our provider. Now create the probe. 226 */ 227 if ((id = dtrace_probe_lookup(prov->sdtp_id, modname, 228 func, nname)) != DTRACE_IDNONE) { 229 old = dtrace_probe_arg(prov->sdtp_id, id); 230 ASSERT(old != NULL); 231 232 sdp->sdp_next = old->sdp_next; 233 sdp->sdp_id = id; 234 old->sdp_next = sdp; 235 } else { 236 sdp->sdp_id = dtrace_probe_create(prov->sdtp_id, 237 modname, func, nname, 1, sdp); 238 239 mp->sdt_nprobes++; 240 } 241 242 sdp->sdp_patchval = SDT_CALL((uintptr_t)mp->text + 243 sdpd->sdpd_offset, tab); 244 sdp->sdp_patchpoint = (uint32_t *)((uintptr_t)mp->textwin + 245 sdpd->sdpd_offset); 246 sdp->sdp_savedval = *sdp->sdp_patchpoint; 247 sdt_initialize(sdp, &tab); 248 } 249 } 250 251 /*ARGSUSED*/ 252 static void 253 sdt_destroy(void *arg, dtrace_id_t id, void *parg) 254 { 255 sdt_probe_t *sdp = parg, *old; 256 struct modctl *ctl = sdp->sdp_ctl; 257 258 if (ctl != NULL && ctl->mod_loadcnt == sdp->sdp_loadcnt) { 259 if ((ctl->mod_loadcnt == sdp->sdp_loadcnt && 260 ctl->mod_loaded) || sdp->sdp_primary) { 261 ((struct module *)(ctl->mod_mp))->sdt_nprobes--; 262 } 263 } 264 265 while (sdp != NULL) { 266 old = sdp; 267 kmem_free(sdp->sdp_name, sdp->sdp_namelen); 268 sdp = sdp->sdp_next; 269 kmem_free(old, sizeof (sdt_probe_t)); 270 } 271 } 272 273 /*ARGSUSED*/ 274 static void 275 sdt_enable(void *arg, dtrace_id_t id, void *parg) 276 { 277 sdt_probe_t *sdp = parg; 278 struct modctl *ctl = sdp->sdp_ctl; 279 280 ctl->mod_nenabled++; 281 282 /* 283 * If this module has disappeared since we discovered its probes, 284 * refuse to enable it. 285 */ 286 if (!sdp->sdp_primary && !ctl->mod_loaded) { 287 if (sdt_verbose) { 288 cmn_err(CE_NOTE, "sdt is failing for probe %s " 289 "(module %s unloaded)", 290 sdp->sdp_name, ctl->mod_modname); 291 } 292 goto err; 293 } 294 295 /* 296 * Now check that our modctl has the expected load count. If it 297 * doesn't, this module must have been unloaded and reloaded -- and 298 * we're not going to touch it. 299 */ 300 if (ctl->mod_loadcnt != sdp->sdp_loadcnt) { 301 if (sdt_verbose) { 302 cmn_err(CE_NOTE, "sdt is failing for probe %s " 303 "(module %s reloaded)", 304 sdp->sdp_name, ctl->mod_modname); 305 } 306 goto err; 307 } 308 309 while (sdp != NULL) { 310 *sdp->sdp_patchpoint = sdp->sdp_patchval; 311 sdp = sdp->sdp_next; 312 } 313 314 err: 315 ; 316 } 317 318 /*ARGSUSED*/ 319 static void 320 sdt_disable(void *arg, dtrace_id_t id, void *parg) 321 { 322 sdt_probe_t *sdp = parg; 323 struct modctl *ctl = sdp->sdp_ctl; 324 325 ASSERT(ctl->mod_nenabled > 0); 326 ctl->mod_nenabled--; 327 328 if ((!sdp->sdp_primary && !ctl->mod_loaded) || 329 (ctl->mod_loadcnt != sdp->sdp_loadcnt)) 330 goto err; 331 332 while (sdp != NULL) { 333 *sdp->sdp_patchpoint = sdp->sdp_savedval; 334 sdp = sdp->sdp_next; 335 } 336 337 err: 338 ; 339 } 340 341 static dtrace_pops_t sdt_pops = { 342 NULL, 343 sdt_provide_module, 344 sdt_enable, 345 sdt_disable, 346 NULL, 347 NULL, 348 sdt_getargdesc, 349 NULL, 350 NULL, 351 sdt_destroy 352 }; 353 354 static int 355 sdt_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) 356 { 357 sdt_provider_t *prov; 358 359 switch (cmd) { 360 case DDI_ATTACH: 361 break; 362 case DDI_RESUME: 363 return (DDI_SUCCESS); 364 default: 365 return (DDI_FAILURE); 366 } 367 368 if (ddi_create_minor_node(devi, "sdt", S_IFCHR, 0, 369 DDI_PSEUDO, NULL) == DDI_FAILURE) { 370 ddi_remove_minor_node(devi, NULL); 371 return (DDI_FAILURE); 372 } 373 374 ddi_report_dev(devi); 375 sdt_devi = devi; 376 377 for (prov = sdt_providers; prov->sdtp_name != NULL; prov++) { 378 if (dtrace_register(prov->sdtp_name, prov->sdtp_attr, 379 DTRACE_PRIV_KERNEL, 0, 380 &sdt_pops, prov, &prov->sdtp_id) != 0) { 381 cmn_err(CE_WARN, "failed to register sdt provider %s", 382 prov->sdtp_name); 383 } 384 } 385 386 return (DDI_SUCCESS); 387 } 388 389 static int 390 sdt_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) 391 { 392 sdt_provider_t *prov; 393 394 switch (cmd) { 395 case DDI_DETACH: 396 break; 397 case DDI_SUSPEND: 398 return (DDI_SUCCESS); 399 default: 400 return (DDI_FAILURE); 401 } 402 403 for (prov = sdt_providers; prov->sdtp_name != NULL; prov++) { 404 if (prov->sdtp_id != DTRACE_PROVNONE) { 405 if (dtrace_unregister(prov->sdtp_id) != 0) 406 return (DDI_FAILURE); 407 prov->sdtp_id = DTRACE_PROVNONE; 408 } 409 } 410 411 ddi_remove_minor_node(devi, NULL); 412 return (DDI_SUCCESS); 413 } 414 415 /*ARGSUSED*/ 416 static int 417 sdt_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 418 { 419 int error; 420 421 switch (infocmd) { 422 case DDI_INFO_DEVT2DEVINFO: 423 *result = (void *)sdt_devi; 424 error = DDI_SUCCESS; 425 break; 426 case DDI_INFO_DEVT2INSTANCE: 427 *result = (void *)0; 428 error = DDI_SUCCESS; 429 break; 430 default: 431 error = DDI_FAILURE; 432 } 433 return (error); 434 } 435 436 /*ARGSUSED*/ 437 static int 438 sdt_open(dev_t *devp, int flag, int otyp, cred_t *cred_p) 439 { 440 return (0); 441 } 442 443 static struct cb_ops sdt_cb_ops = { 444 sdt_open, /* open */ 445 nodev, /* close */ 446 nulldev, /* strategy */ 447 nulldev, /* print */ 448 nodev, /* dump */ 449 nodev, /* read */ 450 nodev, /* write */ 451 nodev, /* ioctl */ 452 nodev, /* devmap */ 453 nodev, /* mmap */ 454 nodev, /* segmap */ 455 nochpoll, /* poll */ 456 ddi_prop_op, /* cb_prop_op */ 457 0, /* streamtab */ 458 D_NEW | D_MP /* Driver compatibility flag */ 459 }; 460 461 static struct dev_ops sdt_ops = { 462 DEVO_REV, /* devo_rev, */ 463 0, /* refcnt */ 464 sdt_info, /* get_dev_info */ 465 nulldev, /* identify */ 466 nulldev, /* probe */ 467 sdt_attach, /* attach */ 468 sdt_detach, /* detach */ 469 nodev, /* reset */ 470 &sdt_cb_ops, /* driver operations */ 471 NULL, /* bus operations */ 472 nodev /* dev power */ 473 }; 474 475 /* 476 * Module linkage information for the kernel. 477 */ 478 static struct modldrv modldrv = { 479 &mod_driverops, /* module type (this is a pseudo driver) */ 480 "Statically Defined Tracing", /* name of module */ 481 &sdt_ops, /* driver ops */ 482 }; 483 484 static struct modlinkage modlinkage = { 485 MODREV_1, 486 (void *)&modldrv, 487 NULL 488 }; 489 490 int 491 _init(void) 492 { 493 return (mod_install(&modlinkage)); 494 } 495 496 int 497 _info(struct modinfo *modinfop) 498 { 499 return (mod_info(&modlinkage, modinfop)); 500 } 501 502 int 503 _fini(void) 504 { 505 return (mod_remove(&modlinkage)); 506 } 507