Home | History | Annotate | Line # | Download | only in i386
dtrace_isa.c revision 1.4.4.1
      1 /*	$NetBSD: dtrace_isa.c,v 1.4.4.1 2017/04/21 16:52:40 bouyer Exp $	*/
      2 
      3 /*
      4  * CDDL HEADER START
      5  *
      6  * The contents of this file are subject to the terms of the
      7  * Common Development and Distribution License, Version 1.0 only
      8  * (the "License").  You may not use this file except in compliance
      9  * with the License.
     10  *
     11  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     12  * or http://www.opensolaris.org/os/licensing.
     13  * See the License for the specific language governing permissions
     14  * and limitations under the License.
     15  *
     16  * When distributing Covered Code, include this CDDL HEADER in each
     17  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     18  * If applicable, add the following below this CDDL HEADER, with the
     19  * fields enclosed by brackets "[]" replaced with your own identifying
     20  * information: Portions Copyright [yyyy] [name of copyright owner]
     21  *
     22  * CDDL HEADER END
     23  *
     24  * $FreeBSD: src/sys/cddl/dev/dtrace/i386/dtrace_isa.c,v 1.1.4.1 2009/08/03 08:13:06 kensmith Exp $
     25  */
     26 /*
     27  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
     28  * Use is subject to license terms.
     29  */
     30 #include <sys/cdefs.h>
     31 
     32 #include <sys/param.h>
     33 #include <sys/systm.h>
     34 #include <sys/kernel.h>
     35 
     36 #include <machine/vmparam.h>
     37 #include <machine/pmap.h>
     38 
     39 uintptr_t kernelbase = (uintptr_t)KERNBASE;
     40 
     41 #define INKERNEL(va) \
     42 	(((vm_offset_t)(va)) >= VM_MIN_KERNEL_ADDRESS && \
     43 	 ((vm_offset_t)(va)) < VM_MAX_KERNEL_ADDRESS)
     44 
     45 struct i386_frame {
     46 	struct i386_frame	*f_frame;
     47 	int			 f_retaddr;
     48 };
     49 
     50 typedef	unsigned long	vm_offset_t;
     51 
     52 uint8_t dtrace_fuword8_nocheck(void *);
     53 uint16_t dtrace_fuword16_nocheck(void *);
     54 uint32_t dtrace_fuword32_nocheck(void *);
     55 uint64_t dtrace_fuword64_nocheck(void *);
     56 
     57 void
     58 dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes,
     59     uint32_t *intrpc)
     60 {
     61 	int depth = 0;
     62 	register_t ebp;
     63 	struct i386_frame *frame;
     64 	vm_offset_t callpc;
     65 	pc_t caller = (pc_t) solaris_cpu[cpu_number()].cpu_dtrace_caller;
     66 
     67 	if (intrpc != 0)
     68 		pcstack[depth++] = (pc_t) intrpc;
     69 
     70 	aframes++;
     71 
     72 	__asm __volatile("movl %%ebp,%0" : "=r" (ebp));
     73 
     74 	frame = (struct i386_frame *)ebp;
     75 	while (depth < pcstack_limit) {
     76 		if (!INKERNEL(frame))
     77 			break;
     78 
     79 		callpc = frame->f_retaddr;
     80 
     81 		if (!INKERNEL(callpc))
     82 			break;
     83 
     84 		if (aframes > 0) {
     85 			aframes--;
     86 			if ((aframes == 0) && (caller != 0)) {
     87 				pcstack[depth++] = caller;
     88 			}
     89 		}
     90 		else {
     91 			pcstack[depth++] = callpc;
     92 		}
     93 
     94 		if (frame->f_frame <= frame ||
     95 		    (vm_offset_t)frame->f_frame >=
     96 		    (vm_offset_t)ebp + KSTACK_SIZE)
     97 			break;
     98 		frame = frame->f_frame;
     99 	}
    100 
    101 	for (; depth < pcstack_limit; depth++) {
    102 		pcstack[depth] = 0;
    103 	}
    104 }
    105 
    106 static int
    107 dtrace_getustack_common(uint64_t *pcstack, int pcstack_limit, uintptr_t pc,
    108     uintptr_t sp)
    109 {
    110 #ifdef notyet
    111 	proc_t *p = curproc;
    112 	uintptr_t oldcontext = lwp->lwp_oldcontext; /* XXX signal stack. */
    113 	size_t s1, s2;
    114 #endif
    115 	volatile uint16_t *flags =
    116 	    (volatile uint16_t *)&cpu_core[cpu_number()].cpuc_dtrace_flags;
    117 	int ret = 0;
    118 
    119 	ASSERT(pcstack == NULL || pcstack_limit > 0);
    120 
    121 #ifdef notyet /* XXX signal stack. */
    122 	if (p->p_model == DATAMODEL_NATIVE) {
    123 		s1 = sizeof (struct frame) + 2 * sizeof (long);
    124 		s2 = s1 + sizeof (siginfo_t);
    125 	} else {
    126 		s1 = sizeof (struct frame32) + 3 * sizeof (int);
    127 		s2 = s1 + sizeof (siginfo32_t);
    128 	}
    129 #endif
    130 
    131 	while (pc != 0) {
    132 		ret++;
    133 		if (pcstack != NULL) {
    134 			*pcstack++ = (uint64_t)pc;
    135 			pcstack_limit--;
    136 			if (pcstack_limit <= 0)
    137 				break;
    138 		}
    139 
    140 		if (sp == 0)
    141 			break;
    142 
    143 #ifdef notyet /* XXX signal stack. */
    144 		if (oldcontext == sp + s1 || oldcontext == sp + s2) {
    145 			if (p->p_model == DATAMODEL_NATIVE) {
    146 				ucontext_t *ucp = (ucontext_t *)oldcontext;
    147 				greg_t *gregs = ucp->uc_mcontext.gregs;
    148 
    149 				sp = dtrace_fulword(&gregs[REG_FP]);
    150 				pc = dtrace_fulword(&gregs[REG_PC]);
    151 
    152 				oldcontext = dtrace_fulword(&ucp->uc_link);
    153 			} else {
    154 				ucontext32_t *ucp = (ucontext32_t *)oldcontext;
    155 				greg32_t *gregs = ucp->uc_mcontext.gregs;
    156 
    157 				sp = dtrace_fuword32(&gregs[EBP]);
    158 				pc = dtrace_fuword32(&gregs[EIP]);
    159 
    160 				oldcontext = dtrace_fuword32(&ucp->uc_link);
    161 			}
    162 		} else {
    163 			if (p->p_model == DATAMODEL_NATIVE) {
    164 				struct frame *fr = (struct frame *)sp;
    165 
    166 				pc = dtrace_fulword(&fr->fr_savpc);
    167 				sp = dtrace_fulword(&fr->fr_savfp);
    168 			} else {
    169 				struct frame32 *fr = (struct frame32 *)sp;
    170 
    171 				pc = dtrace_fuword32(&fr->fr_savpc);
    172 				sp = dtrace_fuword32(&fr->fr_savfp);
    173 			}
    174 		}
    175 #else
    176 		pc = dtrace_fuword32((void *)(sp +
    177 			offsetof(struct i386_frame, f_retaddr)));
    178 		sp = dtrace_fuword32((void *)sp);
    179 #endif /* ! notyet */
    180 
    181 		/*
    182 		 * This is totally bogus:  if we faulted, we're going to clear
    183 		 * the fault and break.  This is to deal with the apparently
    184 		 * broken Java stacks on x86.
    185 		 */
    186 		if (*flags & CPU_DTRACE_FAULT) {
    187 			*flags &= ~CPU_DTRACE_FAULT;
    188 			break;
    189 		}
    190 	}
    191 
    192 	return (ret);
    193 }
    194 
    195 void
    196 dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit)
    197 {
    198 	proc_t *p = curproc;
    199 	struct trapframe *tf;
    200 	uintptr_t pc, sp, fp;
    201 	volatile uint16_t *flags =
    202 	    (volatile uint16_t *)&cpu_core[cpu_number()].cpuc_dtrace_flags;
    203 	int n;
    204 
    205 	if (*flags & CPU_DTRACE_FAULT)
    206 		return;
    207 
    208 	if (pcstack_limit <= 0)
    209 		return;
    210 
    211 	/*
    212 	 * If there's no user context we still need to zero the stack.
    213 	 */
    214 	if (p == NULL || (tf = curlwp->l_md.md_regs) == NULL)
    215 		goto zero;
    216 
    217 	*pcstack++ = (uint64_t)p->p_pid;
    218 	pcstack_limit--;
    219 
    220 	if (pcstack_limit <= 0)
    221 		return;
    222 
    223 	pc = tf->tf_eip;
    224 	fp = tf->tf_ebp;
    225 	sp = tf->tf_esp;
    226 
    227 	if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) {
    228 		/*
    229 		 * In an entry probe.  The frame pointer has not yet been
    230 		 * pushed (that happens in the function prologue).  The
    231 		 * best approach is to add the current pc as a missing top
    232 		 * of stack and back the pc up to the caller, which is stored
    233 		 * at the current stack pointer address since the call
    234 		 * instruction puts it there right before the branch.
    235 		 */
    236 
    237 		*pcstack++ = (uint64_t)pc;
    238 		pcstack_limit--;
    239 		if (pcstack_limit <= 0)
    240 			return;
    241 
    242 		pc = dtrace_fuword32((void *) sp);
    243 	}
    244 
    245 	n = dtrace_getustack_common(pcstack, pcstack_limit, pc, fp);
    246 	ASSERT(n >= 0);
    247 	ASSERT(n <= pcstack_limit);
    248 
    249 	pcstack += n;
    250 	pcstack_limit -= n;
    251 
    252 zero:
    253 	while (pcstack_limit-- > 0)
    254 		*pcstack++ = 0;
    255 }
    256 
    257 int
    258 dtrace_getustackdepth(void)
    259 {
    260 	proc_t *p = curproc;
    261 	struct trapframe *tf;
    262 	uintptr_t pc, fp, sp;
    263 	int n = 0;
    264 
    265 	if (p == NULL || (tf = curlwp->l_md.md_regs) == NULL)
    266 		return (0);
    267 
    268 	if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_FAULT))
    269 		return (-1);
    270 
    271 	pc = tf->tf_eip;
    272 	fp = tf->tf_ebp;
    273 	sp = tf->tf_esp;
    274 
    275 	if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) {
    276 		/*
    277 		 * In an entry probe.  The frame pointer has not yet been
    278 		 * pushed (that happens in the function prologue).  The
    279 		 * best approach is to add the current pc as a missing top
    280 		 * of stack and back the pc up to the caller, which is stored
    281 		 * at the current stack pointer address since the call
    282 		 * instruction puts it there right before the branch.
    283 		 */
    284 
    285 		pc = dtrace_fuword32((void *) sp);
    286 		n++;
    287 	}
    288 
    289 	n += dtrace_getustack_common(NULL, 0, pc, fp);
    290 
    291 	return (n);
    292 }
    293 
    294 void
    295 dtrace_getufpstack(uint64_t *pcstack, uint64_t *fpstack, int pcstack_limit)
    296 {
    297 	proc_t *p = curproc;
    298 	struct trapframe *tf;
    299 	uintptr_t pc, sp, fp;
    300 	volatile uint16_t *flags =
    301 	    (volatile uint16_t *)&cpu_core[cpu_number()].cpuc_dtrace_flags;
    302 #ifdef notyet /* XXX signal stack */
    303 	uintptr_t oldcontext;
    304 	size_t s1, s2;
    305 #endif
    306 
    307 	if (*flags & CPU_DTRACE_FAULT)
    308 		return;
    309 
    310 	if (pcstack_limit <= 0)
    311 		return;
    312 
    313 	/*
    314 	 * If there's no user context we still need to zero the stack.
    315 	 */
    316 	if (p == NULL || (tf = curlwp->l_md.md_regs) == NULL)
    317 		goto zero;
    318 
    319 	*pcstack++ = (uint64_t)p->p_pid;
    320 	pcstack_limit--;
    321 
    322 	if (pcstack_limit <= 0)
    323 		return;
    324 
    325 	pc = tf->tf_eip;
    326 	fp = tf->tf_ebp;
    327 	sp = tf->tf_esp;
    328 
    329 #ifdef notyet /* XXX signal stack */
    330 	oldcontext = lwp->lwp_oldcontext;
    331 
    332 	if (p->p_model == DATAMODEL_NATIVE) {
    333 		s1 = sizeof (struct frame) + 2 * sizeof (long);
    334 		s2 = s1 + sizeof (siginfo_t);
    335 	} else {
    336 		s1 = sizeof (struct frame32) + 3 * sizeof (int);
    337 		s2 = s1 + sizeof (siginfo32_t);
    338 	}
    339 #endif
    340 
    341 	if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) {
    342 		*pcstack++ = (uint64_t)pc;
    343 		*fpstack++ = 0;
    344 		pcstack_limit--;
    345 		if (pcstack_limit <= 0)
    346 			return;
    347 
    348 		pc = dtrace_fuword32((void *)sp);
    349 	}
    350 
    351 	while (pc != 0) {
    352 		*pcstack++ = (uint64_t)pc;
    353 		*fpstack++ = fp;
    354 		pcstack_limit--;
    355 		if (pcstack_limit <= 0)
    356 			break;
    357 
    358 		if (fp == 0)
    359 			break;
    360 
    361 #ifdef notyet /* XXX signal stack */
    362 		if (oldcontext == sp + s1 || oldcontext == sp + s2) {
    363 			if (p->p_model == DATAMODEL_NATIVE) {
    364 				ucontext_t *ucp = (ucontext_t *)oldcontext;
    365 				greg_t *gregs = ucp->uc_mcontext.gregs;
    366 
    367 				sp = dtrace_fulword(&gregs[REG_FP]);
    368 				pc = dtrace_fulword(&gregs[REG_PC]);
    369 
    370 				oldcontext = dtrace_fulword(&ucp->uc_link);
    371 			} else {
    372 				ucontext_t *ucp = (ucontext_t *)oldcontext;
    373 				greg_t *gregs = ucp->uc_mcontext.gregs;
    374 
    375 				sp = dtrace_fuword32(&gregs[EBP]);
    376 				pc = dtrace_fuword32(&gregs[EIP]);
    377 
    378 				oldcontext = dtrace_fuword32(&ucp->uc_link);
    379 			}
    380 		} else
    381 #endif /* XXX */
    382 		{
    383 			pc = dtrace_fuword32((void *)(fp +
    384 				offsetof(struct i386_frame, f_retaddr)));
    385 			fp = dtrace_fuword32((void *)fp);
    386 		}
    387 
    388 		/*
    389 		 * This is totally bogus:  if we faulted, we're going to clear
    390 		 * the fault and break.  This is to deal with the apparently
    391 		 * broken Java stacks on x86.
    392 		 */
    393 		if (*flags & CPU_DTRACE_FAULT) {
    394 			*flags &= ~CPU_DTRACE_FAULT;
    395 			break;
    396 		}
    397 	}
    398 
    399 zero:
    400 	while (pcstack_limit-- > 0)
    401 		*pcstack++ = 0;
    402 }
    403 
    404 uint64_t
    405 dtrace_getarg(int arg, int aframes)
    406 {
    407 	struct trapframe *frame;
    408 	struct i386_frame *fp = (struct i386_frame *)dtrace_getfp();
    409 	uintptr_t *stack, val;
    410 	int i;
    411 
    412 	for (i = 1; i <= aframes; i++) {
    413 		fp = fp->f_frame;
    414 
    415 		if (P2ROUNDUP(fp->f_retaddr, 16) ==
    416 		    (long)dtrace_invop_callsite) {
    417 			/*
    418 			 * If we pass through the invalid op handler, we will
    419 			 * use the trap frame pointer that it pushed on the
    420 			 * stack as the second argument to dtrace_invop() as
    421 			 * the pointer to the stack.
    422 			 */
    423 			frame = (struct trapframe *)(((uintptr_t **)&fp[1])[1]);
    424 
    425 			/*
    426 			 * Skip the three hardware-saved registers and the
    427 			 * return address.
    428 			 */
    429 			stack = (uintptr_t *)&frame->tf_esp + 1;
    430 			goto load;
    431 		}
    432 	}
    433 
    434 	/*
    435 	 * We know that we did not come through a trap to get into
    436 	 * dtrace_probe() -- the provider simply called dtrace_probe()
    437 	 * directly.  As this is the case, we need to shift the argument
    438 	 * that we're looking for:  the probe ID is the first argument to
    439 	 * dtrace_probe(), so the argument n will actually be found where
    440 	 * one would expect to find argument (n + 1).
    441 	 */
    442 	arg++;
    443 
    444 	stack = (uintptr_t *)fp + 2;
    445 
    446 load:
    447 	DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
    448 	val = stack[arg];
    449 	DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
    450 
    451 	return (val);
    452 }
    453 
    454 int
    455 dtrace_getstackdepth(int aframes)
    456 {
    457 	int depth = 0;
    458 	struct i386_frame *frame;
    459 	vm_offset_t ebp;
    460 
    461 	aframes++;
    462 	ebp = dtrace_getfp();
    463 	frame = (struct i386_frame *)ebp;
    464 	depth++;
    465 	for(;;) {
    466 		if (!INKERNEL((long) frame))
    467 			break;
    468 		if (!INKERNEL((long) frame->f_frame))
    469 			break;
    470 		depth++;
    471 		if (frame->f_frame <= frame ||
    472 		    (vm_offset_t)frame->f_frame >=
    473 		    (vm_offset_t)ebp + KSTACK_SIZE)
    474 			break;
    475 		frame = frame->f_frame;
    476 	}
    477 	if (depth < aframes)
    478 		return 0;
    479 	else
    480 		return depth - aframes;
    481 }
    482 
    483 #ifdef notyet
    484 ulong_t
    485 dtrace_getreg(struct regs *rp, uint_t reg)
    486 {
    487 #if defined(__amd64)
    488 	int regmap[] = {
    489 		REG_GS,		/* GS */
    490 		REG_FS,		/* FS */
    491 		REG_ES,		/* ES */
    492 		REG_DS,		/* DS */
    493 		REG_RDI,	/* EDI */
    494 		REG_RSI,	/* ESI */
    495 		REG_RBP,	/* EBP */
    496 		REG_RSP,	/* ESP */
    497 		REG_RBX,	/* EBX */
    498 		REG_RDX,	/* EDX */
    499 		REG_RCX,	/* ECX */
    500 		REG_RAX,	/* EAX */
    501 		REG_TRAPNO,	/* TRAPNO */
    502 		REG_ERR,	/* ERR */
    503 		REG_RIP,	/* EIP */
    504 		REG_CS,		/* CS */
    505 		REG_RFL,	/* EFL */
    506 		REG_RSP,	/* UESP */
    507 		REG_SS		/* SS */
    508 	};
    509 
    510 	if (reg <= SS) {
    511 		if (reg >= sizeof (regmap) / sizeof (int)) {
    512 			DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
    513 			return (0);
    514 		}
    515 
    516 		reg = regmap[reg];
    517 	} else {
    518 		reg -= SS + 1;
    519 	}
    520 
    521 	switch (reg) {
    522 	case REG_RDI:
    523 		return (rp->r_rdi);
    524 	case REG_RSI:
    525 		return (rp->r_rsi);
    526 	case REG_RDX:
    527 		return (rp->r_rdx);
    528 	case REG_RCX:
    529 		return (rp->r_rcx);
    530 	case REG_R8:
    531 		return (rp->r_r8);
    532 	case REG_R9:
    533 		return (rp->r_r9);
    534 	case REG_RAX:
    535 		return (rp->r_rax);
    536 	case REG_RBX:
    537 		return (rp->r_rbx);
    538 	case REG_RBP:
    539 		return (rp->r_rbp);
    540 	case REG_R10:
    541 		return (rp->r_r10);
    542 	case REG_R11:
    543 		return (rp->r_r11);
    544 	case REG_R12:
    545 		return (rp->r_r12);
    546 	case REG_R13:
    547 		return (rp->r_r13);
    548 	case REG_R14:
    549 		return (rp->r_r14);
    550 	case REG_R15:
    551 		return (rp->r_r15);
    552 	case REG_DS:
    553 		return (rp->r_ds);
    554 	case REG_ES:
    555 		return (rp->r_es);
    556 	case REG_FS:
    557 		return (rp->r_fs);
    558 	case REG_GS:
    559 		return (rp->r_gs);
    560 	case REG_TRAPNO:
    561 		return (rp->r_trapno);
    562 	case REG_ERR:
    563 		return (rp->r_err);
    564 	case REG_RIP:
    565 		return (rp->r_rip);
    566 	case REG_CS:
    567 		return (rp->r_cs);
    568 	case REG_SS:
    569 		return (rp->r_ss);
    570 	case REG_RFL:
    571 		return (rp->r_rfl);
    572 	case REG_RSP:
    573 		return (rp->r_rsp);
    574 	default:
    575 		DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
    576 		return (0);
    577 	}
    578 
    579 #else
    580 	if (reg > SS) {
    581 		DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
    582 		return (0);
    583 	}
    584 
    585 	return ((&rp->r_gs)[reg]);
    586 #endif
    587 }
    588 #endif
    589 
    590 static int
    591 dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size)
    592 {
    593 	ASSERT(kaddr >= kernelbase && kaddr + size >= kaddr);
    594 
    595 	if (uaddr + size >= kernelbase || uaddr + size < uaddr) {
    596 		DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
    597 		cpu_core[cpu_number()].cpuc_dtrace_illval = uaddr;
    598 		return (0);
    599 	}
    600 
    601 	return (1);
    602 }
    603 
    604 void
    605 dtrace_copyin(uintptr_t uaddr, uintptr_t kaddr, size_t size,
    606     volatile uint16_t *flags)
    607 {
    608 	if (dtrace_copycheck(uaddr, kaddr, size))
    609 		dtrace_copy(uaddr, kaddr, size);
    610 }
    611 
    612 void
    613 dtrace_copyout(uintptr_t kaddr, uintptr_t uaddr, size_t size,
    614     volatile uint16_t *flags)
    615 {
    616 	if (dtrace_copycheck(uaddr, kaddr, size))
    617 		dtrace_copy(kaddr, uaddr, size);
    618 }
    619 
    620 void
    621 dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
    622     volatile uint16_t *flags)
    623 {
    624 	if (dtrace_copycheck(uaddr, kaddr, size))
    625 		dtrace_copystr(uaddr, kaddr, size, flags);
    626 }
    627 
    628 void
    629 dtrace_copyoutstr(uintptr_t kaddr, uintptr_t uaddr, size_t size,
    630     volatile uint16_t *flags)
    631 {
    632 	if (dtrace_copycheck(uaddr, kaddr, size))
    633 		dtrace_copystr(kaddr, uaddr, size, flags);
    634 }
    635 
    636 uint8_t
    637 dtrace_fuword8(void *uaddr)
    638 {
    639 	if ((uintptr_t)uaddr >= kernelbase) {
    640 		DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
    641 		cpu_core[cpu_number()].cpuc_dtrace_illval = (uintptr_t)uaddr;
    642 		return (0);
    643 	}
    644 	return (dtrace_fuword8_nocheck(uaddr));
    645 }
    646 
    647 uint16_t
    648 dtrace_fuword16(void *uaddr)
    649 {
    650 	if ((uintptr_t)uaddr >= kernelbase) {
    651 		DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
    652 		cpu_core[cpu_number()].cpuc_dtrace_illval = (uintptr_t)uaddr;
    653 		return (0);
    654 	}
    655 	return (dtrace_fuword16_nocheck(uaddr));
    656 }
    657 
    658 uint32_t
    659 dtrace_fuword32(void *uaddr)
    660 {
    661 	if ((uintptr_t)uaddr >= kernelbase) {
    662 		DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
    663 		cpu_core[cpu_number()].cpuc_dtrace_illval = (uintptr_t)uaddr;
    664 		return (0);
    665 	}
    666 	return (dtrace_fuword32_nocheck(uaddr));
    667 }
    668 
    669 uint64_t
    670 dtrace_fuword64(void *uaddr)
    671 {
    672 	if ((uintptr_t)uaddr >= kernelbase) {
    673 		DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
    674 		cpu_core[cpu_number()].cpuc_dtrace_illval = (uintptr_t)uaddr;
    675 		return (0);
    676 	}
    677 	return (dtrace_fuword64_nocheck(uaddr));
    678 }
    679