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