Author: jhibbits
Date: Sat May 20 05:12:32 2017
New Revision: 318572
URL: https://svnweb.freebsd.org/changeset/base/318572

Log:
  MFC r314370,r318130,r318167:
  
    DTrace related fixes for PowerPC.
  
    r314370:
      Unbreak kernel breakpoints, broken for ~4 years now
    r318130:
      Fix the encoded instruction for FBT traps on powerpc
    r318167:
      Fix stack tracing in dtrace for powerpc

Modified:
  stable/11/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c
  stable/11/sys/cddl/dev/fbt/powerpc/fbt_isa.c
  stable/11/sys/powerpc/booke/trap_subr.S
  stable/11/sys/powerpc/include/trap.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c
==============================================================================
--- stable/11/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c  Sat May 20 03:51:31 
2017        (r318571)
+++ stable/11/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c  Sat May 20 05:12:32 
2017        (r318572)
@@ -38,6 +38,7 @@
 
 #include <machine/frame.h>
 #include <machine/md_var.h>
+#include <machine/psl.h>
 #include <machine/reg.h>
 #include <machine/stack.h>
 
@@ -54,16 +55,19 @@
 
 #ifdef __powerpc64__
 #define OFFSET 4 /* Account for the TOC reload slot */
+#define        FRAME_OFFSET    48
 #else
 #define OFFSET 0
+#define        FRAME_OFFSET    8
 #endif
 
 #define INKERNEL(x)    ((x) <= VM_MAX_KERNEL_ADDRESS && \
                (x) >= VM_MIN_KERNEL_ADDRESS)
 
 static __inline int
-dtrace_sp_inkernel(uintptr_t sp, int aframes)
+dtrace_sp_inkernel(uintptr_t sp)
 {
+       struct trapframe *frame;
        vm_offset_t callpc;
 
 #ifdef __powerpc64__
@@ -77,14 +81,15 @@ dtrace_sp_inkernel(uintptr_t sp, int afr
        /*
         * trapexit() and asttrapexit() are sentinels
         * for kernel stack tracing.
-        *
-        * Special-case this for 'aframes == 0', because fbt sets aframes to the
-        * trap callchain depth, so we want to break out of it.
         */
-       if ((callpc + OFFSET == (vm_offset_t) &trapexit ||
-           callpc + OFFSET == (vm_offset_t) &asttrapexit) &&
-           aframes != 0)
-               return (0);
+       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);
+       }
 
        return (1);
 }
@@ -93,6 +98,7 @@ static __inline uintptr_t
 dtrace_next_sp(uintptr_t sp)
 {
        vm_offset_t callpc;
+       struct trapframe *frame;
 
 #ifdef __powerpc64__
        callpc = *(vm_offset_t *)(sp + RETURN_OFFSET64);
@@ -103,18 +109,13 @@ dtrace_next_sp(uintptr_t sp)
        /*
         * trapexit() and asttrapexit() are sentinels
         * for kernel stack tracing.
-        *
-        * Special-case this for 'aframes == 0', because fbt sets aframes to the
-        * trap callchain depth, so we want to break out of it.
         */
        if ((callpc + OFFSET == (vm_offset_t) &trapexit ||
-           callpc + OFFSET == (vm_offset_t) &asttrapexit))
-           /* Access the trap frame */
-#ifdef __powerpc64__
-               return (*(uintptr_t *)sp + 48 + sizeof(register_t));
-#else
-               return (*(uintptr_t *)sp + 8 + sizeof(register_t));
-#endif
+           callpc + OFFSET == (vm_offset_t) &asttrapexit)) {
+               /* Access the trap frame */
+               frame = (struct trapframe *)(sp + FRAME_OFFSET);
+               return (*(uintptr_t *)(frame->fixreg[1]));
+       }
 
        return (*(uintptr_t*)sp);
 }
@@ -122,6 +123,7 @@ dtrace_next_sp(uintptr_t sp)
 static __inline uintptr_t
 dtrace_get_pc(uintptr_t sp)
 {
+       struct trapframe *frame;
        vm_offset_t callpc;
 
 #ifdef __powerpc64__
@@ -133,18 +135,13 @@ dtrace_get_pc(uintptr_t sp)
        /*
         * trapexit() and asttrapexit() are sentinels
         * for kernel stack tracing.
-        *
-        * Special-case this for 'aframes == 0', because fbt sets aframes to the
-        * trap callchain depth, so we want to break out of it.
         */
        if ((callpc + OFFSET == (vm_offset_t) &trapexit ||
-           callpc + OFFSET == (vm_offset_t) &asttrapexit))
-           /* Access the trap frame */
-#ifdef __powerpc64__
-               return (*(uintptr_t *)sp + 48 + offsetof(struct trapframe, lr));
-#else
-               return (*(uintptr_t *)sp + 8 + offsetof(struct trapframe, lr));
-#endif
+           callpc + OFFSET == (vm_offset_t) &asttrapexit)) {
+               /* Access the trap frame */
+               frame = (struct trapframe *)(sp + FRAME_OFFSET);
+               return (frame->srr0);
+       }
 
        return (callpc);
 }
@@ -176,7 +173,7 @@ dtrace_getpcstack(pc_t *pcstack, int pcs
                if (sp <= osp)
                        break;
 
-               if (!dtrace_sp_inkernel(sp, aframes))
+               if (!dtrace_sp_inkernel(sp))
                        break;
                callpc = dtrace_get_pc(sp);
 
@@ -537,7 +534,7 @@ dtrace_getstackdepth(int aframes)
                if (sp <= osp)
                        break;
 
-               if (!dtrace_sp_inkernel(sp, aframes))
+               if (!dtrace_sp_inkernel(sp))
                        break;
 
                if (aframes == 0)

Modified: stable/11/sys/cddl/dev/fbt/powerpc/fbt_isa.c
==============================================================================
--- stable/11/sys/cddl/dev/fbt/powerpc/fbt_isa.c        Sat May 20 03:51:31 
2017        (r318571)
+++ stable/11/sys/cddl/dev/fbt/powerpc/fbt_isa.c        Sat May 20 05:12:32 
2017        (r318572)
@@ -37,7 +37,7 @@
 
 #include "fbt.h"
 
-#define FBT_PATCHVAL           0x7c810808
+#define FBT_PATCHVAL           0x7ffff808
 #define FBT_MFLR_R0            0x7c0802a6
 #define FBT_MTLR_R0            0x7c0803a6
 #define FBT_BLR                        0x4e800020

Modified: stable/11/sys/powerpc/booke/trap_subr.S
==============================================================================
--- stable/11/sys/powerpc/booke/trap_subr.S     Sat May 20 03:51:31 2017        
(r318571)
+++ stable/11/sys/powerpc/booke/trap_subr.S     Sat May 20 05:12:32 2017        
(r318572)
@@ -803,12 +803,12 @@ INTERRUPT(int_debug)
        lwz     %r4,0(%r5)      /* interrupt_vector_base in r4 */
        add     %r4,%r4,%r5
        cmplw   cr0, %r3, %r4
-       blt     1f
+       blt     trap_common
        lwz     %r4,4(%r5)      /* interrupt_vector_top in r4 */
        add     %r4,%r4,%r5
        addi    %r4,%r4,4
        cmplw   cr0, %r3, %r4
-       bge     1f
+       bge     trap_common
        /* Disable single-stepping for the interrupt handlers. */
        lwz     %r3, FRAME_SRR1+8(%r1);
        rlwinm  %r3, %r3, 0, 23, 21
@@ -820,14 +820,6 @@ INTERRUPT(int_debug)
        lwz     %r4, (PC_BOOKE_CRITSAVE+CPUSAVE_SRR1+8)(%r4);
        mtspr   SPR_SRR1, %r4
        b       9f
-1:
-       addi    %r3, %r1, 8
-       bl      CNAME(trap)
-       /*
-        * Handle ASTs, needed for proper support of single-stepping.
-        * We actually need to return to the process with an rfi.
-        */
-       b       trapexit
 9:
        FRAME_LEAVE(SPR_CSRR0, SPR_CSRR1)
        rfci

Modified: stable/11/sys/powerpc/include/trap.h
==============================================================================
--- stable/11/sys/powerpc/include/trap.h        Sat May 20 03:51:31 2017        
(r318571)
+++ stable/11/sys/powerpc/include/trap.h        Sat May 20 05:12:32 2017        
(r318572)
@@ -125,7 +125,7 @@
 #define        EXC_PGM_TRAP            (1UL << 17)
 
 /* DTrace trap opcode. */
-#define EXC_DTRACE     0x7c810808
+#define EXC_DTRACE     0x7ffff808
 
 /* Magic pointer to store TOC base and other info for trap handlers on ppc64 */
 #define TRAP_GENTRAP   0x1f0
_______________________________________________
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