svn commit: r349675 - stable/12/sys/cddl/dev/dtrace/powerpc

Justin Hibbits jhibbits at FreeBSD.org
Wed Jul 3 19:21:04 UTC 2019


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


More information about the svn-src-all mailing list