Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 03 Sep 2019 14:06:48 -0000
From:      Justin Hibbits <jhibbits@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r346173 - head/sys/cddl/dev/dtrace/powerpc
Message-ID:  <201904130332.x3D3WLgC005780@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhibbits
Date: Sat Apr 13 03:32:21 2019
New Revision: 346173
URL: https://svnweb.freebsd.org/changeset/base/346173

Log:
  powerpc/dtrace: Fix dtrace powerpc asm, and simplify stack walking
  
  Fix some execution bugs in the dtrace powerpc asm.  addme pulls in the carry
  flag which we don't want, and the result wasn't recorded anyways, so the
  following beq to check for exit condition wasn't checking the right
  condition.
  
  Simplify the stack walking in dtrace_isa.c, so there's only a single walker
  that handles both pc and sp.  This should make it easier to follow, and any
  bugfix that may be needed for walking only needs to be made in one place
  instead of two now.
  
  MFC after:	2 weeks

Modified:
  head/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S
  head/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c

Modified: head/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S
==============================================================================
--- head/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S	Sat Apr 13 02:29:30 2019	(r346172)
+++ head/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S	Sat Apr 13 03:32:21 2019	(r346173)
@@ -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

Modified: head/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c
==============================================================================
--- head/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c	Sat Apr 13 02:29:30 2019	(r346172)
+++ head/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c	Sat Apr 13 03:32:21 2019	(r346173)
@@ -94,11 +94,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,39 +114,17 @@ 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 (callpc);
+	if (nsp != NULL)
+		*nsp = *(uintptr_t *)sp;
+	if (pc != NULL)
+		*pc = callpc;
 }
 
 greg_t
@@ -179,7 +156,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 +168,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++) {
@@ -546,7 +521,7 @@ dtrace_getstackdepth(int aframes)
 		else
 			aframes--;
 		osp = sp;
-		sp = dtrace_next_sp(sp);
+		dtrace_next_sp_pc(sp, &sp, NULL);
 	}
 	if (depth < aframes)
 		return (0);





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201904130332.x3D3WLgC005780>