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