aboutsummaryrefslogtreecommitdiff
path: root/sys/cddl/dev
diff options
context:
space:
mode:
authorMitchell Horne <mhorne@FreeBSD.org>2023-01-11 18:06:02 +0000
committerMitchell Horne <mhorne@FreeBSD.org>2023-01-12 15:04:58 +0000
commitcdfa49f2584ac174648ced04d76a47ad6773f2f0 (patch)
tree8a6407373d82f4109749028a97c0a4489a686dc5 /sys/cddl/dev
parent756a67e15e01d06e6ceda551dff3e0356c624187 (diff)
Diffstat (limited to 'sys/cddl/dev')
-rw-r--r--sys/cddl/dev/dtrace/riscv/dtrace_isa.c32
-rw-r--r--sys/cddl/dev/fbt/riscv/fbt_isa.c2
2 files changed, 21 insertions, 13 deletions
diff --git a/sys/cddl/dev/dtrace/riscv/dtrace_isa.c b/sys/cddl/dev/dtrace/riscv/dtrace_isa.c
index 1f585aa6fa3c..bc8426a752df 100644
--- a/sys/cddl/dev/dtrace/riscv/dtrace_isa.c
+++ b/sys/cddl/dev/dtrace/riscv/dtrace_isa.c
@@ -64,42 +64,50 @@ dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes,
uint32_t *intrpc)
{
struct unwind_state state;
- int scp_offset;
+ uintptr_t caller;
register_t sp;
+ int scp_offset;
int depth;
depth = 0;
+ caller = solaris_cpu[curcpu].cpu_dtrace_caller;
if (intrpc != 0) {
- pcstack[depth++] = (pc_t) intrpc;
+ pcstack[depth++] = (pc_t)intrpc;
}
- aframes++;
-
+ /*
+ * Construct the unwind state, starting from this function. This frame,
+ * and 'aframes' others will be skipped.
+ */
__asm __volatile("mv %0, sp" : "=&r" (sp));
state.fp = (uintptr_t)__builtin_frame_address(0);
- state.sp = sp;
+ state.sp = (uintptr_t)sp;
state.pc = (uintptr_t)dtrace_getpcstack;
while (depth < pcstack_limit) {
if (!unwind_frame(curthread, &state))
break;
- if (!INKERNEL(state.pc) || !INKERNEL(state.fp))
+ if (!INKERNEL(state.pc) || !kstack_contains(curthread,
+ (vm_offset_t)state.fp, sizeof(uintptr_t)))
break;
- /*
- * NB: Unlike some other architectures, we don't need to
- * explicitly insert cpu_dtrace_caller as it appears in the
- * normal kernel stack trace rather than a special trap frame.
- */
if (aframes > 0) {
aframes--;
+
+ /*
+ * fbt_invop() records the return address at the time
+ * the FBT probe fires. We need to insert this into the
+ * backtrace manually, since the stack frame state at
+ * the time of the probe does not capture it.
+ */
+ if (aframes == 0 && caller != 0)
+ pcstack[depth++] = caller;
} else {
pcstack[depth++] = state.pc;
}
-
}
for (; depth < pcstack_limit; depth++) {
diff --git a/sys/cddl/dev/fbt/riscv/fbt_isa.c b/sys/cddl/dev/fbt/riscv/fbt_isa.c
index 659a9d44c81c..a67e83811d9e 100644
--- a/sys/cddl/dev/fbt/riscv/fbt_isa.c
+++ b/sys/cddl/dev/fbt/riscv/fbt_isa.c
@@ -57,7 +57,7 @@ fbt_invop(uintptr_t addr, struct trapframe *frame, uintptr_t rval)
for (; fbt != NULL; fbt = fbt->fbtp_hashnext) {
if ((uintptr_t)fbt->fbtp_patchpoint == addr) {
- cpu->cpu_dtrace_caller = addr;
+ cpu->cpu_dtrace_caller = frame->tf_ra - INSN_SIZE;
if (fbt->fbtp_roffset == 0) {
dtrace_probe(fbt->fbtp_id, frame->tf_a[0],