1b78ee15eSRuslan Bukin /* 2b78ee15eSRuslan Bukin * CDDL HEADER START 3b78ee15eSRuslan Bukin * 4b78ee15eSRuslan Bukin * The contents of this file are subject to the terms of the 5b78ee15eSRuslan Bukin * Common Development and Distribution License, Version 1.0 only 6b78ee15eSRuslan Bukin * (the "License"). You may not use this file except in compliance 7b78ee15eSRuslan Bukin * with the License. 8b78ee15eSRuslan Bukin * 9b78ee15eSRuslan Bukin * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10b78ee15eSRuslan Bukin * or http://www.opensolaris.org/os/licensing. 11b78ee15eSRuslan Bukin * See the License for the specific language governing permissions 12b78ee15eSRuslan Bukin * and limitations under the License. 13b78ee15eSRuslan Bukin * 14b78ee15eSRuslan Bukin * When distributing Covered Code, include this CDDL HEADER in each 15b78ee15eSRuslan Bukin * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16b78ee15eSRuslan Bukin * If applicable, add the following below this CDDL HEADER, with the 17b78ee15eSRuslan Bukin * fields enclosed by brackets "[]" replaced with your own identifying 18b78ee15eSRuslan Bukin * information: Portions Copyright [yyyy] [name of copyright owner] 19b78ee15eSRuslan Bukin * 20b78ee15eSRuslan Bukin * CDDL HEADER END 21b78ee15eSRuslan Bukin */ 22b78ee15eSRuslan Bukin /* 23b78ee15eSRuslan Bukin * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24b78ee15eSRuslan Bukin * Use is subject to license terms. 25b78ee15eSRuslan Bukin */ 26b78ee15eSRuslan Bukin #include <sys/cdefs.h> 27b78ee15eSRuslan Bukin 28b78ee15eSRuslan Bukin #include <sys/param.h> 29b78ee15eSRuslan Bukin #include <sys/systm.h> 30b78ee15eSRuslan Bukin #include <sys/kernel.h> 31b78ee15eSRuslan Bukin #include <sys/stack.h> 32b78ee15eSRuslan Bukin #include <sys/pcpu.h> 33b78ee15eSRuslan Bukin 34b78ee15eSRuslan Bukin #include <machine/frame.h> 35b78ee15eSRuslan Bukin #include <machine/md_var.h> 36b78ee15eSRuslan Bukin 37b78ee15eSRuslan Bukin #include <vm/vm.h> 38b78ee15eSRuslan Bukin #include <vm/vm_param.h> 39b78ee15eSRuslan Bukin #include <vm/pmap.h> 40b78ee15eSRuslan Bukin 41b78ee15eSRuslan Bukin #include <machine/atomic.h> 42b78ee15eSRuslan Bukin #include <machine/db_machdep.h> 43b78ee15eSRuslan Bukin #include <machine/md_var.h> 44b78ee15eSRuslan Bukin #include <machine/stack.h> 45b78ee15eSRuslan Bukin #include <ddb/db_sym.h> 46b78ee15eSRuslan Bukin #include <ddb/ddb.h> 47b78ee15eSRuslan Bukin #include <sys/kdb.h> 48b78ee15eSRuslan Bukin 49b78ee15eSRuslan Bukin #include "regset.h" 50b78ee15eSRuslan Bukin 511c7c13aaSWojciech Macek #define MAX_USTACK_DEPTH 2048 52b78ee15eSRuslan Bukin 53b78ee15eSRuslan Bukin uint8_t dtrace_fuword8_nocheck(void *); 54b78ee15eSRuslan Bukin uint16_t dtrace_fuword16_nocheck(void *); 55b78ee15eSRuslan Bukin uint32_t dtrace_fuword32_nocheck(void *); 56b78ee15eSRuslan Bukin uint64_t dtrace_fuword64_nocheck(void *); 57b78ee15eSRuslan Bukin 58b78ee15eSRuslan Bukin void 59b78ee15eSRuslan Bukin dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes, 60b78ee15eSRuslan Bukin uint32_t *intrpc) 61b78ee15eSRuslan Bukin { 62b78ee15eSRuslan Bukin struct unwind_state state; 63b78ee15eSRuslan Bukin int scp_offset; 64b78ee15eSRuslan Bukin int depth; 65b78ee15eSRuslan Bukin 66b78ee15eSRuslan Bukin depth = 0; 67b78ee15eSRuslan Bukin 68b78ee15eSRuslan Bukin if (intrpc != 0) { 69b78ee15eSRuslan Bukin pcstack[depth++] = (pc_t) intrpc; 70b78ee15eSRuslan Bukin } 71b78ee15eSRuslan Bukin 72b78ee15eSRuslan Bukin aframes++; 73b78ee15eSRuslan Bukin 744d16f941SJohn Baldwin state.fp = (uintptr_t)__builtin_frame_address(0); 754d16f941SJohn Baldwin state.pc = (uintptr_t)dtrace_getpcstack; 76b78ee15eSRuslan Bukin 77b78ee15eSRuslan Bukin while (depth < pcstack_limit) { 78ae953968SJohn Baldwin if (!unwind_frame(curthread, &state)) 79b78ee15eSRuslan Bukin break; 80ae953968SJohn Baldwin if (!INKERNEL(state.pc)) 81ae953968SJohn Baldwin break; 825f05bda6SMark Johnston 83b78ee15eSRuslan Bukin /* 84b78ee15eSRuslan Bukin * NB: Unlike some other architectures, we don't need to 85b78ee15eSRuslan Bukin * explicitly insert cpu_dtrace_caller as it appears in the 86b78ee15eSRuslan Bukin * normal kernel stack trace rather than a special trap frame. 87b78ee15eSRuslan Bukin */ 88b78ee15eSRuslan Bukin if (aframes > 0) { 89b78ee15eSRuslan Bukin aframes--; 90b78ee15eSRuslan Bukin } else { 91b78ee15eSRuslan Bukin pcstack[depth++] = state.pc; 92b78ee15eSRuslan Bukin } 93b78ee15eSRuslan Bukin 94b78ee15eSRuslan Bukin } 95b78ee15eSRuslan Bukin 96b78ee15eSRuslan Bukin for (; depth < pcstack_limit; depth++) { 97b78ee15eSRuslan Bukin pcstack[depth] = 0; 98b78ee15eSRuslan Bukin } 99b78ee15eSRuslan Bukin } 100b78ee15eSRuslan Bukin 1011c7c13aaSWojciech Macek static int 1021c7c13aaSWojciech Macek dtrace_getustack_common(uint64_t *pcstack, int pcstack_limit, uintptr_t pc, 1031c7c13aaSWojciech Macek uintptr_t fp) 1041c7c13aaSWojciech Macek { 1051c7c13aaSWojciech Macek volatile uint16_t *flags = 1061c7c13aaSWojciech Macek (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags; 1071c7c13aaSWojciech Macek int ret = 0; 1081cb290d2SAndrew Turner uintptr_t oldfp = fp; 1091c7c13aaSWojciech Macek 1101c7c13aaSWojciech Macek ASSERT(pcstack == NULL || pcstack_limit > 0); 1111c7c13aaSWojciech Macek 1121c7c13aaSWojciech Macek while (pc != 0) { 1131c7c13aaSWojciech Macek /* 1141c7c13aaSWojciech Macek * We limit the number of times we can go around this 1151c7c13aaSWojciech Macek * loop to account for a circular stack. 1161c7c13aaSWojciech Macek */ 1171c7c13aaSWojciech Macek if (ret++ >= MAX_USTACK_DEPTH) { 1181c7c13aaSWojciech Macek *flags |= CPU_DTRACE_BADSTACK; 1191c7c13aaSWojciech Macek cpu_core[curcpu].cpuc_dtrace_illval = fp; 1201c7c13aaSWojciech Macek break; 1211c7c13aaSWojciech Macek } 1221c7c13aaSWojciech Macek 1231c7c13aaSWojciech Macek if (pcstack != NULL) { 1241c7c13aaSWojciech Macek *pcstack++ = (uint64_t)pc; 1251c7c13aaSWojciech Macek pcstack_limit--; 1261c7c13aaSWojciech Macek if (pcstack_limit <= 0) 1271c7c13aaSWojciech Macek break; 1281c7c13aaSWojciech Macek } 1291c7c13aaSWojciech Macek 1301c7c13aaSWojciech Macek if (fp == 0) 1311c7c13aaSWojciech Macek break; 1321c7c13aaSWojciech Macek 1331c7c13aaSWojciech Macek pc = dtrace_fuword64((void *)(fp + 134d3251842SMark Johnston offsetof(struct unwind_state, pc))); 1351c7c13aaSWojciech Macek fp = dtrace_fuword64((void *)fp); 1361c7c13aaSWojciech Macek 1371c7c13aaSWojciech Macek if (fp == oldfp) { 1381c7c13aaSWojciech Macek *flags |= CPU_DTRACE_BADSTACK; 1391c7c13aaSWojciech Macek cpu_core[curcpu].cpuc_dtrace_illval = fp; 1401c7c13aaSWojciech Macek break; 1411c7c13aaSWojciech Macek } 1421c7c13aaSWojciech Macek 1431c7c13aaSWojciech Macek /* 1441c7c13aaSWojciech Macek * ARM64TODO: 1451c7c13aaSWojciech Macek * This workaround might not be necessary. It needs to be 1461c7c13aaSWojciech Macek * revised and removed from all architectures if found 1471c7c13aaSWojciech Macek * unwanted. Leaving the original x86 comment for reference. 1481c7c13aaSWojciech Macek * 1491c7c13aaSWojciech Macek * This is totally bogus: if we faulted, we're going to clear 1501c7c13aaSWojciech Macek * the fault and break. This is to deal with the apparently 1511c7c13aaSWojciech Macek * broken Java stacks on x86. 1521c7c13aaSWojciech Macek */ 1531c7c13aaSWojciech Macek if (*flags & CPU_DTRACE_FAULT) { 1541c7c13aaSWojciech Macek *flags &= ~CPU_DTRACE_FAULT; 1551c7c13aaSWojciech Macek break; 1561c7c13aaSWojciech Macek } 1571cb290d2SAndrew Turner 1581cb290d2SAndrew Turner oldfp = fp; 1591c7c13aaSWojciech Macek } 1601c7c13aaSWojciech Macek 1611c7c13aaSWojciech Macek return (ret); 1621c7c13aaSWojciech Macek } 1631c7c13aaSWojciech Macek 164b78ee15eSRuslan Bukin void 165b78ee15eSRuslan Bukin dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit) 166b78ee15eSRuslan Bukin { 1671c7c13aaSWojciech Macek proc_t *p = curproc; 1681c7c13aaSWojciech Macek struct trapframe *tf; 16905985a7fSJessica Clarke uintptr_t pc, fp; 1701c7c13aaSWojciech Macek volatile uint16_t *flags = 1711c7c13aaSWojciech Macek (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags; 1721c7c13aaSWojciech Macek int n; 173b78ee15eSRuslan Bukin 1741c7c13aaSWojciech Macek if (*flags & CPU_DTRACE_FAULT) 1751c7c13aaSWojciech Macek return; 1761c7c13aaSWojciech Macek 1771c7c13aaSWojciech Macek if (pcstack_limit <= 0) 1781c7c13aaSWojciech Macek return; 1791c7c13aaSWojciech Macek 1801c7c13aaSWojciech Macek /* 1811c7c13aaSWojciech Macek * If there's no user context we still need to zero the stack. 1821c7c13aaSWojciech Macek */ 1831c7c13aaSWojciech Macek if (p == NULL || (tf = curthread->td_frame) == NULL) 1841c7c13aaSWojciech Macek goto zero; 1851c7c13aaSWojciech Macek 1861c7c13aaSWojciech Macek *pcstack++ = (uint64_t)p->p_pid; 1871c7c13aaSWojciech Macek pcstack_limit--; 1881c7c13aaSWojciech Macek 1891c7c13aaSWojciech Macek if (pcstack_limit <= 0) 1901c7c13aaSWojciech Macek return; 1911c7c13aaSWojciech Macek 1921c7c13aaSWojciech Macek pc = tf->tf_elr; 1931c7c13aaSWojciech Macek fp = tf->tf_x[29]; 1941c7c13aaSWojciech Macek 1951c7c13aaSWojciech Macek if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) { 1961c7c13aaSWojciech Macek /* 1971c7c13aaSWojciech Macek * In an entry probe. The frame pointer has not yet been 1981c7c13aaSWojciech Macek * pushed (that happens in the function prologue). The 1991c7c13aaSWojciech Macek * best approach is to add the current pc as a missing top 2001c7c13aaSWojciech Macek * of stack and back the pc up to the caller, which is stored 2011c7c13aaSWojciech Macek * at the current stack pointer address since the call 2021c7c13aaSWojciech Macek * instruction puts it there right before the branch. 2031c7c13aaSWojciech Macek */ 2041c7c13aaSWojciech Macek 2051c7c13aaSWojciech Macek *pcstack++ = (uint64_t)pc; 2061c7c13aaSWojciech Macek pcstack_limit--; 2071c7c13aaSWojciech Macek if (pcstack_limit <= 0) 2081c7c13aaSWojciech Macek return; 2091c7c13aaSWojciech Macek 2101c7c13aaSWojciech Macek pc = tf->tf_lr; 2111c7c13aaSWojciech Macek } 2121c7c13aaSWojciech Macek 2131c7c13aaSWojciech Macek n = dtrace_getustack_common(pcstack, pcstack_limit, pc, fp); 2141c7c13aaSWojciech Macek ASSERT(n >= 0); 2151c7c13aaSWojciech Macek ASSERT(n <= pcstack_limit); 2161c7c13aaSWojciech Macek 2171c7c13aaSWojciech Macek pcstack += n; 2181c7c13aaSWojciech Macek pcstack_limit -= n; 2191c7c13aaSWojciech Macek 2201c7c13aaSWojciech Macek zero: 2211c7c13aaSWojciech Macek while (pcstack_limit-- > 0) 2221c7c13aaSWojciech Macek *pcstack++ = 0; 223b78ee15eSRuslan Bukin } 224b78ee15eSRuslan Bukin 225b78ee15eSRuslan Bukin int 226b78ee15eSRuslan Bukin dtrace_getustackdepth(void) 227b78ee15eSRuslan Bukin { 228b78ee15eSRuslan Bukin 229b78ee15eSRuslan Bukin printf("IMPLEMENT ME: %s\n", __func__); 230b78ee15eSRuslan Bukin 231b78ee15eSRuslan Bukin return (0); 232b78ee15eSRuslan Bukin } 233b78ee15eSRuslan Bukin 234b78ee15eSRuslan Bukin void 235b78ee15eSRuslan Bukin dtrace_getufpstack(uint64_t *pcstack, uint64_t *fpstack, int pcstack_limit) 236b78ee15eSRuslan Bukin { 237b78ee15eSRuslan Bukin 238b78ee15eSRuslan Bukin printf("IMPLEMENT ME: %s\n", __func__); 239b78ee15eSRuslan Bukin } 240b78ee15eSRuslan Bukin 241b78ee15eSRuslan Bukin uint64_t 242*bae00433SMark Johnston dtrace_getarg(int arg, int aframes __unused) 243b78ee15eSRuslan Bukin { 244*bae00433SMark Johnston struct trapframe *tf; 245b78ee15eSRuslan Bukin 246*bae00433SMark Johnston /* 247*bae00433SMark Johnston * We only handle invop providers here. 248*bae00433SMark Johnston */ 249*bae00433SMark Johnston if ((tf = curthread->t_dtrace_trapframe) == NULL) { 250*bae00433SMark Johnston DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP); 251b78ee15eSRuslan Bukin return (0); 252*bae00433SMark Johnston } else if (arg < 8) { 253*bae00433SMark Johnston return (tf->tf_x[arg]); 254*bae00433SMark Johnston } else { 255*bae00433SMark Johnston uintptr_t p; 256*bae00433SMark Johnston uint64_t val; 257*bae00433SMark Johnston 258*bae00433SMark Johnston p = (tf->tf_sp + (arg - 8) * sizeof(uint64_t)); 259*bae00433SMark Johnston if ((p & 7) != 0) { 260*bae00433SMark Johnston DTRACE_CPUFLAG_SET(CPU_DTRACE_BADALIGN); 261*bae00433SMark Johnston cpu_core[curcpu].cpuc_dtrace_illval = p; 262*bae00433SMark Johnston return (0); 263*bae00433SMark Johnston } 264*bae00433SMark Johnston if (!kstack_contains(curthread, p, sizeof(uint64_t))) { 265*bae00433SMark Johnston DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 266*bae00433SMark Johnston cpu_core[curcpu].cpuc_dtrace_illval = p; 267*bae00433SMark Johnston return (0); 268*bae00433SMark Johnston } 269*bae00433SMark Johnston memcpy(&val, (void *)p, sizeof(uint64_t)); 270*bae00433SMark Johnston return (val); 271*bae00433SMark Johnston } 272b78ee15eSRuslan Bukin } 273b78ee15eSRuslan Bukin 274b78ee15eSRuslan Bukin int 275b78ee15eSRuslan Bukin dtrace_getstackdepth(int aframes) 276b78ee15eSRuslan Bukin { 277b78ee15eSRuslan Bukin struct unwind_state state; 278b78ee15eSRuslan Bukin int scp_offset; 279b78ee15eSRuslan Bukin int depth; 280ae953968SJohn Baldwin bool done; 281b78ee15eSRuslan Bukin 282b78ee15eSRuslan Bukin depth = 1; 283ae953968SJohn Baldwin done = false; 284b78ee15eSRuslan Bukin 2854d16f941SJohn Baldwin state.fp = (uintptr_t)__builtin_frame_address(0); 2864d16f941SJohn Baldwin state.pc = (uintptr_t)dtrace_getstackdepth; 287b78ee15eSRuslan Bukin 288b78ee15eSRuslan Bukin do { 289ae953968SJohn Baldwin done = !unwind_frame(curthread, &state); 290b78ee15eSRuslan Bukin if (!INKERNEL(state.pc) || !INKERNEL(state.fp)) 291b78ee15eSRuslan Bukin break; 292b78ee15eSRuslan Bukin depth++; 293b78ee15eSRuslan Bukin } while (!done); 294b78ee15eSRuslan Bukin 295b78ee15eSRuslan Bukin if (depth < aframes) 296b78ee15eSRuslan Bukin return (0); 297b78ee15eSRuslan Bukin else 298b78ee15eSRuslan Bukin return (depth - aframes); 299b78ee15eSRuslan Bukin } 300b78ee15eSRuslan Bukin 301b78ee15eSRuslan Bukin ulong_t 30298ab9802SChristos Margiolis dtrace_getreg(struct trapframe *frame, uint_t reg) 303b78ee15eSRuslan Bukin { 30421a16d55SChristos Margiolis switch (reg) { 30521a16d55SChristos Margiolis case REG_X0 ... REG_X29: 30698ab9802SChristos Margiolis return (frame->tf_x[reg]); 30721a16d55SChristos Margiolis case REG_LR: 30898ab9802SChristos Margiolis return (frame->tf_lr); 30921a16d55SChristos Margiolis case REG_SP: 31098ab9802SChristos Margiolis return (frame->tf_sp); 31121a16d55SChristos Margiolis case REG_PC: 31298ab9802SChristos Margiolis return (frame->tf_elr); 31321a16d55SChristos Margiolis default: 31421a16d55SChristos Margiolis DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP); 315b78ee15eSRuslan Bukin return (0); 316b78ee15eSRuslan Bukin } 31721a16d55SChristos Margiolis /* NOTREACHED */ 31821a16d55SChristos Margiolis } 319b78ee15eSRuslan Bukin 320b78ee15eSRuslan Bukin static int 321b78ee15eSRuslan Bukin dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size) 322b78ee15eSRuslan Bukin { 323b78ee15eSRuslan Bukin 324b78ee15eSRuslan Bukin if (uaddr + size > VM_MAXUSER_ADDRESS || uaddr + size < uaddr) { 325b78ee15eSRuslan Bukin DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 326b78ee15eSRuslan Bukin cpu_core[curcpu].cpuc_dtrace_illval = uaddr; 327b78ee15eSRuslan Bukin return (0); 328b78ee15eSRuslan Bukin } 329b78ee15eSRuslan Bukin 330b78ee15eSRuslan Bukin return (1); 331b78ee15eSRuslan Bukin } 332b78ee15eSRuslan Bukin 333b78ee15eSRuslan Bukin void 334b78ee15eSRuslan Bukin dtrace_copyin(uintptr_t uaddr, uintptr_t kaddr, size_t size, 335b78ee15eSRuslan Bukin volatile uint16_t *flags) 336b78ee15eSRuslan Bukin { 337b78ee15eSRuslan Bukin 338b78ee15eSRuslan Bukin if (dtrace_copycheck(uaddr, kaddr, size)) 339b78ee15eSRuslan Bukin dtrace_copy(uaddr, kaddr, size); 340b78ee15eSRuslan Bukin } 341b78ee15eSRuslan Bukin 342b78ee15eSRuslan Bukin void 343b78ee15eSRuslan Bukin dtrace_copyout(uintptr_t kaddr, uintptr_t uaddr, size_t size, 344b78ee15eSRuslan Bukin volatile uint16_t *flags) 345b78ee15eSRuslan Bukin { 346b78ee15eSRuslan Bukin 347b78ee15eSRuslan Bukin if (dtrace_copycheck(uaddr, kaddr, size)) 348b78ee15eSRuslan Bukin dtrace_copy(kaddr, uaddr, size); 349b78ee15eSRuslan Bukin } 350b78ee15eSRuslan Bukin 351b78ee15eSRuslan Bukin void 352b78ee15eSRuslan Bukin dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size, 353b78ee15eSRuslan Bukin volatile uint16_t *flags) 354b78ee15eSRuslan Bukin { 355b78ee15eSRuslan Bukin 356b78ee15eSRuslan Bukin if (dtrace_copycheck(uaddr, kaddr, size)) 357b78ee15eSRuslan Bukin dtrace_copystr(uaddr, kaddr, size, flags); 358b78ee15eSRuslan Bukin } 359b78ee15eSRuslan Bukin 360b78ee15eSRuslan Bukin void 361b78ee15eSRuslan Bukin dtrace_copyoutstr(uintptr_t kaddr, uintptr_t uaddr, size_t size, 362b78ee15eSRuslan Bukin volatile uint16_t *flags) 363b78ee15eSRuslan Bukin { 364b78ee15eSRuslan Bukin 365b78ee15eSRuslan Bukin if (dtrace_copycheck(uaddr, kaddr, size)) 366b78ee15eSRuslan Bukin dtrace_copystr(kaddr, uaddr, size, flags); 367b78ee15eSRuslan Bukin } 368b78ee15eSRuslan Bukin 369b78ee15eSRuslan Bukin uint8_t 370b78ee15eSRuslan Bukin dtrace_fuword8(void *uaddr) 371b78ee15eSRuslan Bukin { 372b78ee15eSRuslan Bukin 373b78ee15eSRuslan Bukin if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { 374b78ee15eSRuslan Bukin DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 375b78ee15eSRuslan Bukin cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 376b78ee15eSRuslan Bukin return (0); 377b78ee15eSRuslan Bukin } 378b78ee15eSRuslan Bukin 379b78ee15eSRuslan Bukin return (dtrace_fuword8_nocheck(uaddr)); 380b78ee15eSRuslan Bukin } 381b78ee15eSRuslan Bukin 382b78ee15eSRuslan Bukin uint16_t 383b78ee15eSRuslan Bukin dtrace_fuword16(void *uaddr) 384b78ee15eSRuslan Bukin { 385b78ee15eSRuslan Bukin 386b78ee15eSRuslan Bukin if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { 387b78ee15eSRuslan Bukin DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 388b78ee15eSRuslan Bukin cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 389b78ee15eSRuslan Bukin return (0); 390b78ee15eSRuslan Bukin } 391b78ee15eSRuslan Bukin 392b78ee15eSRuslan Bukin return (dtrace_fuword16_nocheck(uaddr)); 393b78ee15eSRuslan Bukin } 394b78ee15eSRuslan Bukin 395b78ee15eSRuslan Bukin uint32_t 396b78ee15eSRuslan Bukin dtrace_fuword32(void *uaddr) 397b78ee15eSRuslan Bukin { 398b78ee15eSRuslan Bukin 399b78ee15eSRuslan Bukin if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { 400b78ee15eSRuslan Bukin DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 401b78ee15eSRuslan Bukin cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 402b78ee15eSRuslan Bukin return (0); 403b78ee15eSRuslan Bukin } 404b78ee15eSRuslan Bukin 405b78ee15eSRuslan Bukin return (dtrace_fuword32_nocheck(uaddr)); 406b78ee15eSRuslan Bukin } 407b78ee15eSRuslan Bukin 408b78ee15eSRuslan Bukin uint64_t 409b78ee15eSRuslan Bukin dtrace_fuword64(void *uaddr) 410b78ee15eSRuslan Bukin { 411b78ee15eSRuslan Bukin 412b78ee15eSRuslan Bukin if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { 413b78ee15eSRuslan Bukin DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); 414b78ee15eSRuslan Bukin cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; 415b78ee15eSRuslan Bukin return (0); 416b78ee15eSRuslan Bukin } 417b78ee15eSRuslan Bukin 418b78ee15eSRuslan Bukin return (dtrace_fuword64_nocheck(uaddr)); 419b78ee15eSRuslan Bukin } 420