xref: /onnv-gate/usr/src/uts/i86pc/os/dtrace_subr.c (revision 3939:8f689b97125d)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
52179Sahl  * Common Development and Distribution License (the "License").
62179Sahl  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
212179Sahl 
220Sstevel@tonic-gate /*
233446Smrj  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
280Sstevel@tonic-gate 
290Sstevel@tonic-gate #include <sys/dtrace.h>
300Sstevel@tonic-gate #include <sys/fasttrap.h>
310Sstevel@tonic-gate #include <sys/x_call.h>
320Sstevel@tonic-gate #include <sys/cmn_err.h>
330Sstevel@tonic-gate #include <sys/trap.h>
340Sstevel@tonic-gate #include <sys/psw.h>
350Sstevel@tonic-gate #include <sys/privregs.h>
360Sstevel@tonic-gate #include <sys/machsystm.h>
370Sstevel@tonic-gate #include <vm/seg_kmem.h>
380Sstevel@tonic-gate 
390Sstevel@tonic-gate typedef struct dtrace_invop_hdlr {
400Sstevel@tonic-gate 	int (*dtih_func)(uintptr_t, uintptr_t *, uintptr_t);
410Sstevel@tonic-gate 	struct dtrace_invop_hdlr *dtih_next;
420Sstevel@tonic-gate } dtrace_invop_hdlr_t;
430Sstevel@tonic-gate 
440Sstevel@tonic-gate dtrace_invop_hdlr_t *dtrace_invop_hdlr;
450Sstevel@tonic-gate 
460Sstevel@tonic-gate int
470Sstevel@tonic-gate dtrace_invop(uintptr_t addr, uintptr_t *stack, uintptr_t eax)
480Sstevel@tonic-gate {
490Sstevel@tonic-gate 	dtrace_invop_hdlr_t *hdlr;
500Sstevel@tonic-gate 	int rval;
510Sstevel@tonic-gate 
520Sstevel@tonic-gate 	for (hdlr = dtrace_invop_hdlr; hdlr != NULL; hdlr = hdlr->dtih_next) {
530Sstevel@tonic-gate 		if ((rval = hdlr->dtih_func(addr, stack, eax)) != 0)
540Sstevel@tonic-gate 			return (rval);
550Sstevel@tonic-gate 	}
560Sstevel@tonic-gate 
570Sstevel@tonic-gate 	return (0);
580Sstevel@tonic-gate }
590Sstevel@tonic-gate 
600Sstevel@tonic-gate void
610Sstevel@tonic-gate dtrace_invop_add(int (*func)(uintptr_t, uintptr_t *, uintptr_t))
620Sstevel@tonic-gate {
630Sstevel@tonic-gate 	dtrace_invop_hdlr_t *hdlr;
640Sstevel@tonic-gate 
650Sstevel@tonic-gate 	hdlr = kmem_alloc(sizeof (dtrace_invop_hdlr_t), KM_SLEEP);
660Sstevel@tonic-gate 	hdlr->dtih_func = func;
670Sstevel@tonic-gate 	hdlr->dtih_next = dtrace_invop_hdlr;
680Sstevel@tonic-gate 	dtrace_invop_hdlr = hdlr;
690Sstevel@tonic-gate }
700Sstevel@tonic-gate 
710Sstevel@tonic-gate void
720Sstevel@tonic-gate dtrace_invop_remove(int (*func)(uintptr_t, uintptr_t *, uintptr_t))
730Sstevel@tonic-gate {
740Sstevel@tonic-gate 	dtrace_invop_hdlr_t *hdlr = dtrace_invop_hdlr, *prev = NULL;
750Sstevel@tonic-gate 
760Sstevel@tonic-gate 	for (;;) {
770Sstevel@tonic-gate 		if (hdlr == NULL)
780Sstevel@tonic-gate 			panic("attempt to remove non-existent invop handler");
790Sstevel@tonic-gate 
800Sstevel@tonic-gate 		if (hdlr->dtih_func == func)
810Sstevel@tonic-gate 			break;
820Sstevel@tonic-gate 
830Sstevel@tonic-gate 		prev = hdlr;
840Sstevel@tonic-gate 		hdlr = hdlr->dtih_next;
850Sstevel@tonic-gate 	}
860Sstevel@tonic-gate 
870Sstevel@tonic-gate 	if (prev == NULL) {
880Sstevel@tonic-gate 		ASSERT(dtrace_invop_hdlr == hdlr);
890Sstevel@tonic-gate 		dtrace_invop_hdlr = hdlr->dtih_next;
900Sstevel@tonic-gate 	} else {
910Sstevel@tonic-gate 		ASSERT(dtrace_invop_hdlr != hdlr);
920Sstevel@tonic-gate 		prev->dtih_next = hdlr->dtih_next;
930Sstevel@tonic-gate 	}
940Sstevel@tonic-gate 
950Sstevel@tonic-gate 	kmem_free(hdlr, sizeof (dtrace_invop_hdlr_t));
960Sstevel@tonic-gate }
970Sstevel@tonic-gate 
980Sstevel@tonic-gate int
990Sstevel@tonic-gate dtrace_getipl(void)
1000Sstevel@tonic-gate {
1010Sstevel@tonic-gate 	return (CPU->cpu_pri);
1020Sstevel@tonic-gate }
1030Sstevel@tonic-gate 
1040Sstevel@tonic-gate /*ARGSUSED*/
1050Sstevel@tonic-gate void
1060Sstevel@tonic-gate dtrace_toxic_ranges(void (*func)(uintptr_t base, uintptr_t limit))
1070Sstevel@tonic-gate {
1080Sstevel@tonic-gate #ifdef __amd64
1090Sstevel@tonic-gate 	extern uintptr_t toxic_addr;
1100Sstevel@tonic-gate 	extern size_t toxic_size;
1110Sstevel@tonic-gate 
1120Sstevel@tonic-gate 	(*func)(0, _userlimit);
1130Sstevel@tonic-gate 
1140Sstevel@tonic-gate 	if (hole_end > hole_start)
1150Sstevel@tonic-gate 		(*func)(hole_start, hole_end);
1160Sstevel@tonic-gate 	(*func)(toxic_addr, toxic_addr + toxic_size);
1170Sstevel@tonic-gate #else
1180Sstevel@tonic-gate 	extern void *device_arena_contains(void *, size_t, size_t *);
1190Sstevel@tonic-gate 	caddr_t	vaddr;
1200Sstevel@tonic-gate 	size_t	len;
1210Sstevel@tonic-gate 
1220Sstevel@tonic-gate 	for (vaddr = (caddr_t)kernelbase; vaddr < (caddr_t)KERNEL_TEXT;
1230Sstevel@tonic-gate 	    vaddr += len) {
1240Sstevel@tonic-gate 		len = (caddr_t)KERNEL_TEXT - vaddr;
1250Sstevel@tonic-gate 		vaddr = device_arena_contains(vaddr, len, &len);
1260Sstevel@tonic-gate 		if (vaddr == NULL)
1270Sstevel@tonic-gate 		    break;
1280Sstevel@tonic-gate 		(*func)((uintptr_t)vaddr, (uintptr_t)vaddr + len);
1290Sstevel@tonic-gate 	}
1300Sstevel@tonic-gate #endif
1310Sstevel@tonic-gate 	(*func)(0, _userlimit);
1320Sstevel@tonic-gate }
1330Sstevel@tonic-gate 
1340Sstevel@tonic-gate static int
1350Sstevel@tonic-gate dtrace_xcall_func(dtrace_xcall_t func, void *arg)
1360Sstevel@tonic-gate {
1370Sstevel@tonic-gate 	(*func)(arg);
1380Sstevel@tonic-gate 
1390Sstevel@tonic-gate 	return (0);
1400Sstevel@tonic-gate }
1410Sstevel@tonic-gate 
1420Sstevel@tonic-gate /*ARGSUSED*/
1430Sstevel@tonic-gate void
1440Sstevel@tonic-gate dtrace_xcall(processorid_t cpu, dtrace_xcall_t func, void *arg)
1450Sstevel@tonic-gate {
1460Sstevel@tonic-gate 	cpuset_t set;
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate 	CPUSET_ZERO(set);
1490Sstevel@tonic-gate 
1500Sstevel@tonic-gate 	if (cpu == DTRACE_CPUALL) {
1510Sstevel@tonic-gate 		CPUSET_ALL(set);
1520Sstevel@tonic-gate 	} else {
1530Sstevel@tonic-gate 		CPUSET_ADD(set, cpu);
1540Sstevel@tonic-gate 	}
1550Sstevel@tonic-gate 
1560Sstevel@tonic-gate 	kpreempt_disable();
1570Sstevel@tonic-gate 	xc_sync((xc_arg_t)func, (xc_arg_t)arg, 0, X_CALL_HIPRI, set,
1580Sstevel@tonic-gate 		(xc_func_t)dtrace_xcall_func);
1590Sstevel@tonic-gate 	kpreempt_enable();
1600Sstevel@tonic-gate }
1610Sstevel@tonic-gate 
1620Sstevel@tonic-gate void
1630Sstevel@tonic-gate dtrace_sync_func(void)
1640Sstevel@tonic-gate {}
1650Sstevel@tonic-gate 
1660Sstevel@tonic-gate void
1670Sstevel@tonic-gate dtrace_sync(void)
1680Sstevel@tonic-gate {
1690Sstevel@tonic-gate 	dtrace_xcall(DTRACE_CPUALL, (dtrace_xcall_t)dtrace_sync_func, NULL);
1700Sstevel@tonic-gate }
1710Sstevel@tonic-gate 
1720Sstevel@tonic-gate int (*dtrace_pid_probe_ptr)(struct regs *);
1730Sstevel@tonic-gate int (*dtrace_return_probe_ptr)(struct regs *);
1740Sstevel@tonic-gate 
1750Sstevel@tonic-gate void
1760Sstevel@tonic-gate dtrace_user_probe(struct regs *rp, caddr_t addr, processorid_t cpuid)
1770Sstevel@tonic-gate {
1780Sstevel@tonic-gate 	krwlock_t *rwp;
1790Sstevel@tonic-gate 	proc_t *p = curproc;
1800Sstevel@tonic-gate 	extern void trap(struct regs *, caddr_t, processorid_t);
1810Sstevel@tonic-gate 
1820Sstevel@tonic-gate 	if (USERMODE(rp->r_cs) || (rp->r_ps & PS_VM)) {
1830Sstevel@tonic-gate 		if (curthread->t_cred != p->p_cred) {
1840Sstevel@tonic-gate 			cred_t *oldcred = curthread->t_cred;
1850Sstevel@tonic-gate 			/*
1860Sstevel@tonic-gate 			 * DTrace accesses t_cred in probe context.  t_cred
1870Sstevel@tonic-gate 			 * must always be either NULL, or point to a valid,
1880Sstevel@tonic-gate 			 * allocated cred structure.
1890Sstevel@tonic-gate 			 */
1900Sstevel@tonic-gate 			curthread->t_cred = crgetcred();
1910Sstevel@tonic-gate 			crfree(oldcred);
1920Sstevel@tonic-gate 		}
1930Sstevel@tonic-gate 	}
1940Sstevel@tonic-gate 
1950Sstevel@tonic-gate 	if (rp->r_trapno == T_DTRACE_RET) {
1960Sstevel@tonic-gate 		uint8_t step = curthread->t_dtrace_step;
1970Sstevel@tonic-gate 		uint8_t ret = curthread->t_dtrace_ret;
1980Sstevel@tonic-gate 		uintptr_t npc = curthread->t_dtrace_npc;
1990Sstevel@tonic-gate 
2000Sstevel@tonic-gate 		if (curthread->t_dtrace_ast) {
2010Sstevel@tonic-gate 			aston(curthread);
2020Sstevel@tonic-gate 			curthread->t_sig_check = 1;
2030Sstevel@tonic-gate 		}
2040Sstevel@tonic-gate 
2050Sstevel@tonic-gate 		/*
2060Sstevel@tonic-gate 		 * Clear all user tracing flags.
2070Sstevel@tonic-gate 		 */
2080Sstevel@tonic-gate 		curthread->t_dtrace_ft = 0;
2090Sstevel@tonic-gate 
2100Sstevel@tonic-gate 		/*
2110Sstevel@tonic-gate 		 * If we weren't expecting to take a return probe trap, kill
2120Sstevel@tonic-gate 		 * the process as though it had just executed an unassigned
2130Sstevel@tonic-gate 		 * trap instruction.
2140Sstevel@tonic-gate 		 */
2150Sstevel@tonic-gate 		if (step == 0) {
2160Sstevel@tonic-gate 			tsignal(curthread, SIGILL);
2170Sstevel@tonic-gate 			return;
2180Sstevel@tonic-gate 		}
2190Sstevel@tonic-gate 
2200Sstevel@tonic-gate 		/*
2210Sstevel@tonic-gate 		 * If we hit this trap unrelated to a return probe, we're
2220Sstevel@tonic-gate 		 * just here to reset the AST flag since we deferred a signal
2230Sstevel@tonic-gate 		 * until after we logically single-stepped the instruction we
2240Sstevel@tonic-gate 		 * copied out.
2250Sstevel@tonic-gate 		 */
2260Sstevel@tonic-gate 		if (ret == 0) {
2270Sstevel@tonic-gate 			rp->r_pc = npc;
2280Sstevel@tonic-gate 			return;
2290Sstevel@tonic-gate 		}
2300Sstevel@tonic-gate 
2310Sstevel@tonic-gate 		/*
2320Sstevel@tonic-gate 		 * We need to wait until after we've called the
2330Sstevel@tonic-gate 		 * dtrace_return_probe_ptr function pointer to set %pc.
2340Sstevel@tonic-gate 		 */
2350Sstevel@tonic-gate 		rwp = &CPU->cpu_ft_lock;
2360Sstevel@tonic-gate 		rw_enter(rwp, RW_READER);
2370Sstevel@tonic-gate 		if (dtrace_return_probe_ptr != NULL)
2380Sstevel@tonic-gate 			(void) (*dtrace_return_probe_ptr)(rp);
2390Sstevel@tonic-gate 		rw_exit(rwp);
2400Sstevel@tonic-gate 		rp->r_pc = npc;
2410Sstevel@tonic-gate 
2420Sstevel@tonic-gate 	} else if (rp->r_trapno == T_BPTFLT) {
243*3939Ssethg 		uint8_t instr, instr2;
244*3939Ssethg 		caddr_t linearpc;
2450Sstevel@tonic-gate 		rwp = &CPU->cpu_ft_lock;
2460Sstevel@tonic-gate 
2470Sstevel@tonic-gate 		/*
2480Sstevel@tonic-gate 		 * The DTrace fasttrap provider uses the breakpoint trap
2490Sstevel@tonic-gate 		 * (int 3). We let DTrace take the first crack at handling
2500Sstevel@tonic-gate 		 * this trap; if it's not a probe that DTrace knowns about,
2510Sstevel@tonic-gate 		 * we call into the trap() routine to handle it like a
2520Sstevel@tonic-gate 		 * breakpoint placed by a conventional debugger.
2530Sstevel@tonic-gate 		 */
2540Sstevel@tonic-gate 		rw_enter(rwp, RW_READER);
2550Sstevel@tonic-gate 		if (dtrace_pid_probe_ptr != NULL &&
2560Sstevel@tonic-gate 		    (*dtrace_pid_probe_ptr)(rp) == 0) {
2570Sstevel@tonic-gate 			rw_exit(rwp);
2580Sstevel@tonic-gate 			return;
2590Sstevel@tonic-gate 		}
2600Sstevel@tonic-gate 		rw_exit(rwp);
2610Sstevel@tonic-gate 
262*3939Ssethg 		if (dtrace_linear_pc(rp, p, &linearpc) != 0) {
263*3939Ssethg 			trap(rp, addr, cpuid);
264*3939Ssethg 			return;
265*3939Ssethg 		}
266*3939Ssethg 
2670Sstevel@tonic-gate 		/*
2680Sstevel@tonic-gate 		 * If the instruction that caused the breakpoint trap doesn't
2690Sstevel@tonic-gate 		 * look like an int 3 anymore, it may be that this tracepoint
2700Sstevel@tonic-gate 		 * was removed just after the user thread executed it. In
2710Sstevel@tonic-gate 		 * that case, return to user land to retry the instuction.
272*3939Ssethg 		 * Note that we assume the length of the instruction to retry
273*3939Ssethg 		 * is 1 byte because that's the length of FASTTRAP_INSTR.
274*3939Ssethg 		 * We check for r_pc > 0 and > 2 so that we don't have to
275*3939Ssethg 		 * deal with segment wraparound.
2760Sstevel@tonic-gate 		 */
277*3939Ssethg 		if (rp->r_pc > 0 && fuword8(linearpc - 1, &instr) == 0 &&
278*3939Ssethg 		    instr != FASTTRAP_INSTR &&
279*3939Ssethg 		    (instr != 3 || (rp->r_pc >= 2 &&
280*3939Ssethg 		    (fuword8(linearpc - 2, &instr2) != 0 || instr2 != 0xCD)))) {
2810Sstevel@tonic-gate 			rp->r_pc--;
2820Sstevel@tonic-gate 			return;
2830Sstevel@tonic-gate 		}
2840Sstevel@tonic-gate 
2850Sstevel@tonic-gate 		trap(rp, addr, cpuid);
2860Sstevel@tonic-gate 
2870Sstevel@tonic-gate 	} else {
2880Sstevel@tonic-gate 		trap(rp, addr, cpuid);
2890Sstevel@tonic-gate 	}
2900Sstevel@tonic-gate }
2910Sstevel@tonic-gate 
2920Sstevel@tonic-gate void
2930Sstevel@tonic-gate dtrace_safe_synchronous_signal(void)
2940Sstevel@tonic-gate {
2950Sstevel@tonic-gate 	kthread_t *t = curthread;
2960Sstevel@tonic-gate 	struct regs *rp = lwptoregs(ttolwp(t));
2970Sstevel@tonic-gate 	size_t isz = t->t_dtrace_npc - t->t_dtrace_pc;
2980Sstevel@tonic-gate 
2990Sstevel@tonic-gate 	ASSERT(t->t_dtrace_on);
3000Sstevel@tonic-gate 
3010Sstevel@tonic-gate 	/*
3020Sstevel@tonic-gate 	 * If we're not in the range of scratch addresses, we're not actually
3030Sstevel@tonic-gate 	 * tracing user instructions so turn off the flags. If the instruction
3040Sstevel@tonic-gate 	 * we copied out caused a synchonous trap, reset the pc back to its
3050Sstevel@tonic-gate 	 * original value and turn off the flags.
3060Sstevel@tonic-gate 	 */
3070Sstevel@tonic-gate 	if (rp->r_pc < t->t_dtrace_scrpc ||
3080Sstevel@tonic-gate 	    rp->r_pc > t->t_dtrace_astpc + isz) {
3090Sstevel@tonic-gate 		t->t_dtrace_ft = 0;
3100Sstevel@tonic-gate 	} else if (rp->r_pc == t->t_dtrace_scrpc ||
3110Sstevel@tonic-gate 	    rp->r_pc == t->t_dtrace_astpc) {
3120Sstevel@tonic-gate 		rp->r_pc = t->t_dtrace_pc;
3130Sstevel@tonic-gate 		t->t_dtrace_ft = 0;
3140Sstevel@tonic-gate 	}
3150Sstevel@tonic-gate }
3160Sstevel@tonic-gate 
3170Sstevel@tonic-gate int
3180Sstevel@tonic-gate dtrace_safe_defer_signal(void)
3190Sstevel@tonic-gate {
3200Sstevel@tonic-gate 	kthread_t *t = curthread;
3210Sstevel@tonic-gate 	struct regs *rp = lwptoregs(ttolwp(t));
3220Sstevel@tonic-gate 	size_t isz = t->t_dtrace_npc - t->t_dtrace_pc;
3230Sstevel@tonic-gate 
3240Sstevel@tonic-gate 	ASSERT(t->t_dtrace_on);
3250Sstevel@tonic-gate 
3260Sstevel@tonic-gate 	/*
3270Sstevel@tonic-gate 	 * If we're not in the range of scratch addresses, we're not actually
3280Sstevel@tonic-gate 	 * tracing user instructions so turn off the flags.
3290Sstevel@tonic-gate 	 */
3300Sstevel@tonic-gate 	if (rp->r_pc < t->t_dtrace_scrpc ||
3310Sstevel@tonic-gate 	    rp->r_pc > t->t_dtrace_astpc + isz) {
3320Sstevel@tonic-gate 		t->t_dtrace_ft = 0;
3330Sstevel@tonic-gate 		return (0);
3340Sstevel@tonic-gate 	}
3350Sstevel@tonic-gate 
3360Sstevel@tonic-gate 	/*
3370Sstevel@tonic-gate 	 * If we've executed the original instruction, but haven't performed
3380Sstevel@tonic-gate 	 * the jmp back to t->t_dtrace_npc or the clean up of any registers
3390Sstevel@tonic-gate 	 * used to emulate %rip-relative instructions in 64-bit mode, do that
3400Sstevel@tonic-gate 	 * here and take the signal right away. We detect this condition by
3410Sstevel@tonic-gate 	 * seeing if the program counter is the range [scrpc + isz, astpc).
3420Sstevel@tonic-gate 	 */
3430Sstevel@tonic-gate 	if (t->t_dtrace_astpc - rp->r_pc <
3440Sstevel@tonic-gate 	    t->t_dtrace_astpc - t->t_dtrace_scrpc - isz) {
3450Sstevel@tonic-gate #ifdef __amd64
3460Sstevel@tonic-gate 		/*
3470Sstevel@tonic-gate 		 * If there is a scratch register and we're on the
3480Sstevel@tonic-gate 		 * instruction immediately after the modified instruction,
3490Sstevel@tonic-gate 		 * restore the value of that scratch register.
3500Sstevel@tonic-gate 		 */
3510Sstevel@tonic-gate 		if (t->t_dtrace_reg != 0 &&
3520Sstevel@tonic-gate 		    rp->r_pc == t->t_dtrace_scrpc + isz) {
3530Sstevel@tonic-gate 			switch (t->t_dtrace_reg) {
3540Sstevel@tonic-gate 			case REG_RAX:
3550Sstevel@tonic-gate 				rp->r_rax = t->t_dtrace_regv;
3560Sstevel@tonic-gate 				break;
3570Sstevel@tonic-gate 			case REG_RCX:
3580Sstevel@tonic-gate 				rp->r_rcx = t->t_dtrace_regv;
3590Sstevel@tonic-gate 				break;
3600Sstevel@tonic-gate 			case REG_R8:
3610Sstevel@tonic-gate 				rp->r_r8 = t->t_dtrace_regv;
3620Sstevel@tonic-gate 				break;
3630Sstevel@tonic-gate 			case REG_R9:
3640Sstevel@tonic-gate 				rp->r_r9 = t->t_dtrace_regv;
3650Sstevel@tonic-gate 				break;
3660Sstevel@tonic-gate 			}
3670Sstevel@tonic-gate 		}
3680Sstevel@tonic-gate #endif
3690Sstevel@tonic-gate 		rp->r_pc = t->t_dtrace_npc;
3700Sstevel@tonic-gate 		t->t_dtrace_ft = 0;
3710Sstevel@tonic-gate 		return (0);
3720Sstevel@tonic-gate 	}
3730Sstevel@tonic-gate 
3740Sstevel@tonic-gate 	/*
3750Sstevel@tonic-gate 	 * Otherwise, make sure we'll return to the kernel after executing
3760Sstevel@tonic-gate 	 * the copied out instruction and defer the signal.
3770Sstevel@tonic-gate 	 */
3780Sstevel@tonic-gate 	if (!t->t_dtrace_step) {
3790Sstevel@tonic-gate 		ASSERT(rp->r_pc < t->t_dtrace_astpc);
3800Sstevel@tonic-gate 		rp->r_pc += t->t_dtrace_astpc - t->t_dtrace_scrpc;
3810Sstevel@tonic-gate 		t->t_dtrace_step = 1;
3820Sstevel@tonic-gate 	}
3830Sstevel@tonic-gate 
3840Sstevel@tonic-gate 	t->t_dtrace_ast = 1;
3850Sstevel@tonic-gate 
3860Sstevel@tonic-gate 	return (1);
3870Sstevel@tonic-gate }
3883446Smrj 
3893446Smrj /*
3903446Smrj  * Additional artificial frames for the machine type. For i86pc, we're already
3913446Smrj  * accounted for, so return 0.
3923446Smrj  */
3933446Smrj int
3943446Smrj dtrace_mach_aframes(void)
3953446Smrj {
3963446Smrj 	return (0);
3973446Smrj }
398