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