The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/cddl/dev/dtrace/powerpc/dtrace_isa.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * CDDL HEADER START
    3  *
    4  * The contents of this file are subject to the terms of the
    5  * Common Development and Distribution License, Version 1.0 only
    6  * (the "License").  You may not use this file except in compliance
    7  * with the License.
    8  *
    9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   10  * or http://www.opensolaris.org/os/licensing.
   11  * See the License for the specific language governing permissions
   12  * and limitations under the License.
   13  *
   14  * When distributing Covered Code, include this CDDL HEADER in each
   15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
   16  * If applicable, add the following below this CDDL HEADER, with the
   17  * fields enclosed by brackets "[]" replaced with your own identifying
   18  * information: Portions Copyright [yyyy] [name of copyright owner]
   19  *
   20  * CDDL HEADER END
   21  *
   22  * Portions Copyright 2012,2013 Justin Hibbits <jhibbits@freebsd.org>
   23  *
   24  * $FreeBSD$
   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 #include <sys/stack.h>
   36 #include <sys/sysent.h>
   37 #include <sys/pcpu.h>
   38 
   39 #include <machine/frame.h>
   40 #include <machine/md_var.h>
   41 #include <machine/psl.h>
   42 #include <machine/stack.h>
   43 
   44 #include <vm/vm.h>
   45 #include <vm/vm_param.h>
   46 #include <vm/pmap.h>
   47 
   48 #include "regset.h"
   49 
   50 /* Offset to the LR Save word (ppc32) */
   51 #define RETURN_OFFSET   4
   52 /* Offset to LR Save word (ppc64).  CR Save area sits between back chain and LR */
   53 #define RETURN_OFFSET64 16
   54 
   55 #ifdef __powerpc64__
   56 #define OFFSET 4 /* Account for the TOC reload slot */
   57 #define FRAME_OFFSET    48
   58 #else
   59 #define OFFSET 0
   60 #define FRAME_OFFSET    8
   61 #endif
   62 
   63 #define INKERNEL(x)     (((x) <= VM_MAX_KERNEL_ADDRESS && \
   64                 (x) >= VM_MIN_KERNEL_ADDRESS) || \
   65                 (PMAP_HAS_DMAP && (x) >= DMAP_BASE_ADDRESS && \
   66                  (x) <= DMAP_MAX_ADDRESS))
   67 
   68 static __inline int
   69 dtrace_sp_inkernel(uintptr_t sp)
   70 {
   71         struct trapframe *frame;
   72         vm_offset_t callpc;
   73 
   74         /* Not within the kernel, or not aligned. */
   75         if (!INKERNEL(sp) || (sp & 0xf) != 0)
   76                 return (0);
   77 #ifdef __powerpc64__
   78         callpc = *(vm_offset_t *)(sp + RETURN_OFFSET64);
   79 #else
   80         callpc = *(vm_offset_t *)(sp + RETURN_OFFSET);
   81 #endif
   82         if ((callpc & 3) || (callpc < 0x100))
   83                 return (0);
   84 
   85         /*
   86          * trapexit() and asttrapexit() are sentinels
   87          * for kernel stack tracing.
   88          */
   89         if (callpc + OFFSET == (vm_offset_t) &trapexit ||
   90             callpc + OFFSET == (vm_offset_t) &asttrapexit) {
   91                 frame = (struct trapframe *)(sp + FRAME_OFFSET);
   92 
   93                 return ((frame->srr1 & PSL_PR) == 0);
   94         }
   95 
   96         return (1);
   97 }
   98 
   99 static __inline void
  100 dtrace_next_sp_pc(uintptr_t sp, uintptr_t *nsp, uintptr_t *pc)
  101 {
  102         vm_offset_t callpc;
  103         struct trapframe *frame;
  104 
  105 #ifdef __powerpc64__
  106         callpc = *(vm_offset_t *)(sp + RETURN_OFFSET64);
  107 #else
  108         callpc = *(vm_offset_t *)(sp + RETURN_OFFSET);
  109 #endif
  110 
  111         /*
  112          * trapexit() and asttrapexit() are sentinels
  113          * for kernel stack tracing.
  114          */
  115         if ((callpc + OFFSET == (vm_offset_t) &trapexit ||
  116             callpc + OFFSET == (vm_offset_t) &asttrapexit)) {
  117                 /* Access the trap frame */
  118                 frame = (struct trapframe *)(sp + FRAME_OFFSET);
  119 
  120                 if (nsp != NULL)
  121                         *nsp = frame->fixreg[1];
  122                 if (pc != NULL)
  123                         *pc = frame->srr0;
  124                 return;
  125         }
  126 
  127         if (nsp != NULL)
  128                 *nsp = *(uintptr_t *)sp;
  129         if (pc != NULL)
  130                 *pc = callpc;
  131 }
  132 
  133 void
  134 dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes,
  135     uint32_t *intrpc)
  136 {
  137         int depth = 0;
  138         uintptr_t osp, sp;
  139         vm_offset_t callpc;
  140         pc_t caller = (pc_t) solaris_cpu[curcpu].cpu_dtrace_caller;
  141 
  142         osp = PAGE_SIZE;
  143         if (intrpc != 0)
  144                 pcstack[depth++] = (pc_t) intrpc;
  145 
  146         aframes++;
  147 
  148         sp = (uintptr_t)__builtin_frame_address(0);
  149 
  150         while (depth < pcstack_limit) {
  151                 if (sp <= osp)
  152                         break;
  153 
  154                 if (!dtrace_sp_inkernel(sp))
  155                         break;
  156                 osp = sp;
  157                 dtrace_next_sp_pc(osp, &sp, &callpc);
  158 
  159                 if (aframes > 0) {
  160                         aframes--;
  161                         if ((aframes == 0) && (caller != 0)) {
  162                                 pcstack[depth++] = caller;
  163                         }
  164                 }
  165                 else {
  166                         pcstack[depth++] = callpc;
  167                 }
  168         }
  169 
  170         for (; depth < pcstack_limit; depth++) {
  171                 pcstack[depth] = 0;
  172         }
  173 }
  174 
  175 static int
  176 dtrace_getustack_common(uint64_t *pcstack, int pcstack_limit, uintptr_t pc,
  177     uintptr_t sp)
  178 {
  179         proc_t *p = curproc;
  180         int ret = 0;
  181 
  182         ASSERT(pcstack == NULL || pcstack_limit > 0);
  183 
  184         while (pc != 0) {
  185                 ret++;
  186                 if (pcstack != NULL) {
  187                         *pcstack++ = (uint64_t)pc;
  188                         pcstack_limit--;
  189                         if (pcstack_limit <= 0)
  190                                 break;
  191                 }
  192 
  193                 if (sp == 0)
  194                         break;
  195 
  196                 if (SV_PROC_FLAG(p, SV_ILP32)) {
  197                         pc = dtrace_fuword32((void *)(sp + RETURN_OFFSET));
  198                         sp = dtrace_fuword32((void *)sp);
  199                 }
  200                 else {
  201                         pc = dtrace_fuword64((void *)(sp + RETURN_OFFSET64));
  202                         sp = dtrace_fuword64((void *)sp);
  203                 }
  204         }
  205 
  206         return (ret);
  207 }
  208 
  209 void
  210 dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit)
  211 {
  212         proc_t *p = curproc;
  213         struct trapframe *tf;
  214         uintptr_t pc, sp;
  215         volatile uint16_t *flags =
  216             (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags;
  217         int n;
  218 
  219         if (*flags & CPU_DTRACE_FAULT)
  220                 return;
  221 
  222         if (pcstack_limit <= 0)
  223                 return;
  224 
  225         /*
  226          * If there's no user context we still need to zero the stack.
  227          */
  228         if (p == NULL || (tf = curthread->td_frame) == NULL)
  229                 goto zero;
  230 
  231         *pcstack++ = (uint64_t)p->p_pid;
  232         pcstack_limit--;
  233 
  234         if (pcstack_limit <= 0)
  235                 return;
  236 
  237         pc = tf->srr0;
  238         sp = tf->fixreg[1];
  239 
  240         if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) {
  241                 /* 
  242                  * In an entry probe.  The frame pointer has not yet been
  243                  * pushed (that happens in the function prologue).  The
  244                  * best approach is to add the current pc as a missing top
  245                  * of stack and back the pc up to the caller, which is stored
  246                  * at the current stack pointer address since the call 
  247                  * instruction puts it there right before the branch.
  248                  */
  249 
  250                 *pcstack++ = (uint64_t)pc;
  251                 pcstack_limit--;
  252                 if (pcstack_limit <= 0)
  253                         return;
  254 
  255                 pc = tf->lr;
  256         }
  257 
  258         n = dtrace_getustack_common(pcstack, pcstack_limit, pc, sp);
  259         ASSERT(n >= 0);
  260         ASSERT(n <= pcstack_limit);
  261 
  262         pcstack += n;
  263         pcstack_limit -= n;
  264 
  265 zero:
  266         while (pcstack_limit-- > 0)
  267                 *pcstack++ = 0;
  268 }
  269 
  270 int
  271 dtrace_getustackdepth(void)
  272 {
  273         proc_t *p = curproc;
  274         struct trapframe *tf;
  275         uintptr_t pc, sp;
  276         int n = 0;
  277 
  278         if (p == NULL || (tf = curthread->td_frame) == NULL)
  279                 return (0);
  280 
  281         if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_FAULT))
  282                 return (-1);
  283 
  284         pc = tf->srr0;
  285         sp = tf->fixreg[1];
  286 
  287         if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) {
  288                 /* 
  289                  * In an entry probe.  The frame pointer has not yet been
  290                  * pushed (that happens in the function prologue).  The
  291                  * best approach is to add the current pc as a missing top
  292                  * of stack and back the pc up to the caller, which is stored
  293                  * at the current stack pointer address since the call 
  294                  * instruction puts it there right before the branch.
  295                  */
  296 
  297                 if (SV_PROC_FLAG(p, SV_ILP32)) {
  298                         pc = dtrace_fuword32((void *) sp);
  299                 }
  300                 else
  301                         pc = dtrace_fuword64((void *) sp);
  302                 n++;
  303         }
  304 
  305         n += dtrace_getustack_common(NULL, 0, pc, sp);
  306 
  307         return (n);
  308 }
  309 
  310 void
  311 dtrace_getufpstack(uint64_t *pcstack, uint64_t *fpstack, int pcstack_limit)
  312 {
  313         proc_t *p = curproc;
  314         struct trapframe *tf;
  315         uintptr_t pc, sp;
  316         volatile uint16_t *flags =
  317             (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags;
  318 #ifdef notyet   /* XXX signal stack */
  319         uintptr_t oldcontext;
  320         size_t s1, s2;
  321 #endif
  322 
  323         if (*flags & CPU_DTRACE_FAULT)
  324                 return;
  325 
  326         if (pcstack_limit <= 0)
  327                 return;
  328 
  329         /*
  330          * If there's no user context we still need to zero the stack.
  331          */
  332         if (p == NULL || (tf = curthread->td_frame) == NULL)
  333                 goto zero;
  334 
  335         *pcstack++ = (uint64_t)p->p_pid;
  336         pcstack_limit--;
  337 
  338         if (pcstack_limit <= 0)
  339                 return;
  340 
  341         pc = tf->srr0;
  342         sp = tf->fixreg[1];
  343 
  344 #ifdef notyet /* XXX signal stack */
  345         oldcontext = lwp->lwp_oldcontext;
  346         s1 = sizeof (struct xframe) + 2 * sizeof (long);
  347         s2 = s1 + sizeof (siginfo_t);
  348 #endif
  349 
  350         if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) {
  351                 *pcstack++ = (uint64_t)pc;
  352                 *fpstack++ = 0;
  353                 pcstack_limit--;
  354                 if (pcstack_limit <= 0)
  355                         return;
  356 
  357                 if (SV_PROC_FLAG(p, SV_ILP32)) {
  358                         pc = dtrace_fuword32((void *)sp);
  359                 }
  360                 else {
  361                         pc = dtrace_fuword64((void *)sp);
  362                 }
  363         }
  364 
  365         while (pc != 0) {
  366                 *pcstack++ = (uint64_t)pc;
  367                 *fpstack++ = sp;
  368                 pcstack_limit--;
  369                 if (pcstack_limit <= 0)
  370                         break;
  371 
  372                 if (sp == 0)
  373                         break;
  374 
  375 #ifdef notyet /* XXX signal stack */
  376                 if (oldcontext == sp + s1 || oldcontext == sp + s2) {
  377                         ucontext_t *ucp = (ucontext_t *)oldcontext;
  378                         greg_t *gregs = ucp->uc_mcontext.gregs;
  379 
  380                         sp = dtrace_fulword(&gregs[REG_FP]);
  381                         pc = dtrace_fulword(&gregs[REG_PC]);
  382 
  383                         oldcontext = dtrace_fulword(&ucp->uc_link);
  384                 } else
  385 #endif /* XXX */
  386                 {
  387                         if (SV_PROC_FLAG(p, SV_ILP32)) {
  388                                 pc = dtrace_fuword32((void *)(sp + RETURN_OFFSET));
  389                                 sp = dtrace_fuword32((void *)sp);
  390                         }
  391                         else {
  392                                 pc = dtrace_fuword64((void *)(sp + RETURN_OFFSET64));
  393                                 sp = dtrace_fuword64((void *)sp);
  394                         }
  395                 }
  396 
  397                 /*
  398                  * This is totally bogus:  if we faulted, we're going to clear
  399                  * the fault and break.  This is to deal with the apparently
  400                  * broken Java stacks on x86.
  401                  */
  402                 if (*flags & CPU_DTRACE_FAULT) {
  403                         *flags &= ~CPU_DTRACE_FAULT;
  404                         break;
  405                 }
  406         }
  407 
  408 zero:
  409         while (pcstack_limit-- > 0)
  410                 *pcstack++ = 0;
  411 }
  412 
  413 /*ARGSUSED*/
  414 uint64_t
  415 dtrace_getarg(int arg, int aframes)
  416 {
  417         uintptr_t val;
  418         uintptr_t *fp = (uintptr_t *)__builtin_frame_address(0);
  419         uintptr_t *stack;
  420         int i;
  421 
  422         /*
  423          * A total of 8 arguments are passed via registers; any argument with
  424          * index of 7 or lower is therefore in a register.
  425          */
  426         int inreg = 7;
  427 
  428         for (i = 1; i <= aframes; i++) {
  429                 fp = (uintptr_t *)*fp;
  430 
  431                 /*
  432                  * On ppc32 trapexit() is the immediately following label.  On
  433                  * ppc64 AIM trapexit() follows a nop.
  434                  */
  435 #ifdef __powerpc64__
  436                 if ((long)(fp[2]) + 4 == (long)trapexit) {
  437 #else
  438                 if ((long)(fp[1]) == (long)trapexit) {
  439 #endif
  440                         /*
  441                          * In the case of powerpc, we will use the pointer to the regs
  442                          * structure that was pushed when we took the trap.  To get this
  443                          * structure, we must increment beyond the frame structure.  If the
  444                          * argument that we're seeking is passed on the stack, we'll pull
  445                          * the true stack pointer out of the saved registers and decrement
  446                          * our argument by the number of arguments passed in registers; if
  447                          * the argument we're seeking is passed in regsiters, we can just
  448                          * load it directly.
  449                          */
  450 #ifdef __powerpc64__
  451                         struct reg *rp = (struct reg *)((uintptr_t)fp[0] + 48);
  452 #else
  453                         struct reg *rp = (struct reg *)((uintptr_t)fp[0] + 8);
  454 #endif
  455 
  456                         if (arg <= inreg) {
  457                                 stack = &rp->fixreg[3];
  458                         } else {
  459                                 stack = (uintptr_t *)(rp->fixreg[1]);
  460                                 arg -= inreg;
  461                         }
  462                         goto load;
  463                 }
  464 
  465         }
  466 
  467         /*
  468          * We know that we did not come through a trap to get into
  469          * dtrace_probe() -- the provider simply called dtrace_probe()
  470          * directly.  As this is the case, we need to shift the argument
  471          * that we're looking for:  the probe ID is the first argument to
  472          * dtrace_probe(), so the argument n will actually be found where
  473          * one would expect to find argument (n + 1).
  474          */
  475         arg++;
  476 
  477         if (arg <= inreg) {
  478                 /*
  479                  * This shouldn't happen.  If the argument is passed in a
  480                  * register then it should have been, well, passed in a
  481                  * register...
  482                  */
  483                 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
  484                 return (0);
  485         }
  486 
  487         arg -= (inreg + 1);
  488         stack = fp + 2;
  489 
  490 load:
  491         DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
  492         val = stack[arg];
  493         DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
  494 
  495         return (val);
  496 }
  497 
  498 int
  499 dtrace_getstackdepth(int aframes)
  500 {
  501         int depth = 0;
  502         uintptr_t osp, sp;
  503         vm_offset_t callpc;
  504 
  505         osp = PAGE_SIZE;
  506         sp = (uintptr_t)__builtin_frame_address(0);
  507         for(;;) {
  508                 if (sp <= osp)
  509                         break;
  510 
  511                 if (!dtrace_sp_inkernel(sp))
  512                         break;
  513 
  514                 depth++;
  515                 osp = sp;
  516                 dtrace_next_sp_pc(sp, &sp, NULL);
  517         }
  518         if (depth < aframes)
  519                 return (0);
  520 
  521         return (depth - aframes);
  522 }
  523 
  524 ulong_t
  525 dtrace_getreg(struct trapframe *rp, uint_t reg)
  526 {
  527         if (reg < 32)
  528                 return (rp->fixreg[reg]);
  529 
  530         switch (reg) {
  531         case 32:
  532                 return (rp->lr);
  533         case 33:
  534                 return (rp->cr);
  535         case 34:
  536                 return (rp->xer);
  537         case 35:
  538                 return (rp->ctr);
  539         case 36:
  540                 return (rp->srr0);
  541         case 37:
  542                 return (rp->srr1);
  543         case 38:
  544                 return (rp->exc);
  545         default:
  546                 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
  547                 return (0);
  548         }
  549 }
  550 
  551 static int
  552 dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size)
  553 {
  554         ASSERT(INKERNEL(kaddr) && kaddr + size >= kaddr);
  555 
  556         if (uaddr + size > VM_MAXUSER_ADDRESS || uaddr + size < uaddr) {
  557                 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
  558                 cpu_core[curcpu].cpuc_dtrace_illval = uaddr;
  559                 return (0);
  560         }
  561 
  562         return (1);
  563 }
  564 
  565 void
  566 dtrace_copyin(uintptr_t uaddr, uintptr_t kaddr, size_t size,
  567     volatile uint16_t *flags)
  568 {
  569         if (dtrace_copycheck(uaddr, kaddr, size))
  570                 if (copyin((const void *)uaddr, (void *)kaddr, size)) {
  571                         DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
  572                         cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
  573                 }
  574 }
  575 
  576 void
  577 dtrace_copyout(uintptr_t kaddr, uintptr_t uaddr, size_t size,
  578     volatile uint16_t *flags)
  579 {
  580         if (dtrace_copycheck(uaddr, kaddr, size)) {
  581                 if (copyout((const void *)kaddr, (void *)uaddr, size)) {
  582                         DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
  583                         cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
  584                 }
  585         }
  586 }
  587 
  588 void
  589 dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
  590     volatile uint16_t *flags)
  591 {
  592         size_t actual;
  593         int    error;
  594 
  595         if (dtrace_copycheck(uaddr, kaddr, size)) {
  596                 error = copyinstr((const void *)uaddr, (void *)kaddr,
  597                     size, &actual);
  598                 
  599                 /* ENAMETOOLONG is not a fault condition. */
  600                 if (error && error != ENAMETOOLONG) {
  601                         DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
  602                         cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
  603                 }
  604         }
  605 }
  606 
  607 /*
  608  * The bulk of this function could be replaced to match dtrace_copyinstr() 
  609  * if we ever implement a copyoutstr().
  610  */
  611 void
  612 dtrace_copyoutstr(uintptr_t kaddr, uintptr_t uaddr, size_t size,
  613     volatile uint16_t *flags)
  614 {
  615         size_t len;
  616 
  617         if (dtrace_copycheck(uaddr, kaddr, size)) {
  618                 len = strlen((const char *)kaddr);
  619                 if (len > size)
  620                         len = size;
  621 
  622                 if (copyout((const void *)kaddr, (void *)uaddr, len)) {
  623                         DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
  624                         cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
  625                 }
  626         }
  627 }
  628 
  629 uint8_t
  630 dtrace_fuword8(void *uaddr)
  631 {
  632         if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) {
  633                 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
  634                 cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
  635                 return (0);
  636         }
  637         return (fubyte(uaddr));
  638 }
  639 
  640 uint16_t
  641 dtrace_fuword16(void *uaddr)
  642 {
  643         uint16_t ret = 0;
  644 
  645         if (dtrace_copycheck((uintptr_t)uaddr, (uintptr_t)&ret, sizeof(ret))) {
  646                 if (copyin((const void *)uaddr, (void *)&ret, sizeof(ret))) {
  647                         DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
  648                         cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
  649                 }
  650         }
  651         return ret;
  652 }
  653 
  654 uint32_t
  655 dtrace_fuword32(void *uaddr)
  656 {
  657         if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) {
  658                 DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
  659                 cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
  660                 return (0);
  661         }
  662         return (fuword32(uaddr));
  663 }
  664 
  665 uint64_t
  666 dtrace_fuword64(void *uaddr)
  667 {
  668         uint64_t ret = 0;
  669 
  670         if (dtrace_copycheck((uintptr_t)uaddr, (uintptr_t)&ret, sizeof(ret))) {
  671                 if (copyin((const void *)uaddr, (void *)&ret, sizeof(ret))) {
  672                         DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
  673                         cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
  674                 }
  675         }
  676         return ret;
  677 }
  678 
  679 uintptr_t
  680 dtrace_fulword(void *uaddr)
  681 {
  682         uintptr_t ret = 0;
  683 
  684         if (dtrace_copycheck((uintptr_t)uaddr, (uintptr_t)&ret, sizeof(ret))) {
  685                 if (copyin((const void *)uaddr, (void *)&ret, sizeof(ret))) {
  686                         DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
  687                         cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr;
  688                 }
  689         }
  690         return ret;
  691 }

Cache object: adfb99a412187391255ebff710ece9e6


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.