summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhibbits <jhibbits@FreeBSD.org>2017-05-20 05:12:32 +0000
committerjhibbits <jhibbits@FreeBSD.org>2017-05-20 05:12:32 +0000
commit78abf039aa297d9b0021f82c669f194c4bfc611e (patch)
tree79811f5b0629101641348734377be5eee7881ea6
parentf4f7900bc18788394c1004abc37d2fb303297e06 (diff)
downloadFreeBSD-src-78abf039aa297d9b0021f82c669f194c4bfc611e.zip
FreeBSD-src-78abf039aa297d9b0021f82c669f194c4bfc611e.tar.gz
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
-rw-r--r--sys/cddl/dev/dtrace/powerpc/dtrace_isa.c57
-rw-r--r--sys/cddl/dev/fbt/powerpc/fbt_isa.c2
-rw-r--r--sys/powerpc/booke/trap_subr.S12
-rw-r--r--sys/powerpc/include/trap.h2
4 files changed, 31 insertions, 42 deletions
diff --git a/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c b/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c
index 950e9ac..c6c72a3 100644
--- a/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c
+++ b/sys/cddl/dev/dtrace/powerpc/dtrace_isa.c
@@ -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 aframes)
/*
* 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 pcstack_limit, int aframes,
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)
diff --git a/sys/cddl/dev/fbt/powerpc/fbt_isa.c b/sys/cddl/dev/fbt/powerpc/fbt_isa.c
index e67e837..fa9b1d6 100644
--- a/sys/cddl/dev/fbt/powerpc/fbt_isa.c
+++ b/sys/cddl/dev/fbt/powerpc/fbt_isa.c
@@ -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
diff --git a/sys/powerpc/booke/trap_subr.S b/sys/powerpc/booke/trap_subr.S
index 8737dba..ebaa656 100644
--- a/sys/powerpc/booke/trap_subr.S
+++ b/sys/powerpc/booke/trap_subr.S
@@ -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
diff --git a/sys/powerpc/include/trap.h b/sys/powerpc/include/trap.h
index 81c40c9..07c70fa 100644
--- a/sys/powerpc/include/trap.h
+++ b/sys/powerpc/include/trap.h
@@ -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
OpenPOWER on IntegriCloud