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.
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.
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]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * Copyright (c) 2012, Joyent, Inc. All rights reserved.
30 #include <sys/modctl.h>
31 #include <sys/sunddi.h>
32 #include <sys/dtrace.h>
36 #include <vm/seg_kmem.h>
37 #include <sys/stack.h>
38 #include <sys/sdt_impl.h>
40 static dev_info_t
*sdt_devi
;
58 #define SDT_SIMM13_MASK 0x1fff
59 #define SDT_SIMM13_MAX ((int32_t)0xfff)
60 #define SDT_CALL(from, to) (((uint32_t)1 << 30) | \
61 (((uintptr_t)(to) - (uintptr_t)(from) >> 2) & \
63 #define SDT_SAVE (0x9de3a000 | (-SA(MINFRAME) & SDT_SIMM13_MASK))
64 #define SDT_RET 0x81c7e008
65 #define SDT_RESTORE 0x81e80000
67 #define SDT_OP_SETHI 0x1000000
68 #define SDT_OP_OR 0x80100000
70 #define SDT_FMT2_RD_SHIFT 25
71 #define SDT_IMM22_SHIFT 10
72 #define SDT_IMM22_MASK 0x3fffff
73 #define SDT_IMM10_MASK 0x3ff
75 #define SDT_FMT3_RD_SHIFT 25
76 #define SDT_FMT3_RS1_SHIFT 14
77 #define SDT_FMT3_RS2_SHIFT 0
78 #define SDT_FMT3_IMM (1 << 13)
80 #define SDT_MOV(rs, rd) \
81 (SDT_OP_OR | (SDT_REG_G0 << SDT_FMT3_RS1_SHIFT) | \
82 ((rs) << SDT_FMT3_RS2_SHIFT) | ((rd) << SDT_FMT3_RD_SHIFT))
84 #define SDT_ORLO(rs, val, rd) \
85 (SDT_OP_OR | ((rs) << SDT_FMT3_RS1_SHIFT) | \
86 ((rd) << SDT_FMT3_RD_SHIFT) | SDT_FMT3_IMM | ((val) & SDT_IMM10_MASK))
88 #define SDT_ORSIMM13(rs, val, rd) \
89 (SDT_OP_OR | ((rs) << SDT_FMT3_RS1_SHIFT) | \
90 ((rd) << SDT_FMT3_RD_SHIFT) | SDT_FMT3_IMM | ((val) & SDT_SIMM13_MASK))
92 #define SDT_SETHI(val, reg) \
93 (SDT_OP_SETHI | (reg << SDT_FMT2_RD_SHIFT) | \
94 ((val >> SDT_IMM22_SHIFT) & SDT_IMM22_MASK))
96 #define SDT_ENTRY_SIZE (11 * sizeof (uint32_t))
99 sdt_initialize(sdt_probe_t
*sdp
, uint32_t **trampoline
)
101 uint32_t *instr
= *trampoline
;
105 if (sdp
->sdp_id
> (uint32_t)SDT_SIMM13_MAX
) {
106 *instr
++ = SDT_SETHI(sdp
->sdp_id
, SDT_REG_O0
);
107 *instr
++ = SDT_ORLO(SDT_REG_O0
, sdp
->sdp_id
, SDT_REG_O0
);
109 *instr
++ = SDT_ORSIMM13(SDT_REG_G0
, sdp
->sdp_id
, SDT_REG_O0
);
112 *instr
++ = SDT_MOV(SDT_REG_I0
, SDT_REG_O1
);
113 *instr
++ = SDT_MOV(SDT_REG_I1
, SDT_REG_O2
);
114 *instr
++ = SDT_MOV(SDT_REG_I2
, SDT_REG_O3
);
115 *instr
++ = SDT_MOV(SDT_REG_I3
, SDT_REG_O4
);
116 *instr
= SDT_CALL(instr
, dtrace_probe
);
118 *instr
++ = SDT_MOV(SDT_REG_I4
, SDT_REG_O5
);
121 *instr
++ = SDT_RESTORE
;
127 sdt_provide_module(void *arg
, struct modctl
*ctl
)
129 struct module
*mp
= ctl
->mod_mp
;
130 char *modname
= ctl
->mod_modname
;
131 int primary
, nprobes
= 0;
132 sdt_probedesc_t
*sdpd
;
133 sdt_probe_t
*sdp
, *old
;
135 sdt_provider_t
*prov
;
139 * One for all, and all for one: if we haven't yet registered all of
140 * our providers, we'll refuse to provide anything.
142 for (prov
= sdt_providers
; prov
->sdtp_name
!= NULL
; prov
++) {
143 if (prov
->sdtp_id
== DTRACE_PROVNONE
)
147 if (mp
->sdt_nprobes
!= 0 || (sdpd
= mp
->sdt_probes
) == NULL
)
150 kobj_textwin_alloc(mp
);
153 * Hack to identify unix/genunix/krtld.
155 primary
= vmem_contains(heap_arena
, (void *)ctl
,
156 sizeof (struct modctl
)) == 0;
159 * If there hasn't been an sdt table allocated, we'll do so now.
161 if (mp
->sdt_tab
== NULL
) {
162 for (; sdpd
!= NULL
; sdpd
= sdpd
->sdpd_next
) {
167 * We could (should?) determine precisely the size of the
168 * table -- but a reasonable maximum will suffice.
170 mp
->sdt_size
= nprobes
* SDT_ENTRY_SIZE
;
171 mp
->sdt_tab
= kobj_texthole_alloc(mp
->text
, mp
->sdt_size
);
173 if (mp
->sdt_tab
== NULL
) {
174 cmn_err(CE_WARN
, "couldn't allocate SDT table "
175 "for module %s", modname
);
180 tab
= (uint32_t *)mp
->sdt_tab
;
182 for (sdpd
= mp
->sdt_probes
; sdpd
!= NULL
; sdpd
= sdpd
->sdpd_next
) {
183 char *name
= sdpd
->sdpd_name
, *func
, *nname
;
185 sdt_provider_t
*prov
;
189 for (prov
= sdt_providers
; prov
->sdtp_prefix
!= NULL
; prov
++) {
190 char *prefix
= prov
->sdtp_prefix
;
192 if (strncmp(name
, prefix
, strlen(prefix
)) == 0) {
193 name
+= strlen(prefix
);
198 nname
= kmem_alloc(len
= strlen(name
) + 1, KM_SLEEP
);
200 for (i
= 0, j
= 0; name
[j
] != '\0'; i
++) {
201 if (name
[j
] == '_' && name
[j
+ 1] == '_') {
205 nname
[i
] = name
[j
++];
211 sdp
= kmem_zalloc(sizeof (sdt_probe_t
), KM_SLEEP
);
212 sdp
->sdp_loadcnt
= ctl
->mod_loadcnt
;
213 sdp
->sdp_primary
= primary
;
215 sdp
->sdp_name
= nname
;
216 sdp
->sdp_namelen
= len
;
217 sdp
->sdp_provider
= prov
;
219 func
= kobj_searchsym(mp
, sdpd
->sdpd_offset
+
220 (uintptr_t)mp
->text
, &offs
);
226 * We have our provider. Now create the probe.
228 if ((id
= dtrace_probe_lookup(prov
->sdtp_id
, modname
,
229 func
, nname
)) != DTRACE_IDNONE
) {
230 old
= dtrace_probe_arg(prov
->sdtp_id
, id
);
233 sdp
->sdp_next
= old
->sdp_next
;
237 sdp
->sdp_id
= dtrace_probe_create(prov
->sdtp_id
,
238 modname
, func
, nname
, 1, sdp
);
243 sdp
->sdp_patchval
= SDT_CALL((uintptr_t)mp
->text
+
244 sdpd
->sdpd_offset
, tab
);
245 sdp
->sdp_patchpoint
= (uint32_t *)((uintptr_t)mp
->textwin
+
247 sdp
->sdp_savedval
= *sdp
->sdp_patchpoint
;
248 sdt_initialize(sdp
, &tab
);
254 sdt_destroy(void *arg
, dtrace_id_t id
, void *parg
)
256 sdt_probe_t
*sdp
= parg
, *old
;
257 struct modctl
*ctl
= sdp
->sdp_ctl
;
259 if (ctl
!= NULL
&& ctl
->mod_loadcnt
== sdp
->sdp_loadcnt
) {
260 if ((ctl
->mod_loadcnt
== sdp
->sdp_loadcnt
&&
261 ctl
->mod_loaded
) || sdp
->sdp_primary
) {
262 ((struct module
*)(ctl
->mod_mp
))->sdt_nprobes
--;
266 while (sdp
!= NULL
) {
268 kmem_free(sdp
->sdp_name
, sdp
->sdp_namelen
);
270 kmem_free(old
, sizeof (sdt_probe_t
));
276 sdt_enable(void *arg
, dtrace_id_t id
, void *parg
)
278 sdt_probe_t
*sdp
= parg
;
279 struct modctl
*ctl
= sdp
->sdp_ctl
;
284 * If this module has disappeared since we discovered its probes,
285 * refuse to enable it.
287 if (!sdp
->sdp_primary
&& !ctl
->mod_loaded
) {
289 cmn_err(CE_NOTE
, "sdt is failing for probe %s "
290 "(module %s unloaded)",
291 sdp
->sdp_name
, ctl
->mod_modname
);
297 * Now check that our modctl has the expected load count. If it
298 * doesn't, this module must have been unloaded and reloaded -- and
299 * we're not going to touch it.
301 if (ctl
->mod_loadcnt
!= sdp
->sdp_loadcnt
) {
303 cmn_err(CE_NOTE
, "sdt is failing for probe %s "
304 "(module %s reloaded)",
305 sdp
->sdp_name
, ctl
->mod_modname
);
310 while (sdp
!= NULL
) {
311 *sdp
->sdp_patchpoint
= sdp
->sdp_patchval
;
321 sdt_disable(void *arg
, dtrace_id_t id
, void *parg
)
323 sdt_probe_t
*sdp
= parg
;
324 struct modctl
*ctl
= sdp
->sdp_ctl
;
326 ASSERT(ctl
->mod_nenabled
> 0);
329 if ((!sdp
->sdp_primary
&& !ctl
->mod_loaded
) ||
330 (ctl
->mod_loadcnt
!= sdp
->sdp_loadcnt
))
333 while (sdp
!= NULL
) {
334 *sdp
->sdp_patchpoint
= sdp
->sdp_savedval
;
342 static dtrace_pops_t sdt_pops
= {
356 sdt_attach(dev_info_t
*devi
, ddi_attach_cmd_t cmd
)
358 sdt_provider_t
*prov
;
364 return (DDI_SUCCESS
);
366 return (DDI_FAILURE
);
369 if (ddi_create_minor_node(devi
, "sdt", S_IFCHR
, 0,
370 DDI_PSEUDO
, NULL
) == DDI_FAILURE
) {
371 ddi_remove_minor_node(devi
, NULL
);
372 return (DDI_FAILURE
);
375 ddi_report_dev(devi
);
378 for (prov
= sdt_providers
; prov
->sdtp_name
!= NULL
; prov
++) {
381 if (prov
->sdtp_priv
== DTRACE_PRIV_NONE
) {
382 priv
= DTRACE_PRIV_KERNEL
;
383 sdt_pops
.dtps_mode
= NULL
;
385 priv
= prov
->sdtp_priv
;
386 ASSERT(priv
== DTRACE_PRIV_USER
);
387 sdt_pops
.dtps_mode
= sdt_mode
;
390 if (dtrace_register(prov
->sdtp_name
, prov
->sdtp_attr
,
391 priv
, NULL
, &sdt_pops
, prov
, &prov
->sdtp_id
) != 0) {
392 cmn_err(CE_WARN
, "failed to register sdt provider %s",
397 return (DDI_SUCCESS
);
401 sdt_detach(dev_info_t
*devi
, ddi_detach_cmd_t cmd
)
403 sdt_provider_t
*prov
;
409 return (DDI_SUCCESS
);
411 return (DDI_FAILURE
);
414 for (prov
= sdt_providers
; prov
->sdtp_name
!= NULL
; prov
++) {
415 if (prov
->sdtp_id
!= DTRACE_PROVNONE
) {
416 if (dtrace_unregister(prov
->sdtp_id
) != 0)
417 return (DDI_FAILURE
);
418 prov
->sdtp_id
= DTRACE_PROVNONE
;
422 ddi_remove_minor_node(devi
, NULL
);
423 return (DDI_SUCCESS
);
428 sdt_info(dev_info_t
*dip
, ddi_info_cmd_t infocmd
, void *arg
, void **result
)
433 case DDI_INFO_DEVT2DEVINFO
:
434 *result
= (void *)sdt_devi
;
437 case DDI_INFO_DEVT2INSTANCE
:
449 sdt_open(dev_t
*devp
, int flag
, int otyp
, cred_t
*cred_p
)
454 static struct cb_ops sdt_cb_ops
= {
457 nulldev
, /* strategy */
467 ddi_prop_op
, /* cb_prop_op */
469 D_NEW
| D_MP
/* Driver compatibility flag */
472 static struct dev_ops sdt_ops
= {
473 DEVO_REV
, /* devo_rev, */
475 sdt_info
, /* get_dev_info */
476 nulldev
, /* identify */
478 sdt_attach
, /* attach */
479 sdt_detach
, /* detach */
481 &sdt_cb_ops
, /* driver operations */
482 NULL
, /* bus operations */
483 nodev
, /* dev power */
484 ddi_quiesce_not_needed
, /* quiesce */
488 * Module linkage information for the kernel.
490 static struct modldrv modldrv
= {
491 &mod_driverops
, /* module type (this is a pseudo driver) */
492 "Statically Defined Tracing", /* name of module */
493 &sdt_ops
, /* driver ops */
496 static struct modlinkage modlinkage
= {
505 return (mod_install(&modlinkage
));
509 _info(struct modinfo
*modinfop
)
511 return (mod_info(&modlinkage
, modinfop
));
517 return (mod_remove(&modlinkage
));