1fed1ca4bSRuslan Bukin /* 2fed1ca4bSRuslan Bukin * CDDL HEADER START 3fed1ca4bSRuslan Bukin * 4fed1ca4bSRuslan Bukin * The contents of this file are subject to the terms of the 5fed1ca4bSRuslan Bukin * Common Development and Distribution License, Version 1.0 only 6fed1ca4bSRuslan Bukin * (the "License"). You may not use this file except in compliance 7fed1ca4bSRuslan Bukin * with the License. 8fed1ca4bSRuslan Bukin * 9fed1ca4bSRuslan Bukin * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10fed1ca4bSRuslan Bukin * or http://www.opensolaris.org/os/licensing. 11fed1ca4bSRuslan Bukin * See the License for the specific language governing permissions 12fed1ca4bSRuslan Bukin * and limitations under the License. 13fed1ca4bSRuslan Bukin * 14fed1ca4bSRuslan Bukin * When distributing Covered Code, include this CDDL HEADER in each 15fed1ca4bSRuslan Bukin * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16fed1ca4bSRuslan Bukin * If applicable, add the following below this CDDL HEADER, with the 17fed1ca4bSRuslan Bukin * fields enclosed by brackets "[]" replaced with your own identifying 18fed1ca4bSRuslan Bukin * information: Portions Copyright [yyyy] [name of copyright owner] 19fed1ca4bSRuslan Bukin * 20fed1ca4bSRuslan Bukin * CDDL HEADER END 21fed1ca4bSRuslan Bukin * 22fed1ca4bSRuslan Bukin * Portions Copyright 2016 Ruslan Bukin <br@bsdpad.com> 23fed1ca4bSRuslan Bukin * 24fed1ca4bSRuslan Bukin * $FreeBSD$ 25fed1ca4bSRuslan Bukin */ 26fed1ca4bSRuslan Bukin /* 27fed1ca4bSRuslan Bukin * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 28fed1ca4bSRuslan Bukin * Use is subject to license terms. 29fed1ca4bSRuslan Bukin */ 30fed1ca4bSRuslan Bukin #include <sys/cdefs.h> 31fed1ca4bSRuslan Bukin 32fed1ca4bSRuslan Bukin #include <sys/param.h> 33fed1ca4bSRuslan Bukin #include <sys/systm.h> 34fed1ca4bSRuslan Bukin #include <sys/kernel.h> 35fed1ca4bSRuslan Bukin #include <sys/stack.h> 36fed1ca4bSRuslan Bukin #include <sys/pcpu.h> 37fed1ca4bSRuslan Bukin 38fed1ca4bSRuslan Bukin #include <machine/frame.h> 39fed1ca4bSRuslan Bukin #include <machine/md_var.h> 40fed1ca4bSRuslan Bukin #include <machine/reg.h> 41fed1ca4bSRuslan Bukin 42fed1ca4bSRuslan Bukin #include <vm/vm.h> 43fed1ca4bSRuslan Bukin #include <vm/vm_param.h> 44fed1ca4bSRuslan Bukin #include <vm/pmap.h> 45fed1ca4bSRuslan Bukin 46fed1ca4bSRuslan Bukin #include <machine/atomic.h> 47fed1ca4bSRuslan Bukin #include <machine/db_machdep.h> 48fed1ca4bSRuslan Bukin #include <machine/md_var.h> 49fed1ca4bSRuslan Bukin #include <machine/stack.h> 50fed1ca4bSRuslan Bukin #include <ddb/db_sym.h> 51fed1ca4bSRuslan Bukin #include <ddb/ddb.h> 52fed1ca4bSRuslan Bukin #include <sys/kdb.h> 53fed1ca4bSRuslan Bukin 54fed1ca4bSRuslan Bukin #include "regset.h" 55fed1ca4bSRuslan Bukin 56fed1ca4bSRuslan Bukin /* 57fed1ca4bSRuslan Bukin * Wee need some reasonable default to prevent backtrace code 58fed1ca4bSRuslan Bukin * from wandering too far 59fed1ca4bSRuslan Bukin */ 60fed1ca4bSRuslan Bukin #define MAX_FUNCTION_SIZE 0x10000 61fed1ca4bSRuslan Bukin #define MAX_PROLOGUE_SIZE 0x100 62fed1ca4bSRuslan Bukin #define MAX_USTACK_DEPTH 2048 63fed1ca4bSRuslan Bukin 64fed1ca4bSRuslan Bukin uint8_t dtrace_fuword8_nocheck(void *); 65fed1ca4bSRuslan Bukin uint16_t dtrace_fuword16_nocheck(void *); 66fed1ca4bSRuslan Bukin uint32_t dtrace_fuword32_nocheck(void *); 67fed1ca4bSRuslan Bukin uint64_t dtrace_fuword64_nocheck(void *); 68fed1ca4bSRuslan Bukin 69fed1ca4bSRuslan Bukin void 70fed1ca4bSRuslan Bukin dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes, 71fed1ca4bSRuslan Bukin uint32_t *intrpc) 72fed1ca4bSRuslan Bukin { 73fed1ca4bSRuslan Bukin struct unwind_state state; 74fed1ca4bSRuslan Bukin int scp_offset; 75fed1ca4bSRuslan Bukin register_t sp; 76fed1ca4bSRuslan Bukin int depth; 77fed1ca4bSRuslan Bukin 78fed1ca4bSRuslan Bukin depth = 0; 79fed1ca4bSRuslan Bukin 80fed1ca4bSRuslan Bukin if (intrpc != 0) { 81fed1ca4bSRuslan Bukin pcstack[depth++] = (pc_t) intrpc; 82fed1ca4bSRuslan Bukin } 83fed1ca4bSRuslan Bukin 84fed1ca4bSRuslan Bukin aframes++; 85fed1ca4bSRuslan Bukin 86fed1ca4bSRuslan Bukin __asm __volatile("mv %0, sp" : "=&r" (sp)); 87fed1ca4bSRuslan Bukin 88*fdd947e4SJohn Baldwin state.fp = (uintptr_t)__builtin_frame_address(0); 89fed1ca4bSRuslan Bukin state.sp = sp; 90*fdd947e4SJohn Baldwin state.pc = (uintptr_t)dtrace_getpcstack; 91fed1ca4bSRuslan Bukin 92fed1ca4bSRuslan Bukin while (depth < pcstack_limit) { 93fed1ca4bSRuslan Bukin if (unwind_frame(&state)) 94fed1ca4bSRuslan Bukin break; 95fed1ca4bSRuslan Bukin 96fed1ca4bSRuslan Bukin if (!INKERNEL(state.pc) || !INKERNEL(state.fp)) 97fed1ca4bSRuslan Bukin break; 98fed1ca4bSRuslan Bukin 99fed1ca4bSRuslan Bukin /* 100fed1ca4bSRuslan Bukin * NB: Unlike some other architectures, we don't need to 101fed1ca4bSRuslan Bukin * explicitly insert cpu_dtrace_caller as it appears in the 102fed1ca4bSRuslan Bukin * normal kernel stack trace rather than a special trap frame. 103fed1ca4bSRuslan Bukin */ 104fed1ca4bSRuslan Bukin if (aframes > 0) { 105fed1ca4bSRuslan Bukin aframes--; 106fed1ca4bSRuslan Bukin } else { 107fed1ca4bSRuslan Bukin pcstack[depth++] = state.pc; 108fed1ca4bSRuslan Bukin } 109fed1ca4bSRuslan Bukin 110fed1ca4bSRuslan Bukin } 111fed1ca4bSRuslan Bukin 112fed1ca4bSRuslan Bukin for (; depth < pcstack_limit; depth++) { 113fed1ca4bSRuslan Bukin pcstack[depth] = 0; 114fed1ca4bSRuslan Bukin } 115fed1ca4bSRuslan Bukin } 116fed1ca4bSRuslan Bukin 117fed1ca4bSRuslan Bukin static int 118fed1ca4bSRuslan Bukin dtrace_getustack_common(uint64_t *pcstack, int pcstack_limit, uintptr_t pc, 119fed1ca4bSRuslan Bukin uintptr_t fp) 120fed1ca4bSRuslan Bukin { 121fed1ca4bSRuslan Bukin volatile uint16_t *flags; 122fed1ca4bSRuslan Bukin uintptr_t oldfp; 123fed1ca4bSRuslan Bukin int ret; 124fed1ca4bSRuslan Bukin 125fed1ca4bSRuslan Bukin ret = 0; 126fed1ca4bSRuslan Bukin flags = (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags; 127fed1ca4bSRuslan Bukin 128fed1ca4bSRuslan Bukin ASSERT(pcstack == NULL || pcstack_limit > 0); 129fed1ca4bSRuslan Bukin 130fed1ca4bSRuslan Bukin while (pc != 0) { 131fed1ca4bSRuslan Bukin /* 132fed1ca4bSRuslan Bukin * We limit the number of times we can go around this 133fed1ca4bSRuslan Bukin * loop to account for a circular stack. 134fed1ca4bSRuslan Bukin */ 135fed1ca4bSRuslan Bukin if (ret++ >= MAX_USTACK_DEPTH) { 136fed1ca4bSRuslan Bukin *flags |= CPU_DTRACE_BADSTACK; 137fed1ca4bSRuslan Bukin cpu_core[curcpu].cpuc_dtrace_illval = fp; 138fed1ca4bSRuslan Bukin break; 139fed1ca4bSRuslan Bukin } 140fed1ca4bSRuslan Bukin 141fed1ca4bSRuslan Bukin if (pcstack != NULL) { 142fed1ca4bSRuslan Bukin *pcstack++ = (uint64_t)pc; 143fed1ca4bSRuslan Bukin pcstack_limit--; 144fed1ca4bSRuslan Bukin if (pcstack_limit <= 0) 145fed1ca4bSRuslan Bukin break; 146fed1ca4bSRuslan Bukin } 147fed1ca4bSRuslan Bukin 148fed1ca4bSRuslan Bukin if (fp == 0) 149fed1ca4bSRuslan Bukin break; 150fed1ca4bSRuslan Bukin 151fed1ca4bSRuslan Bukin pc = dtrace_fuword64((void *)(fp + 152fed1ca4bSRuslan Bukin offsetof(struct riscv_frame, f_retaddr))); 153fed1ca4bSRuslan Bukin fp = dtrace_fuword64((void *)fp); 154fed1ca4bSRuslan Bukin 155fed1ca4bSRuslan Bukin if (fp == oldfp) { 156fed1ca4bSRuslan Bukin *flags |= CPU_DTRACE_BADSTACK; 157fed1ca4bSRuslan Bukin cpu_core[curcpu].cpuc_dtrace_illval = fp; 158fed1ca4bSRuslan Bukin break; 159fed1ca4bSRuslan Bukin } 160fed1ca4bSRuslan Bukin } 161fed1ca4bSRuslan Bukin 162fed1ca4bSRuslan Bukin return (ret); 163fed1ca4bSRuslan Bukin } 164fed1ca4bSRuslan Bukin 165fed1ca4bSRuslan Bukin void 166fed1ca4bSRuslan Bukin dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit) 167fed1ca4bSRuslan Bukin { 168fed1ca4bSRuslan Bukin volatile uint16_t *flags; 169fed1ca4bSRuslan Bukin struct trapframe *tf; 170fed1ca4bSRuslan Bukin uintptr_t pc, sp, fp; 171fed1ca4bSRuslan Bukin proc_t *p; 172fed1ca4bSRuslan Bukin int n; 173fed1ca4bSRuslan Bukin 174fed1ca4bSRuslan Bukin p = curproc; 175fed1ca4bSRuslan Bukin flags = (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags; 176fed1ca4bSRuslan Bukin 177fed1ca4bSRuslan Bukin if (*flags & CPU_DTRACE_FAULT) 178fed1ca4bSRuslan Bukin return; 179fed1ca4bSRuslan Bukin 180fed1ca4bSRuslan Bukin if (pcstack_limit <= 0) 181fed1ca4bSRuslan Bukin return; 182fed1ca4bSRuslan Bukin 183fed1ca4bSRuslan Bukin /* 184fed1ca4bSRuslan Bukin * If there's no user context we still need to zero the stack. 185fed1ca4bSRuslan Bukin */ 186fed1ca4bSRuslan Bukin if (p == NULL || (tf = curthread->td_frame) == NULL) 187fed1ca4bSRuslan Bukin goto zero; 188fed1ca4bSRuslan Bukin 189fed1ca4bSRuslan Bukin *pcstack++ = (uint64_t)p->p_pid; 190fed1ca4bSRuslan Bukin pcstack_limit--; 191fed1ca4bSRuslan Bukin 192fed1ca4bSRuslan Bukin if (pcstack_limit <= 0) 193fed1ca4bSRuslan Bukin return; 194fed1ca4bSRuslan Bukin 195fed1ca4bSRuslan Bukin pc = tf->tf_sepc; 196fed1ca4bSRuslan Bukin sp = tf->tf_sp; 197fed1ca4bSRuslan Bukin fp = tf->tf_s[0]; 198fed1ca4bSRuslan Bukin 199fed1ca4bSRuslan Bukin if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) { 200fed1ca4bSRuslan Bukin /* 201fed1ca4bSRuslan Bukin * In an entry probe. The frame pointer has not yet been 202fed1ca4bSRuslan Bukin * pushed (that happens in the function prologue). The 203fed1ca4bSRuslan Bukin * best approach is to add the current pc as a missing top 204fed1ca4bSRuslan Bukin * of stack and back the pc up to the caller, which is stored 205fed1ca4bSRuslan Bukin * at the current stack pointer address since the call 206fed1ca4bSRuslan Bukin * instruction puts it there right before the branch. 207fed1ca4bSRuslan Bukin */ 208fed1ca4bSRuslan Bukin 209fed1ca4bSRuslan Bukin *pcstack++ = (uint64_t)pc; 210fed1ca4bSRuslan Bukin pcstack_limit--; 211fed1ca4bSRuslan Bukin if (pcstack_limit <= 0) 212fed1ca4bSRuslan Bukin return; 213fed1ca4bSRuslan Bukin 214fed1ca4bSRuslan Bukin pc = tf->tf_ra; 215fed1ca4bSRuslan Bukin } 216fed1ca4bSRuslan Bukin 217fed1ca4bSRuslan Bukin n = dtrace_getustack_common(pcstack, pcstack_limit, pc, fp); 218fed1ca4bSRuslan Bukin ASSERT(n >= 0); 219fed1ca4bSRuslan Bukin ASSERT(n <= pcstack_limit); 220fed1ca4bSRuslan Bukin 221fed1ca4bSRuslan Bukin pcstack += n; 222fed1ca4bSRuslan Bukin pcstack_limit -= n; 223fed1ca4bSRuslan Bukin 224fed1ca4bSRuslan Bukin zero: 225fed1ca4bSRuslan Bukin while (pcstack_limit-- > 0) 226fed1ca4bSRuslan Bukin *pcstack++ = 0; 227fed1ca4bSRuslan Bukin } 228fed1ca4bSRuslan Bukin 229fed1ca4bSRuslan Bukin int 230fed1ca4bSRuslan Bukin dtrace_getustackdepth(void) 231fed1ca4bSRuslan Bukin { 232fed1ca4bSRuslan Bukin 233fed1ca4bSRuslan Bukin printf("IMPLEMENT ME: %s\n", __func__); 234fed1ca4bSRuslan Bukin 235fed1ca4bSRuslan Bukin return (0); 236fed1ca4bSRuslan Bukin } 237fed1ca4bSRuslan Bukin 238fed1ca4bSRuslan Bukin void 239fed1ca4bSRuslan Bukin dtrace_getufpstack(uint64_t *pcstack, uint64_t *fpstack, int pcstack_limit) 240fed1ca4bSRuslan Bukin { 241fed1ca4bSRuslan Bukin 242fed1ca4bSRuslan Bukin printf("IMPLEMENT ME: %s\n", __func__); 243fed1ca4bSRuslan Bukin } 244fed1ca4bSRuslan Bukin 245fed1ca4bSRuslan Bukin /*ARGSUSED*/ 246fed1ca4bSRuslan Bukin uint64_t 247fed1ca4bSRuslan Bukin dtrace_getarg(int arg, int aframes) 248fed1ca4bSRuslan Bukin { 249fed1ca4bSRuslan Bukin 250fed1ca4bSRuslan Bukin printf("IMPLEMENT ME: %s\n", __func__); 251fed1ca4bSRuslan Bukin 252fed1ca4bSRuslan Bukin return (0); 253fed1ca4bSRuslan Bukin } 254fed1ca4bSRuslan Bukin 255fed1ca4bSRuslan Bukin int 256fed1ca4bSRuslan Bukin dtrace_getstackdepth(int aframes) 257fed1ca4bSRuslan Bukin { 258fed1ca4bSRuslan Bukin struct unwind_state state; 259fed1ca4bSRuslan Bukin int scp_offset; 260fed1ca4bSRuslan Bukin register_t sp; 261fed1ca4bSRuslan Bukin int depth; 262fed1ca4bSRuslan Bukin int done; 263fed1ca4bSRuslan Bukin 264fed1ca4bSRuslan Bukin depth = 1; 265fed1ca4bSRuslan Bukin done = 0; 266fed1ca4bSRuslan Bukin 267fed1ca4bSRuslan Bukin __asm __volatile("mv %0, sp" : "=&r" (sp)); 268fed1ca4bSRuslan Bukin 269*fdd947e4SJohn Baldwin state.fp = (uintptr_t)__builtin_frame_address(0); 270fed1ca4bSRuslan Bukin state.sp = sp; 271*fdd947e4SJohn Baldwin state.pc = (uintptr_t)dtrace_getstackdepth; 272fed1ca4bSRuslan Bukin 273fed1ca4bSRuslan Bukin do { 274fed1ca4bSRuslan Bukin done = unwind_frame(&state); 275fed1ca4bSRuslan Bukin if (!INKERNEL(state.pc) || !INKERNEL(state.fp)) 276fed1ca4bSRuslan Bukin break; 277fed1ca4bSRuslan Bukin depth++; 278fed1ca4bSRuslan Bukin } while (!done); 279fed1ca4bSRuslan Bukin 280fed1ca4bSRuslan Bukin if (depth < aframes) 281fed1ca4bSRuslan Bukin return (0); 282fed1ca4bSRuslan Bukin else 283fed1ca4bSRuslan Bukin return (depth - aframes); 284fed1ca4bSRuslan Bukin } 285fed1ca4bSRuslan Bukin 286fed1ca4bSRuslan Bukin ulong_t 287fed1ca4bSRuslan Bukin dtrace_getreg(struct trapframe *rp, uint_t reg) 288fed1ca4bSRuslan Bukin { 289fed1ca4bSRuslan Bukin 290fed1ca4bSRuslan Bukin printf("IMPLEMENT ME: %s\n", __func__); 291fed1ca4bSRuslan Bukin 292fed1ca4bSRuslan Bukin return (0); 293fed1ca4bSRuslan Bukin } 294fed1ca4bSRuslan Bukin 295fed1ca4bSRuslan Bukin static int 296fed1ca4bSRuslan Bukin dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size) 297fed1ca4bSRuslan Bukin { 298fed1ca4bSRuslan Bukin 299fed1ca4bSRuslan Bukin if (uaddr + size > VM_MAXUSER_ADDRESS || uaddr + size < uaddr) { 300fed1ca4bSRuslan Bukin DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 301fed1ca4bSRuslan Bukin cpu_core[curcpu].cpuc_dtrace_illval = uaddr; 302fed1ca4bSRuslan Bukin return (0); 303fed1ca4bSRuslan Bukin } 304fed1ca4bSRuslan Bukin 305fed1ca4bSRuslan Bukin return (1); 306fed1ca4bSRuslan Bukin } 307fed1ca4bSRuslan Bukin 308fed1ca4bSRuslan Bukin void 309fed1ca4bSRuslan Bukin dtrace_copyin(uintptr_t uaddr, uintptr_t kaddr, size_t size, 310fed1ca4bSRuslan Bukin volatile uint16_t *flags) 311fed1ca4bSRuslan Bukin { 312fed1ca4bSRuslan Bukin 313fed1ca4bSRuslan Bukin if (dtrace_copycheck(uaddr, kaddr, size)) 314fed1ca4bSRuslan Bukin dtrace_copy(uaddr, kaddr, size); 315fed1ca4bSRuslan Bukin } 316fed1ca4bSRuslan Bukin 317fed1ca4bSRuslan Bukin void 318fed1ca4bSRuslan Bukin dtrace_copyout(uintptr_t kaddr, uintptr_t uaddr, size_t size, 319fed1ca4bSRuslan Bukin volatile uint16_t *flags) 320fed1ca4bSRuslan Bukin { 321fed1ca4bSRuslan Bukin 322fed1ca4bSRuslan Bukin if (dtrace_copycheck(uaddr, kaddr, size)) 323fed1ca4bSRuslan Bukin dtrace_copy(kaddr, uaddr, size); 324fed1ca4bSRuslan Bukin } 325fed1ca4bSRuslan Bukin 326fed1ca4bSRuslan Bukin void 327fed1ca4bSRuslan Bukin dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size, 328fed1ca4bSRuslan Bukin volatile uint16_t *flags) 329fed1ca4bSRuslan Bukin { 330fed1ca4bSRuslan Bukin 331fed1ca4bSRuslan Bukin if (dtrace_copycheck(uaddr, kaddr, size)) 332fed1ca4bSRuslan Bukin dtrace_copystr(uaddr, kaddr, size, flags); 333fed1ca4bSRuslan Bukin } 334fed1ca4bSRuslan Bukin 335fed1ca4bSRuslan Bukin void 336fed1ca4bSRuslan Bukin dtrace_copyoutstr(uintptr_t kaddr, uintptr_t uaddr, size_t size, 337fed1ca4bSRuslan Bukin volatile uint16_t *flags) 338fed1ca4bSRuslan Bukin { 339fed1ca4bSRuslan Bukin 340fed1ca4bSRuslan Bukin if (dtrace_copycheck(uaddr, kaddr, size)) 341fed1ca4bSRuslan Bukin dtrace_copystr(kaddr, uaddr, size, flags); 342fed1ca4bSRuslan Bukin } 343fed1ca4bSRuslan Bukin 344fed1ca4bSRuslan Bukin uint8_t 345fed1ca4bSRuslan Bukin dtrace_fuword8(void *uaddr) 346fed1ca4bSRuslan Bukin { 347fed1ca4bSRuslan Bukin 348fed1ca4bSRuslan Bukin if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { 349fed1ca4bSRuslan Bukin DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 350fed1ca4bSRuslan Bukin cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 351fed1ca4bSRuslan Bukin return (0); 352fed1ca4bSRuslan Bukin } 353fed1ca4bSRuslan Bukin 354fed1ca4bSRuslan Bukin return (dtrace_fuword8_nocheck(uaddr)); 355fed1ca4bSRuslan Bukin } 356fed1ca4bSRuslan Bukin 357fed1ca4bSRuslan Bukin uint16_t 358fed1ca4bSRuslan Bukin dtrace_fuword16(void *uaddr) 359fed1ca4bSRuslan Bukin { 360fed1ca4bSRuslan Bukin 361fed1ca4bSRuslan Bukin if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { 362fed1ca4bSRuslan Bukin DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 363fed1ca4bSRuslan Bukin cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 364fed1ca4bSRuslan Bukin return (0); 365fed1ca4bSRuslan Bukin } 366fed1ca4bSRuslan Bukin 367fed1ca4bSRuslan Bukin return (dtrace_fuword16_nocheck(uaddr)); 368fed1ca4bSRuslan Bukin } 369fed1ca4bSRuslan Bukin 370fed1ca4bSRuslan Bukin uint32_t 371fed1ca4bSRuslan Bukin dtrace_fuword32(void *uaddr) 372fed1ca4bSRuslan Bukin { 373fed1ca4bSRuslan Bukin 374fed1ca4bSRuslan Bukin if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { 375fed1ca4bSRuslan Bukin DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 376fed1ca4bSRuslan Bukin cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 377fed1ca4bSRuslan Bukin return (0); 378fed1ca4bSRuslan Bukin } 379fed1ca4bSRuslan Bukin 380fed1ca4bSRuslan Bukin return (dtrace_fuword32_nocheck(uaddr)); 381fed1ca4bSRuslan Bukin } 382fed1ca4bSRuslan Bukin 383fed1ca4bSRuslan Bukin uint64_t 384fed1ca4bSRuslan Bukin dtrace_fuword64(void *uaddr) 385fed1ca4bSRuslan Bukin { 386fed1ca4bSRuslan Bukin 387fed1ca4bSRuslan Bukin if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { 388fed1ca4bSRuslan Bukin DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 389fed1ca4bSRuslan Bukin cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 390fed1ca4bSRuslan Bukin return (0); 391fed1ca4bSRuslan Bukin } 392fed1ca4bSRuslan Bukin 393fed1ca4bSRuslan Bukin return (dtrace_fuword64_nocheck(uaddr)); 394fed1ca4bSRuslan Bukin } 395