1c7570492SJustin Hibbits /*
2c7570492SJustin Hibbits * CDDL HEADER START
3c7570492SJustin Hibbits *
4c7570492SJustin Hibbits * The contents of this file are subject to the terms of the
5c7570492SJustin Hibbits * Common Development and Distribution License, Version 1.0 only
6c7570492SJustin Hibbits * (the "License"). You may not use this file except in compliance
7c7570492SJustin Hibbits * with the License.
8c7570492SJustin Hibbits *
9c7570492SJustin Hibbits * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10c7570492SJustin Hibbits * or http://www.opensolaris.org/os/licensing.
11c7570492SJustin Hibbits * See the License for the specific language governing permissions
12c7570492SJustin Hibbits * and limitations under the License.
13c7570492SJustin Hibbits *
14c7570492SJustin Hibbits * When distributing Covered Code, include this CDDL HEADER in each
15c7570492SJustin Hibbits * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16c7570492SJustin Hibbits * If applicable, add the following below this CDDL HEADER, with the
17c7570492SJustin Hibbits * fields enclosed by brackets "[]" replaced with your own identifying
18c7570492SJustin Hibbits * information: Portions Copyright [yyyy] [name of copyright owner]
19c7570492SJustin Hibbits *
20c7570492SJustin Hibbits * CDDL HEADER END
21c7570492SJustin Hibbits *
22c7570492SJustin Hibbits */
23c7570492SJustin Hibbits /*
24c7570492SJustin Hibbits * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
25c7570492SJustin Hibbits * Use is subject to license terms.
26c7570492SJustin Hibbits */
27c7570492SJustin Hibbits
28c7570492SJustin Hibbits #include <sys/param.h>
29c7570492SJustin Hibbits #include <sys/systm.h>
30c7570492SJustin Hibbits #include <sys/kernel.h>
31c7570492SJustin Hibbits #include <sys/malloc.h>
32c7570492SJustin Hibbits #include <sys/kmem.h>
33*bdd101c4SMark Johnston #include <sys/proc.h>
34c7570492SJustin Hibbits #include <sys/smp.h>
35c7570492SJustin Hibbits #include <sys/dtrace_impl.h>
36c7570492SJustin Hibbits #include <sys/dtrace_bsd.h>
37*bdd101c4SMark Johnston #include <cddl/dev/dtrace/dtrace_cddl.h>
38c7570492SJustin Hibbits #include <machine/clock.h>
39c7570492SJustin Hibbits #include <machine/frame.h>
40c7570492SJustin Hibbits #include <machine/trap.h>
41c7570492SJustin Hibbits #include <vm/pmap.h>
42c7570492SJustin Hibbits
43c7570492SJustin Hibbits #define DELAYBRANCH(x) ((int)(x) < 0)
44c7570492SJustin Hibbits
45c7570492SJustin Hibbits extern dtrace_id_t dtrace_probeid_error;
4680a5635cSJustin Hibbits extern int (*dtrace_invop_jump_addr)(struct trapframe *);
47c7570492SJustin Hibbits
48f0bd82a1SJustin Hibbits extern void dtrace_getnanotime(struct timespec *tsp);
49f0bd82a1SJustin Hibbits
506c280659SMark Johnston int dtrace_invop(uintptr_t, struct trapframe *, uintptr_t);
5180a5635cSJustin Hibbits void dtrace_invop_init(void);
5280a5635cSJustin Hibbits void dtrace_invop_uninit(void);
53c7570492SJustin Hibbits
54c7570492SJustin Hibbits typedef struct dtrace_invop_hdlr {
556c280659SMark Johnston int (*dtih_func)(uintptr_t, struct trapframe *, uintptr_t);
56c7570492SJustin Hibbits struct dtrace_invop_hdlr *dtih_next;
57c7570492SJustin Hibbits } dtrace_invop_hdlr_t;
58c7570492SJustin Hibbits
59c7570492SJustin Hibbits dtrace_invop_hdlr_t *dtrace_invop_hdlr;
60c7570492SJustin Hibbits
61c7570492SJustin Hibbits int
dtrace_invop(uintptr_t addr,struct trapframe * frame,uintptr_t arg0)626c280659SMark Johnston dtrace_invop(uintptr_t addr, struct trapframe *frame, uintptr_t arg0)
63c7570492SJustin Hibbits {
64*bdd101c4SMark Johnston struct thread *td;
65c7570492SJustin Hibbits dtrace_invop_hdlr_t *hdlr;
66c7570492SJustin Hibbits int rval;
67c7570492SJustin Hibbits
68*bdd101c4SMark Johnston rval = 0;
69*bdd101c4SMark Johnston td = curthread;
70*bdd101c4SMark Johnston td->t_dtrace_trapframe = frame;
71c7570492SJustin Hibbits for (hdlr = dtrace_invop_hdlr; hdlr != NULL; hdlr = hdlr->dtih_next)
726c280659SMark Johnston if ((rval = hdlr->dtih_func(addr, frame, arg0)) != 0)
73*bdd101c4SMark Johnston break;
74*bdd101c4SMark Johnston td->t_dtrace_trapframe = NULL;
75c7570492SJustin Hibbits return (rval);
76c7570492SJustin Hibbits }
77c7570492SJustin Hibbits
7880a5635cSJustin Hibbits void
dtrace_invop_add(int (* func)(uintptr_t,struct trapframe *,uintptr_t))796c280659SMark Johnston dtrace_invop_add(int (*func)(uintptr_t, struct trapframe *, uintptr_t))
8080a5635cSJustin Hibbits {
8180a5635cSJustin Hibbits dtrace_invop_hdlr_t *hdlr;
8280a5635cSJustin Hibbits
8380a5635cSJustin Hibbits hdlr = kmem_alloc(sizeof (dtrace_invop_hdlr_t), KM_SLEEP);
8480a5635cSJustin Hibbits hdlr->dtih_func = func;
8580a5635cSJustin Hibbits hdlr->dtih_next = dtrace_invop_hdlr;
8680a5635cSJustin Hibbits dtrace_invop_hdlr = hdlr;
8780a5635cSJustin Hibbits }
8880a5635cSJustin Hibbits
8980a5635cSJustin Hibbits void
dtrace_invop_remove(int (* func)(uintptr_t,struct trapframe *,uintptr_t))906c280659SMark Johnston dtrace_invop_remove(int (*func)(uintptr_t, struct trapframe *, uintptr_t))
9180a5635cSJustin Hibbits {
9280a5635cSJustin Hibbits dtrace_invop_hdlr_t *hdlr = dtrace_invop_hdlr, *prev = NULL;
9380a5635cSJustin Hibbits
9480a5635cSJustin Hibbits for (;;) {
9580a5635cSJustin Hibbits if (hdlr == NULL)
9680a5635cSJustin Hibbits panic("attempt to remove non-existent invop handler");
9780a5635cSJustin Hibbits
9880a5635cSJustin Hibbits if (hdlr->dtih_func == func)
9980a5635cSJustin Hibbits break;
10080a5635cSJustin Hibbits
10180a5635cSJustin Hibbits prev = hdlr;
10280a5635cSJustin Hibbits hdlr = hdlr->dtih_next;
10380a5635cSJustin Hibbits }
10480a5635cSJustin Hibbits
10580a5635cSJustin Hibbits if (prev == NULL) {
10680a5635cSJustin Hibbits ASSERT(dtrace_invop_hdlr == hdlr);
10780a5635cSJustin Hibbits dtrace_invop_hdlr = hdlr->dtih_next;
10880a5635cSJustin Hibbits } else {
10980a5635cSJustin Hibbits ASSERT(dtrace_invop_hdlr != hdlr);
11080a5635cSJustin Hibbits prev->dtih_next = hdlr->dtih_next;
11180a5635cSJustin Hibbits }
11280a5635cSJustin Hibbits
11380a5635cSJustin Hibbits kmem_free(hdlr, 0);
11480a5635cSJustin Hibbits }
11580a5635cSJustin Hibbits
116c7570492SJustin Hibbits
117c7570492SJustin Hibbits /*ARGSUSED*/
118c7570492SJustin Hibbits void
dtrace_toxic_ranges(void (* func)(uintptr_t base,uintptr_t limit))119c7570492SJustin Hibbits dtrace_toxic_ranges(void (*func)(uintptr_t base, uintptr_t limit))
120c7570492SJustin Hibbits {
121c7570492SJustin Hibbits /*
122c7570492SJustin Hibbits * No toxic regions?
123c7570492SJustin Hibbits */
124c7570492SJustin Hibbits }
125c7570492SJustin Hibbits
126c7570492SJustin Hibbits void
dtrace_xcall(processorid_t cpu,dtrace_xcall_t func,void * arg)127c7570492SJustin Hibbits dtrace_xcall(processorid_t cpu, dtrace_xcall_t func, void *arg)
128c7570492SJustin Hibbits {
129c7570492SJustin Hibbits cpuset_t cpus;
130c7570492SJustin Hibbits
131c7570492SJustin Hibbits if (cpu == DTRACE_CPUALL)
132c7570492SJustin Hibbits cpus = all_cpus;
133c7570492SJustin Hibbits else
134c7570492SJustin Hibbits CPU_SETOF(cpu, &cpus);
135c7570492SJustin Hibbits
13667d955aaSPatrick Kelsey smp_rendezvous_cpus(cpus, smp_no_rendezvous_barrier, func,
13767d955aaSPatrick Kelsey smp_no_rendezvous_barrier, arg);
138c7570492SJustin Hibbits }
139c7570492SJustin Hibbits
140c7570492SJustin Hibbits static void
dtrace_sync_func(void)141c7570492SJustin Hibbits dtrace_sync_func(void)
142c7570492SJustin Hibbits {
143c7570492SJustin Hibbits }
144c7570492SJustin Hibbits
145c7570492SJustin Hibbits void
dtrace_sync(void)146c7570492SJustin Hibbits dtrace_sync(void)
147c7570492SJustin Hibbits {
148c7570492SJustin Hibbits dtrace_xcall(DTRACE_CPUALL, (dtrace_xcall_t)dtrace_sync_func, NULL);
149c7570492SJustin Hibbits }
150c7570492SJustin Hibbits
151f0bd82a1SJustin Hibbits static int64_t tgt_cpu_tsc;
152f0bd82a1SJustin Hibbits static int64_t hst_cpu_tsc;
153f0bd82a1SJustin Hibbits static int64_t timebase_skew[MAXCPU];
154f0bd82a1SJustin Hibbits static uint64_t nsec_scale;
155f0bd82a1SJustin Hibbits
156f0bd82a1SJustin Hibbits /* See below for the explanation of this macro. */
157f0bd82a1SJustin Hibbits /* This is taken from the amd64 dtrace_subr, to provide a synchronized timer
158f0bd82a1SJustin Hibbits * between multiple processors in dtrace. Since PowerPC Timebases can be much
159f0bd82a1SJustin Hibbits * lower than x86, the scale shift is 26 instead of 28, allowing for a 15.63MHz
160f0bd82a1SJustin Hibbits * timebase.
161f0bd82a1SJustin Hibbits */
162f0bd82a1SJustin Hibbits #define SCALE_SHIFT 26
163f0bd82a1SJustin Hibbits
164f0bd82a1SJustin Hibbits static void
dtrace_gethrtime_init_cpu(void * arg)165f0bd82a1SJustin Hibbits dtrace_gethrtime_init_cpu(void *arg)
166f0bd82a1SJustin Hibbits {
167f0bd82a1SJustin Hibbits uintptr_t cpu = (uintptr_t) arg;
168f0bd82a1SJustin Hibbits
169f0bd82a1SJustin Hibbits if (cpu == curcpu)
170f0bd82a1SJustin Hibbits tgt_cpu_tsc = mftb();
171f0bd82a1SJustin Hibbits else
172f0bd82a1SJustin Hibbits hst_cpu_tsc = mftb();
173f0bd82a1SJustin Hibbits }
174f0bd82a1SJustin Hibbits
175f0bd82a1SJustin Hibbits static void
dtrace_gethrtime_init(void * arg)176f0bd82a1SJustin Hibbits dtrace_gethrtime_init(void *arg)
177f0bd82a1SJustin Hibbits {
178f0bd82a1SJustin Hibbits struct pcpu *pc;
179f0bd82a1SJustin Hibbits uint64_t tb_f;
180f0bd82a1SJustin Hibbits cpuset_t map;
181f0bd82a1SJustin Hibbits int i;
182f0bd82a1SJustin Hibbits
183f0bd82a1SJustin Hibbits tb_f = cpu_tickrate();
184f0bd82a1SJustin Hibbits
185f0bd82a1SJustin Hibbits /*
186f0bd82a1SJustin Hibbits * The following line checks that nsec_scale calculated below
187f0bd82a1SJustin Hibbits * doesn't overflow 32-bit unsigned integer, so that it can multiply
188f0bd82a1SJustin Hibbits * another 32-bit integer without overflowing 64-bit.
189f0bd82a1SJustin Hibbits * Thus minimum supported Timebase frequency is 15.63MHz.
190f0bd82a1SJustin Hibbits */
191f0bd82a1SJustin Hibbits KASSERT(tb_f > (NANOSEC >> (32 - SCALE_SHIFT)), ("Timebase frequency is too low"));
192f0bd82a1SJustin Hibbits
193f0bd82a1SJustin Hibbits /*
194f0bd82a1SJustin Hibbits * We scale up NANOSEC/tb_f ratio to preserve as much precision
195f0bd82a1SJustin Hibbits * as possible.
196f0bd82a1SJustin Hibbits * 2^26 factor was chosen quite arbitrarily from practical
197f0bd82a1SJustin Hibbits * considerations:
198f0bd82a1SJustin Hibbits * - it supports TSC frequencies as low as 15.63MHz (see above);
199f0bd82a1SJustin Hibbits */
200f0bd82a1SJustin Hibbits nsec_scale = ((uint64_t)NANOSEC << SCALE_SHIFT) / tb_f;
201f0bd82a1SJustin Hibbits
202f0bd82a1SJustin Hibbits /* The current CPU is the reference one. */
203f0bd82a1SJustin Hibbits sched_pin();
204f0bd82a1SJustin Hibbits timebase_skew[curcpu] = 0;
205f0bd82a1SJustin Hibbits CPU_FOREACH(i) {
206f0bd82a1SJustin Hibbits if (i == curcpu)
207f0bd82a1SJustin Hibbits continue;
208f0bd82a1SJustin Hibbits
209f0bd82a1SJustin Hibbits pc = pcpu_find(i);
210f0bd82a1SJustin Hibbits CPU_SETOF(PCPU_GET(cpuid), &map);
211f0bd82a1SJustin Hibbits CPU_SET(pc->pc_cpuid, &map);
212f0bd82a1SJustin Hibbits
213f0bd82a1SJustin Hibbits smp_rendezvous_cpus(map, NULL,
214f0bd82a1SJustin Hibbits dtrace_gethrtime_init_cpu,
21567d955aaSPatrick Kelsey smp_no_rendezvous_barrier, (void *)(uintptr_t) i);
216f0bd82a1SJustin Hibbits
217f0bd82a1SJustin Hibbits timebase_skew[i] = tgt_cpu_tsc - hst_cpu_tsc;
218f0bd82a1SJustin Hibbits }
219f0bd82a1SJustin Hibbits sched_unpin();
220f0bd82a1SJustin Hibbits }
221fdce57a0SJohn Baldwin #ifdef EARLY_AP_STARTUP
222fdce57a0SJohn Baldwin SYSINIT(dtrace_gethrtime_init, SI_SUB_DTRACE, SI_ORDER_ANY,
223fdce57a0SJohn Baldwin dtrace_gethrtime_init, NULL);
224fdce57a0SJohn Baldwin #else
225fdce57a0SJohn Baldwin SYSINIT(dtrace_gethrtime_init, SI_SUB_SMP, SI_ORDER_ANY, dtrace_gethrtime_init,
226fdce57a0SJohn Baldwin NULL);
227fdce57a0SJohn Baldwin #endif
228f0bd82a1SJustin Hibbits
229c7570492SJustin Hibbits /*
230c7570492SJustin Hibbits * DTrace needs a high resolution time function which can
231c7570492SJustin Hibbits * be called from a probe context and guaranteed not to have
232c7570492SJustin Hibbits * instrumented with probes itself.
233c7570492SJustin Hibbits *
234c7570492SJustin Hibbits * Returns nanoseconds since boot.
235c7570492SJustin Hibbits */
236c7570492SJustin Hibbits uint64_t
dtrace_gethrtime(void)2377701f301SDimitry Andric dtrace_gethrtime(void)
238c7570492SJustin Hibbits {
239f0bd82a1SJustin Hibbits uint64_t timebase;
240f0bd82a1SJustin Hibbits uint32_t lo;
241f0bd82a1SJustin Hibbits uint32_t hi;
242c7570492SJustin Hibbits
243f0bd82a1SJustin Hibbits /*
244f0bd82a1SJustin Hibbits * We split timebase value into lower and higher 32-bit halves and separately
245f0bd82a1SJustin Hibbits * scale them with nsec_scale, then we scale them down by 2^28
246f0bd82a1SJustin Hibbits * (see nsec_scale calculations) taking into account 32-bit shift of
247f0bd82a1SJustin Hibbits * the higher half and finally add.
248f0bd82a1SJustin Hibbits */
249f0bd82a1SJustin Hibbits timebase = mftb() - timebase_skew[curcpu];
250f0bd82a1SJustin Hibbits lo = timebase;
251f0bd82a1SJustin Hibbits hi = timebase >> 32;
252f0bd82a1SJustin Hibbits return (((lo * nsec_scale) >> SCALE_SHIFT) +
253f0bd82a1SJustin Hibbits ((hi * nsec_scale) << (32 - SCALE_SHIFT)));
254c7570492SJustin Hibbits }
255c7570492SJustin Hibbits
256c7570492SJustin Hibbits uint64_t
dtrace_gethrestime(void)257c7570492SJustin Hibbits dtrace_gethrestime(void)
258c7570492SJustin Hibbits {
259c7570492SJustin Hibbits struct timespec curtime;
260c7570492SJustin Hibbits
261f0bd82a1SJustin Hibbits dtrace_getnanotime(&curtime);
262c7570492SJustin Hibbits
263c7570492SJustin Hibbits return (curtime.tv_sec * 1000000000UL + curtime.tv_nsec);
264c7570492SJustin Hibbits }
265c7570492SJustin Hibbits
266f0bd82a1SJustin Hibbits /* Function to handle DTrace traps during probes. See powerpc/powerpc/trap.c */
267c7570492SJustin Hibbits int
dtrace_trap(struct trapframe * frame,u_int type)268cafe8744SMark Johnston dtrace_trap(struct trapframe *frame, u_int type)
269c7570492SJustin Hibbits {
270880870b4SJustin Hibbits uint16_t nofault;
271cafe8744SMark Johnston
272c7570492SJustin Hibbits /*
273c7570492SJustin Hibbits * A trap can occur while DTrace executes a probe. Before
274c7570492SJustin Hibbits * executing the probe, DTrace blocks re-scheduling and sets
275291624fdSMark Johnston * a flag in its per-cpu flags to indicate that it doesn't
276c7570492SJustin Hibbits * want to fault. On returning from the probe, the no-fault
277c7570492SJustin Hibbits * flag is cleared and finally re-scheduling is enabled.
278c7570492SJustin Hibbits *
279c7570492SJustin Hibbits * Check if DTrace has enabled 'no-fault' mode:
280c7570492SJustin Hibbits */
281880870b4SJustin Hibbits sched_pin();
282880870b4SJustin Hibbits nofault = cpu_core[curcpu].cpuc_dtrace_flags & CPU_DTRACE_NOFAULT;
283880870b4SJustin Hibbits sched_unpin();
284880870b4SJustin Hibbits if (nofault) {
285880870b4SJustin Hibbits KASSERT((frame->srr1 & PSL_EE) == 0, ("interrupts enabled"));
286c7570492SJustin Hibbits /*
287c7570492SJustin Hibbits * There are only a couple of trap types that are expected.
288c7570492SJustin Hibbits * All the rest will be handled in the usual way.
289c7570492SJustin Hibbits */
290cafe8744SMark Johnston switch (type) {
291c7570492SJustin Hibbits /* Page fault. */
292c7570492SJustin Hibbits case EXC_DSI:
293c7570492SJustin Hibbits case EXC_DSE:
294c7570492SJustin Hibbits /* Flag a bad address. */
295c7570492SJustin Hibbits cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_BADADDR;
2964c790d26SNathan Whitehorn cpu_core[curcpu].cpuc_dtrace_illval = frame->dar;
297c7570492SJustin Hibbits
298c7570492SJustin Hibbits /*
299c7570492SJustin Hibbits * Offset the instruction pointer to the instruction
300c7570492SJustin Hibbits * following the one causing the fault.
301c7570492SJustin Hibbits */
302c7570492SJustin Hibbits frame->srr0 += sizeof(int);
303c7570492SJustin Hibbits return (1);
304c7570492SJustin Hibbits case EXC_ISI:
305c7570492SJustin Hibbits case EXC_ISE:
306c7570492SJustin Hibbits /* Flag a bad address. */
307c7570492SJustin Hibbits cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_BADADDR;
308c7570492SJustin Hibbits cpu_core[curcpu].cpuc_dtrace_illval = frame->srr0;
309c7570492SJustin Hibbits
310c7570492SJustin Hibbits /*
311c7570492SJustin Hibbits * Offset the instruction pointer to the instruction
312c7570492SJustin Hibbits * following the one causing the fault.
313c7570492SJustin Hibbits */
314c7570492SJustin Hibbits frame->srr0 += sizeof(int);
315c7570492SJustin Hibbits return (1);
316c7570492SJustin Hibbits default:
317c7570492SJustin Hibbits /* Handle all other traps in the usual way. */
318c7570492SJustin Hibbits break;
319c7570492SJustin Hibbits }
320c7570492SJustin Hibbits }
321c7570492SJustin Hibbits
322c7570492SJustin Hibbits /* Handle the trap in the usual way. */
323c7570492SJustin Hibbits return (0);
324c7570492SJustin Hibbits }
325c7570492SJustin Hibbits
326c7570492SJustin Hibbits void
dtrace_probe_error(dtrace_state_t * state,dtrace_epid_t epid,int which,int fault,int fltoffs,uintptr_t illval)327c7570492SJustin Hibbits dtrace_probe_error(dtrace_state_t *state, dtrace_epid_t epid, int which,
328c7570492SJustin Hibbits int fault, int fltoffs, uintptr_t illval)
329c7570492SJustin Hibbits {
330c7570492SJustin Hibbits
331c7570492SJustin Hibbits dtrace_probe(dtrace_probeid_error, (uint64_t)(uintptr_t)state,
332c7570492SJustin Hibbits (uintptr_t)epid,
333c7570492SJustin Hibbits (uintptr_t)which, (uintptr_t)fault, (uintptr_t)fltoffs);
334c7570492SJustin Hibbits }
33580a5635cSJustin Hibbits
33680a5635cSJustin Hibbits static int
dtrace_invop_start(struct trapframe * frame)33780a5635cSJustin Hibbits dtrace_invop_start(struct trapframe *frame)
33880a5635cSJustin Hibbits {
3396c280659SMark Johnston
3406c280659SMark Johnston switch (dtrace_invop(frame->srr0, frame, frame->fixreg[3])) {
34180a5635cSJustin Hibbits case DTRACE_INVOP_JUMP:
34280a5635cSJustin Hibbits break;
34380a5635cSJustin Hibbits case DTRACE_INVOP_BCTR:
34480a5635cSJustin Hibbits frame->srr0 = frame->ctr;
34580a5635cSJustin Hibbits break;
34680a5635cSJustin Hibbits case DTRACE_INVOP_BLR:
34780a5635cSJustin Hibbits frame->srr0 = frame->lr;
34880a5635cSJustin Hibbits break;
34980a5635cSJustin Hibbits case DTRACE_INVOP_MFLR_R0:
35080a5635cSJustin Hibbits frame->fixreg[0] = frame->lr;
351f0bd82a1SJustin Hibbits frame->srr0 = frame->srr0 + 4;
35280a5635cSJustin Hibbits break;
35380a5635cSJustin Hibbits default:
35480a5635cSJustin Hibbits return (-1);
35580a5635cSJustin Hibbits }
35680a5635cSJustin Hibbits return (0);
35780a5635cSJustin Hibbits }
35880a5635cSJustin Hibbits
dtrace_invop_init(void)35980a5635cSJustin Hibbits void dtrace_invop_init(void)
36080a5635cSJustin Hibbits {
36180a5635cSJustin Hibbits dtrace_invop_jump_addr = dtrace_invop_start;
36280a5635cSJustin Hibbits }
36380a5635cSJustin Hibbits
dtrace_invop_uninit(void)36480a5635cSJustin Hibbits void dtrace_invop_uninit(void)
36580a5635cSJustin Hibbits {
36680a5635cSJustin Hibbits dtrace_invop_jump_addr = 0;
36780a5635cSJustin Hibbits }
368