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 41fed1ca4bSRuslan Bukin #include <vm/vm.h> 42fed1ca4bSRuslan Bukin #include <vm/vm_param.h> 43fed1ca4bSRuslan Bukin #include <vm/pmap.h> 44fed1ca4bSRuslan Bukin 45fed1ca4bSRuslan Bukin #include <machine/atomic.h> 46fed1ca4bSRuslan Bukin #include <machine/db_machdep.h> 47fed1ca4bSRuslan Bukin #include <machine/md_var.h> 48fed1ca4bSRuslan Bukin #include <machine/stack.h> 49fed1ca4bSRuslan Bukin #include <ddb/db_sym.h> 50fed1ca4bSRuslan Bukin #include <ddb/ddb.h> 51fed1ca4bSRuslan Bukin #include <sys/kdb.h> 52fed1ca4bSRuslan Bukin 53fed1ca4bSRuslan Bukin #include "regset.h" 54fed1ca4bSRuslan Bukin 55fed1ca4bSRuslan Bukin #define MAX_USTACK_DEPTH 2048 56fed1ca4bSRuslan Bukin 57fed1ca4bSRuslan Bukin uint8_t dtrace_fuword8_nocheck(void *); 58fed1ca4bSRuslan Bukin uint16_t dtrace_fuword16_nocheck(void *); 59fed1ca4bSRuslan Bukin uint32_t dtrace_fuword32_nocheck(void *); 60fed1ca4bSRuslan Bukin uint64_t dtrace_fuword64_nocheck(void *); 61fed1ca4bSRuslan Bukin 62fed1ca4bSRuslan Bukin void 63fed1ca4bSRuslan Bukin dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes, 64fed1ca4bSRuslan Bukin uint32_t *intrpc) 65fed1ca4bSRuslan Bukin { 66fed1ca4bSRuslan Bukin struct unwind_state state; 67*cdfa49f2SMitchell Horne uintptr_t caller; 68fed1ca4bSRuslan Bukin register_t sp; 69*cdfa49f2SMitchell Horne int scp_offset; 70fed1ca4bSRuslan Bukin int depth; 71fed1ca4bSRuslan Bukin 72fed1ca4bSRuslan Bukin depth = 0; 73*cdfa49f2SMitchell Horne caller = solaris_cpu[curcpu].cpu_dtrace_caller; 74fed1ca4bSRuslan Bukin 75fed1ca4bSRuslan Bukin if (intrpc != 0) { 76fed1ca4bSRuslan Bukin pcstack[depth++] = (pc_t)intrpc; 77fed1ca4bSRuslan Bukin } 78fed1ca4bSRuslan Bukin 79*cdfa49f2SMitchell Horne /* 80*cdfa49f2SMitchell Horne * Construct the unwind state, starting from this function. This frame, 81*cdfa49f2SMitchell Horne * and 'aframes' others will be skipped. 82*cdfa49f2SMitchell Horne */ 83fed1ca4bSRuslan Bukin __asm __volatile("mv %0, sp" : "=&r" (sp)); 84fed1ca4bSRuslan Bukin 85fdd947e4SJohn Baldwin state.fp = (uintptr_t)__builtin_frame_address(0); 86*cdfa49f2SMitchell Horne state.sp = (uintptr_t)sp; 87fdd947e4SJohn Baldwin state.pc = (uintptr_t)dtrace_getpcstack; 88fed1ca4bSRuslan Bukin 89fed1ca4bSRuslan Bukin while (depth < pcstack_limit) { 909b9e7f4cSJohn Baldwin if (!unwind_frame(curthread, &state)) 91fed1ca4bSRuslan Bukin break; 92fed1ca4bSRuslan Bukin 93*cdfa49f2SMitchell Horne if (!INKERNEL(state.pc) || !kstack_contains(curthread, 94*cdfa49f2SMitchell Horne (vm_offset_t)state.fp, sizeof(uintptr_t))) 95fed1ca4bSRuslan Bukin break; 96fed1ca4bSRuslan Bukin 97fed1ca4bSRuslan Bukin if (aframes > 0) { 98fed1ca4bSRuslan Bukin aframes--; 99*cdfa49f2SMitchell Horne 100*cdfa49f2SMitchell Horne /* 101*cdfa49f2SMitchell Horne * fbt_invop() records the return address at the time 102*cdfa49f2SMitchell Horne * the FBT probe fires. We need to insert this into the 103*cdfa49f2SMitchell Horne * backtrace manually, since the stack frame state at 104*cdfa49f2SMitchell Horne * the time of the probe does not capture it. 105*cdfa49f2SMitchell Horne */ 106*cdfa49f2SMitchell Horne if (aframes == 0 && caller != 0) 107*cdfa49f2SMitchell Horne pcstack[depth++] = caller; 108fed1ca4bSRuslan Bukin } else { 109fed1ca4bSRuslan Bukin pcstack[depth++] = state.pc; 110fed1ca4bSRuslan Bukin } 111fed1ca4bSRuslan Bukin } 112fed1ca4bSRuslan Bukin 113fed1ca4bSRuslan Bukin for (; depth < pcstack_limit; depth++) { 114fed1ca4bSRuslan Bukin pcstack[depth] = 0; 115fed1ca4bSRuslan Bukin } 116fed1ca4bSRuslan Bukin } 117fed1ca4bSRuslan Bukin 118fed1ca4bSRuslan Bukin static int 119fed1ca4bSRuslan Bukin dtrace_getustack_common(uint64_t *pcstack, int pcstack_limit, uintptr_t pc, 120fed1ca4bSRuslan Bukin uintptr_t fp) 121fed1ca4bSRuslan Bukin { 122fed1ca4bSRuslan Bukin volatile uint16_t *flags; 123fed1ca4bSRuslan Bukin uintptr_t oldfp; 124fed1ca4bSRuslan Bukin int ret; 125fed1ca4bSRuslan Bukin 1260b92d1ddSMitchell Horne oldfp = fp; 127fed1ca4bSRuslan Bukin ret = 0; 128fed1ca4bSRuslan Bukin flags = (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags; 129fed1ca4bSRuslan Bukin 130fed1ca4bSRuslan Bukin ASSERT(pcstack == NULL || pcstack_limit > 0); 131fed1ca4bSRuslan Bukin 132fed1ca4bSRuslan Bukin while (pc != 0) { 133fed1ca4bSRuslan Bukin /* 134fed1ca4bSRuslan Bukin * We limit the number of times we can go around this 135fed1ca4bSRuslan Bukin * loop to account for a circular stack. 136fed1ca4bSRuslan Bukin */ 137fed1ca4bSRuslan Bukin if (ret++ >= MAX_USTACK_DEPTH) { 138fed1ca4bSRuslan Bukin *flags |= CPU_DTRACE_BADSTACK; 139fed1ca4bSRuslan Bukin cpu_core[curcpu].cpuc_dtrace_illval = fp; 140fed1ca4bSRuslan Bukin break; 141fed1ca4bSRuslan Bukin } 142fed1ca4bSRuslan Bukin 143fed1ca4bSRuslan Bukin if (pcstack != NULL) { 144fed1ca4bSRuslan Bukin *pcstack++ = (uint64_t)pc; 145fed1ca4bSRuslan Bukin pcstack_limit--; 146fed1ca4bSRuslan Bukin if (pcstack_limit <= 0) 147fed1ca4bSRuslan Bukin break; 148fed1ca4bSRuslan Bukin } 149fed1ca4bSRuslan Bukin 150fed1ca4bSRuslan Bukin if (fp == 0) 151fed1ca4bSRuslan Bukin break; 152fed1ca4bSRuslan Bukin 153fed1ca4bSRuslan Bukin pc = dtrace_fuword64((void *)(fp + 154fed1ca4bSRuslan Bukin offsetof(struct riscv_frame, f_retaddr))); 155fed1ca4bSRuslan Bukin fp = dtrace_fuword64((void *)fp); 156fed1ca4bSRuslan Bukin 157fed1ca4bSRuslan Bukin if (fp == oldfp) { 158fed1ca4bSRuslan Bukin *flags |= CPU_DTRACE_BADSTACK; 159fed1ca4bSRuslan Bukin cpu_core[curcpu].cpuc_dtrace_illval = fp; 160fed1ca4bSRuslan Bukin break; 161fed1ca4bSRuslan Bukin } 1620b92d1ddSMitchell Horne oldfp = fp; 163fed1ca4bSRuslan Bukin } 164fed1ca4bSRuslan Bukin 165fed1ca4bSRuslan Bukin return (ret); 166fed1ca4bSRuslan Bukin } 167fed1ca4bSRuslan Bukin 168fed1ca4bSRuslan Bukin void 169fed1ca4bSRuslan Bukin dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit) 170fed1ca4bSRuslan Bukin { 171fed1ca4bSRuslan Bukin volatile uint16_t *flags; 172fed1ca4bSRuslan Bukin struct trapframe *tf; 173fed1ca4bSRuslan Bukin uintptr_t pc, sp, fp; 174fed1ca4bSRuslan Bukin proc_t *p; 175fed1ca4bSRuslan Bukin int n; 176fed1ca4bSRuslan Bukin 177fed1ca4bSRuslan Bukin p = curproc; 178fed1ca4bSRuslan Bukin flags = (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags; 179fed1ca4bSRuslan Bukin 180fed1ca4bSRuslan Bukin if (*flags & CPU_DTRACE_FAULT) 181fed1ca4bSRuslan Bukin return; 182fed1ca4bSRuslan Bukin 183fed1ca4bSRuslan Bukin if (pcstack_limit <= 0) 184fed1ca4bSRuslan Bukin return; 185fed1ca4bSRuslan Bukin 186fed1ca4bSRuslan Bukin /* 187fed1ca4bSRuslan Bukin * If there's no user context we still need to zero the stack. 188fed1ca4bSRuslan Bukin */ 189fed1ca4bSRuslan Bukin if (p == NULL || (tf = curthread->td_frame) == NULL) 190fed1ca4bSRuslan Bukin goto zero; 191fed1ca4bSRuslan Bukin 192fed1ca4bSRuslan Bukin *pcstack++ = (uint64_t)p->p_pid; 193fed1ca4bSRuslan Bukin pcstack_limit--; 194fed1ca4bSRuslan Bukin 195fed1ca4bSRuslan Bukin if (pcstack_limit <= 0) 196fed1ca4bSRuslan Bukin return; 197fed1ca4bSRuslan Bukin 198fed1ca4bSRuslan Bukin pc = tf->tf_sepc; 199fed1ca4bSRuslan Bukin sp = tf->tf_sp; 200fed1ca4bSRuslan Bukin fp = tf->tf_s[0]; 201fed1ca4bSRuslan Bukin 202fed1ca4bSRuslan Bukin if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) { 203fed1ca4bSRuslan Bukin /* 204fed1ca4bSRuslan Bukin * In an entry probe. The frame pointer has not yet been 205fed1ca4bSRuslan Bukin * pushed (that happens in the function prologue). The 206fed1ca4bSRuslan Bukin * best approach is to add the current pc as a missing top 207fed1ca4bSRuslan Bukin * of stack and back the pc up to the caller, which is stored 208fed1ca4bSRuslan Bukin * at the current stack pointer address since the call 209fed1ca4bSRuslan Bukin * instruction puts it there right before the branch. 210fed1ca4bSRuslan Bukin */ 211fed1ca4bSRuslan Bukin 212fed1ca4bSRuslan Bukin *pcstack++ = (uint64_t)pc; 213fed1ca4bSRuslan Bukin pcstack_limit--; 214fed1ca4bSRuslan Bukin if (pcstack_limit <= 0) 215fed1ca4bSRuslan Bukin return; 216fed1ca4bSRuslan Bukin 217fed1ca4bSRuslan Bukin pc = tf->tf_ra; 218fed1ca4bSRuslan Bukin } 219fed1ca4bSRuslan Bukin 220fed1ca4bSRuslan Bukin n = dtrace_getustack_common(pcstack, pcstack_limit, pc, fp); 221fed1ca4bSRuslan Bukin ASSERT(n >= 0); 222fed1ca4bSRuslan Bukin ASSERT(n <= pcstack_limit); 223fed1ca4bSRuslan Bukin 224fed1ca4bSRuslan Bukin pcstack += n; 225fed1ca4bSRuslan Bukin pcstack_limit -= n; 226fed1ca4bSRuslan Bukin 227fed1ca4bSRuslan Bukin zero: 228fed1ca4bSRuslan Bukin while (pcstack_limit-- > 0) 229fed1ca4bSRuslan Bukin *pcstack++ = 0; 230fed1ca4bSRuslan Bukin } 231fed1ca4bSRuslan Bukin 232fed1ca4bSRuslan Bukin int 233fed1ca4bSRuslan Bukin dtrace_getustackdepth(void) 234fed1ca4bSRuslan Bukin { 235fed1ca4bSRuslan Bukin 236fed1ca4bSRuslan Bukin printf("IMPLEMENT ME: %s\n", __func__); 237fed1ca4bSRuslan Bukin 238fed1ca4bSRuslan Bukin return (0); 239fed1ca4bSRuslan Bukin } 240fed1ca4bSRuslan Bukin 241fed1ca4bSRuslan Bukin void 242fed1ca4bSRuslan Bukin dtrace_getufpstack(uint64_t *pcstack, uint64_t *fpstack, int pcstack_limit) 243fed1ca4bSRuslan Bukin { 244fed1ca4bSRuslan Bukin 245fed1ca4bSRuslan Bukin printf("IMPLEMENT ME: %s\n", __func__); 246fed1ca4bSRuslan Bukin } 247fed1ca4bSRuslan Bukin 248fed1ca4bSRuslan Bukin /*ARGSUSED*/ 249fed1ca4bSRuslan Bukin uint64_t 250fed1ca4bSRuslan Bukin dtrace_getarg(int arg, int aframes) 251fed1ca4bSRuslan Bukin { 252fed1ca4bSRuslan Bukin 253fed1ca4bSRuslan Bukin printf("IMPLEMENT ME: %s\n", __func__); 254fed1ca4bSRuslan Bukin 255fed1ca4bSRuslan Bukin return (0); 256fed1ca4bSRuslan Bukin } 257fed1ca4bSRuslan Bukin 258fed1ca4bSRuslan Bukin int 259fed1ca4bSRuslan Bukin dtrace_getstackdepth(int aframes) 260fed1ca4bSRuslan Bukin { 261fed1ca4bSRuslan Bukin struct unwind_state state; 262fed1ca4bSRuslan Bukin int scp_offset; 263fed1ca4bSRuslan Bukin register_t sp; 264fed1ca4bSRuslan Bukin int depth; 2659b9e7f4cSJohn Baldwin bool done; 266fed1ca4bSRuslan Bukin 267fed1ca4bSRuslan Bukin depth = 1; 2689b9e7f4cSJohn Baldwin done = false; 269fed1ca4bSRuslan Bukin 270fed1ca4bSRuslan Bukin __asm __volatile("mv %0, sp" : "=&r" (sp)); 271fed1ca4bSRuslan Bukin 272fdd947e4SJohn Baldwin state.fp = (uintptr_t)__builtin_frame_address(0); 273fed1ca4bSRuslan Bukin state.sp = sp; 274fdd947e4SJohn Baldwin state.pc = (uintptr_t)dtrace_getstackdepth; 275fed1ca4bSRuslan Bukin 276fed1ca4bSRuslan Bukin do { 2779b9e7f4cSJohn Baldwin done = !unwind_frame(curthread, &state); 278fed1ca4bSRuslan Bukin if (!INKERNEL(state.pc) || !INKERNEL(state.fp)) 279fed1ca4bSRuslan Bukin break; 280fed1ca4bSRuslan Bukin depth++; 281fed1ca4bSRuslan Bukin } while (!done); 282fed1ca4bSRuslan Bukin 283fed1ca4bSRuslan Bukin if (depth < aframes) 284fed1ca4bSRuslan Bukin return (0); 285fed1ca4bSRuslan Bukin else 286fed1ca4bSRuslan Bukin return (depth - aframes); 287fed1ca4bSRuslan Bukin } 288fed1ca4bSRuslan Bukin 289fed1ca4bSRuslan Bukin ulong_t 290fed1ca4bSRuslan Bukin dtrace_getreg(struct trapframe *rp, uint_t reg) 291fed1ca4bSRuslan Bukin { 292fed1ca4bSRuslan Bukin 293fed1ca4bSRuslan Bukin printf("IMPLEMENT ME: %s\n", __func__); 294fed1ca4bSRuslan Bukin 295fed1ca4bSRuslan Bukin return (0); 296fed1ca4bSRuslan Bukin } 297fed1ca4bSRuslan Bukin 298fed1ca4bSRuslan Bukin static int 299fed1ca4bSRuslan Bukin dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size) 300fed1ca4bSRuslan Bukin { 301fed1ca4bSRuslan Bukin 302fed1ca4bSRuslan Bukin if (uaddr + size > VM_MAXUSER_ADDRESS || uaddr + size < uaddr) { 303fed1ca4bSRuslan Bukin DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 304fed1ca4bSRuslan Bukin cpu_core[curcpu].cpuc_dtrace_illval = uaddr; 305fed1ca4bSRuslan Bukin return (0); 306fed1ca4bSRuslan Bukin } 307fed1ca4bSRuslan Bukin 308fed1ca4bSRuslan Bukin return (1); 309fed1ca4bSRuslan Bukin } 310fed1ca4bSRuslan Bukin 311fed1ca4bSRuslan Bukin void 312fed1ca4bSRuslan Bukin dtrace_copyin(uintptr_t uaddr, uintptr_t kaddr, size_t size, 313fed1ca4bSRuslan Bukin volatile uint16_t *flags) 314fed1ca4bSRuslan Bukin { 315fed1ca4bSRuslan Bukin 316fed1ca4bSRuslan Bukin if (dtrace_copycheck(uaddr, kaddr, size)) 317fed1ca4bSRuslan Bukin dtrace_copy(uaddr, kaddr, size); 318fed1ca4bSRuslan Bukin } 319fed1ca4bSRuslan Bukin 320fed1ca4bSRuslan Bukin void 321fed1ca4bSRuslan Bukin dtrace_copyout(uintptr_t kaddr, uintptr_t uaddr, size_t size, 322fed1ca4bSRuslan Bukin volatile uint16_t *flags) 323fed1ca4bSRuslan Bukin { 324fed1ca4bSRuslan Bukin 325fed1ca4bSRuslan Bukin if (dtrace_copycheck(uaddr, kaddr, size)) 326fed1ca4bSRuslan Bukin dtrace_copy(kaddr, uaddr, size); 327fed1ca4bSRuslan Bukin } 328fed1ca4bSRuslan Bukin 329fed1ca4bSRuslan Bukin void 330fed1ca4bSRuslan Bukin dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size, 331fed1ca4bSRuslan Bukin volatile uint16_t *flags) 332fed1ca4bSRuslan Bukin { 333fed1ca4bSRuslan Bukin 334fed1ca4bSRuslan Bukin if (dtrace_copycheck(uaddr, kaddr, size)) 335fed1ca4bSRuslan Bukin dtrace_copystr(uaddr, kaddr, size, flags); 336fed1ca4bSRuslan Bukin } 337fed1ca4bSRuslan Bukin 338fed1ca4bSRuslan Bukin void 339fed1ca4bSRuslan Bukin dtrace_copyoutstr(uintptr_t kaddr, uintptr_t uaddr, size_t size, 340fed1ca4bSRuslan Bukin volatile uint16_t *flags) 341fed1ca4bSRuslan Bukin { 342fed1ca4bSRuslan Bukin 343fed1ca4bSRuslan Bukin if (dtrace_copycheck(uaddr, kaddr, size)) 344fed1ca4bSRuslan Bukin dtrace_copystr(kaddr, uaddr, size, flags); 345fed1ca4bSRuslan Bukin } 346fed1ca4bSRuslan Bukin 347fed1ca4bSRuslan Bukin uint8_t 348fed1ca4bSRuslan Bukin dtrace_fuword8(void *uaddr) 349fed1ca4bSRuslan Bukin { 350fed1ca4bSRuslan Bukin 351fed1ca4bSRuslan Bukin if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { 352fed1ca4bSRuslan Bukin DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 353fed1ca4bSRuslan Bukin cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 354fed1ca4bSRuslan Bukin return (0); 355fed1ca4bSRuslan Bukin } 356fed1ca4bSRuslan Bukin 357fed1ca4bSRuslan Bukin return (dtrace_fuword8_nocheck(uaddr)); 358fed1ca4bSRuslan Bukin } 359fed1ca4bSRuslan Bukin 360fed1ca4bSRuslan Bukin uint16_t 361fed1ca4bSRuslan Bukin dtrace_fuword16(void *uaddr) 362fed1ca4bSRuslan Bukin { 363fed1ca4bSRuslan Bukin 364fed1ca4bSRuslan Bukin if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { 365fed1ca4bSRuslan Bukin DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 366fed1ca4bSRuslan Bukin cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 367fed1ca4bSRuslan Bukin return (0); 368fed1ca4bSRuslan Bukin } 369fed1ca4bSRuslan Bukin 370fed1ca4bSRuslan Bukin return (dtrace_fuword16_nocheck(uaddr)); 371fed1ca4bSRuslan Bukin } 372fed1ca4bSRuslan Bukin 373fed1ca4bSRuslan Bukin uint32_t 374fed1ca4bSRuslan Bukin dtrace_fuword32(void *uaddr) 375fed1ca4bSRuslan Bukin { 376fed1ca4bSRuslan Bukin 377fed1ca4bSRuslan Bukin if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { 378fed1ca4bSRuslan Bukin DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 379fed1ca4bSRuslan Bukin cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 380fed1ca4bSRuslan Bukin return (0); 381fed1ca4bSRuslan Bukin } 382fed1ca4bSRuslan Bukin 383fed1ca4bSRuslan Bukin return (dtrace_fuword32_nocheck(uaddr)); 384fed1ca4bSRuslan Bukin } 385fed1ca4bSRuslan Bukin 386fed1ca4bSRuslan Bukin uint64_t 387fed1ca4bSRuslan Bukin dtrace_fuword64(void *uaddr) 388fed1ca4bSRuslan Bukin { 389fed1ca4bSRuslan Bukin 390fed1ca4bSRuslan Bukin if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { 391fed1ca4bSRuslan Bukin DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 392fed1ca4bSRuslan Bukin cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 393fed1ca4bSRuslan Bukin return (0); 394fed1ca4bSRuslan Bukin } 395fed1ca4bSRuslan Bukin 396fed1ca4bSRuslan Bukin return (dtrace_fuword64_nocheck(uaddr)); 397fed1ca4bSRuslan Bukin } 398