Author: jhibbits
Date: Wed Jul  3 19:21:03 2019
New Revision: 349675
URL: https://svnweb.freebsd.org/changeset/base/349675

Log:
  MFC r346173,r347943
  
  r346173: powerpc/dtrace: Fix dtrace powerpc asm, and simplify stack walking
  r347943: powerpc/dtrace: Actually fix stack traces

Modified:
  stable/12/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S
  stable/12/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S
==============================================================================
--- stable/12/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S  Wed Jul  3 19:07:42 
2019        (r349674)
+++ stable/12/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S  Wed Jul  3 19:21:03 
2019        (r349675)
@@ -148,14 +148,19 @@ dtrace_copystr(uintptr_t uaddr, uintptr_t kaddr, size_
     volatile uint16_t *flags)
 */
 ASENTRY_NOPROF(dtrace_copystr)
-       addme   %r7,%r3
-       addme   %r8,%r4
+       subi    %r7,%r3,1
+       subi    %r8,%r4,1
 1:
        lbzu    %r3,1(%r7)
        stbu    %r3,1(%r8)
-       addme   %r5,%r5
+       subi    %r5,%r5,1
+#ifdef __powerpc64__
+       cmpldi  %r5,0
+#else
+       cmplwi  %r5,0
+#endif
        beq     2f
-       or      %r3,%r3,%r3
+       cmplwi  %r3,0
        beq     2f
        andi.   %r0,%r5,0x0fff
        beq     2f
@@ -174,3 +179,13 @@ ASENTRY_NOPROF(dtrace_caller)
        li      %r3, -1
        blr
 END(dtrace_caller)
+
+/*
+greg_t
+dtrace_getfp(void)
+*/
+ASENTRY_NOPROF(dtrace_getfp)
+       mr      %r3,%r31
+       blr
+END(dtrace_getfp)
+

Modified: stable/12/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c
==============================================================================
--- stable/12/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c  Wed Jul  3 19:07:42 
2019        (r349674)
+++ stable/12/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c  Wed Jul  3 19:21:03 
2019        (r349675)
@@ -61,8 +61,10 @@
 #define        FRAME_OFFSET    8
 #endif
 
-#define INKERNEL(x)    ((x) <= VM_MAX_KERNEL_ADDRESS && \
-               (x) >= VM_MIN_KERNEL_ADDRESS)
+#define INKERNEL(x)    (((x) <= VM_MAX_KERNEL_ADDRESS && \
+               (x) >= VM_MIN_KERNEL_ADDRESS) || \
+               (PMAP_HAS_DMAP && (x) >= DMAP_BASE_ADDRESS && \
+                (x) <= DMAP_MAX_ADDRESS))
 
 static __inline int
 dtrace_sp_inkernel(uintptr_t sp)
@@ -70,6 +72,9 @@ dtrace_sp_inkernel(uintptr_t sp)
        struct trapframe *frame;
        vm_offset_t callpc;
 
+       /* Not within the kernel, or not aligned. */
+       if (!INKERNEL(sp) || (sp & 0xf) != 0)
+               return (0);
 #ifdef __powerpc64__
        callpc = *(vm_offset_t *)(sp + RETURN_OFFSET64);
 #else
@@ -84,8 +89,6 @@ dtrace_sp_inkernel(uintptr_t sp)
         */
        if (callpc + OFFSET == (vm_offset_t) &trapexit ||
            callpc + OFFSET == (vm_offset_t) &asttrapexit) {
-               if (sp == 0)
-                       return (0);
                frame = (struct trapframe *)(sp + FRAME_OFFSET);
 
                return ((frame->srr1 & PSL_PR) == 0);
@@ -94,11 +97,10 @@ dtrace_sp_inkernel(uintptr_t sp)
        return (1);
 }
 
-static __inline uintptr_t
-dtrace_next_sp(uintptr_t sp)
+static __inline void
+dtrace_next_sp_pc(uintptr_t sp, uintptr_t *nsp, uintptr_t *pc)
 {
        vm_offset_t callpc;
-       uintptr_t *r1;
        struct trapframe *frame;
 
 #ifdef __powerpc64__
@@ -115,47 +117,20 @@ dtrace_next_sp(uintptr_t sp)
            callpc + OFFSET == (vm_offset_t) &asttrapexit)) {
                /* Access the trap frame */
                frame = (struct trapframe *)(sp + FRAME_OFFSET);
-               r1 = (uintptr_t *)frame->fixreg[1];
-               if (r1 == NULL)
-                       return (0);
-               return (*r1);
-       }
 
-       return (*(uintptr_t*)sp);
-}
-
-static __inline uintptr_t
-dtrace_get_pc(uintptr_t sp)
-{
-       struct trapframe *frame;
-       vm_offset_t callpc;
-
-#ifdef __powerpc64__
-       callpc = *(vm_offset_t *)(sp + RETURN_OFFSET64);
-#else
-       callpc = *(vm_offset_t *)(sp + RETURN_OFFSET);
-#endif
-
-       /*
-        * trapexit() and asttrapexit() are sentinels
-        * for kernel stack tracing.
-        */
-       if ((callpc + OFFSET == (vm_offset_t) &trapexit ||
-           callpc + OFFSET == (vm_offset_t) &asttrapexit)) {
-               /* Access the trap frame */
-               frame = (struct trapframe *)(sp + FRAME_OFFSET);
-               return (frame->srr0);
+               if (nsp != NULL)
+                       *nsp = frame->fixreg[1];
+               if (pc != NULL)
+                       *pc = frame->srr0;
+               return;
        }
 
-       return (callpc);
+       if (nsp != NULL)
+               *nsp = *(uintptr_t *)sp;
+       if (pc != NULL)
+               *pc = callpc;
 }
 
-greg_t
-dtrace_getfp(void)
-{
-       return (greg_t)__builtin_frame_address(0);
-}
-
 void
 dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes,
     uint32_t *intrpc)
@@ -171,7 +146,7 @@ dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, in
 
        aframes++;
 
-       sp = dtrace_getfp();
+       sp = (uintptr_t)__builtin_frame_address(0);
 
        while (depth < pcstack_limit) {
                if (sp <= osp)
@@ -179,7 +154,8 @@ dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, in
 
                if (!dtrace_sp_inkernel(sp))
                        break;
-               callpc = dtrace_get_pc(sp);
+               osp = sp;
+               dtrace_next_sp_pc(osp, &sp, &callpc);
 
                if (aframes > 0) {
                        aframes--;
@@ -190,9 +166,6 @@ dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, in
                else {
                        pcstack[depth++] = callpc;
                }
-
-               osp = sp;
-               sp = dtrace_next_sp(sp);
        }
 
        for (; depth < pcstack_limit; depth++) {
@@ -443,7 +416,7 @@ uint64_t
 dtrace_getarg(int arg, int aframes)
 {
        uintptr_t val;
-       uintptr_t *fp = (uintptr_t *)dtrace_getfp();
+       uintptr_t *fp = (uintptr_t *)__builtin_frame_address(0);
        uintptr_t *stack;
        int i;
 
@@ -457,8 +430,8 @@ dtrace_getarg(int arg, int aframes)
                fp = (uintptr_t *)*fp;
 
                /*
-                * On ppc32 AIM, and booke, trapexit() is the immediately 
following
-                * label.  On ppc64 AIM trapexit() follows a nop.
+                * On ppc32 trapexit() is the immediately following label.  On
+                * ppc64 AIM trapexit() follows a nop.
                 */
 #ifdef __powerpc64__
                if ((long)(fp[2]) + 4 == (long)trapexit) {
@@ -531,9 +504,7 @@ dtrace_getstackdepth(int aframes)
        vm_offset_t callpc;
 
        osp = PAGE_SIZE;
-       aframes++;
-       sp = dtrace_getfp();
-       depth++;
+       sp = (uintptr_t)__builtin_frame_address(0);
        for(;;) {
                if (sp <= osp)
                        break;
@@ -541,17 +512,14 @@ dtrace_getstackdepth(int aframes)
                if (!dtrace_sp_inkernel(sp))
                        break;
 
-               if (aframes == 0)
-                       depth++;
-               else
-                       aframes--;
+               depth++;
                osp = sp;
-               sp = dtrace_next_sp(sp);
+               dtrace_next_sp_pc(sp, &sp, NULL);
        }
        if (depth < aframes)
                return (0);
 
-       return (depth);
+       return (depth - aframes);
 }
 
 ulong_t
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to