On Wed Feb 28, 2024 at 9:46 PM AEST, Andrew Jones wrote: > On Mon, Feb 26, 2024 at 08:11:50PM +1000, Nicholas Piggin wrote: > > Add support for backtracing across interrupt stacks, and > > add interrupt frame backtrace for unhandled interrupts. > > > > Signed-off-by: Nicholas Piggin <npiggin@xxxxxxxxx> > > --- > > lib/powerpc/processor.c | 4 ++- > > lib/ppc64/asm/stack.h | 3 +++ > > lib/ppc64/stack.c | 55 +++++++++++++++++++++++++++++++++++++++++ > > powerpc/Makefile.ppc64 | 1 + > > powerpc/cstart64.S | 7 ++++-- > > 5 files changed, 67 insertions(+), 3 deletions(-) > > create mode 100644 lib/ppc64/stack.c > > > > diff --git a/lib/powerpc/processor.c b/lib/powerpc/processor.c > > index ad0d95666..114584024 100644 > > --- a/lib/powerpc/processor.c > > +++ b/lib/powerpc/processor.c > > @@ -51,7 +51,9 @@ void do_handle_exception(struct pt_regs *regs) > > return; > > } > > > > - printf("unhandled cpu exception %#lx at NIA:0x%016lx MSR:0x%016lx\n", regs->trap, regs->nip, regs->msr); > > + printf("Unhandled cpu exception %#lx at NIA:0x%016lx MSR:0x%016lx\n", > > + regs->trap, regs->nip, regs->msr); > > + dump_frame_stack((void *)regs->nip, (void *)regs->gpr[1]); > > abort(); > > } > > > > diff --git a/lib/ppc64/asm/stack.h b/lib/ppc64/asm/stack.h > > index 9734bbb8f..94fd1021c 100644 > > --- a/lib/ppc64/asm/stack.h > > +++ b/lib/ppc64/asm/stack.h > > @@ -5,4 +5,7 @@ > > #error Do not directly include <asm/stack.h>. Just use <stack.h>. > > #endif > > > > +#define HAVE_ARCH_BACKTRACE > > +#define HAVE_ARCH_BACKTRACE_FRAME > > + > > #endif > > diff --git a/lib/ppc64/stack.c b/lib/ppc64/stack.c > > new file mode 100644 > > index 000000000..fcb7fa860 > > --- /dev/null > > +++ b/lib/ppc64/stack.c > > @@ -0,0 +1,55 @@ > > +#include <libcflat.h> > > +#include <asm/ptrace.h> > > +#include <stack.h> > > + > > +extern char exception_stack_marker[]; > > + > > +int backtrace_frame(const void *frame, const void **return_addrs, int max_depth) > > +{ > > + static int walking; > > + int depth = 0; > > + const unsigned long *bp = (unsigned long *)frame; > > + void *return_addr; > > + > > + asm volatile("" ::: "lr"); /* Force it to save LR */ > > + > > + if (walking) { > > + printf("RECURSIVE STACK WALK!!!\n"); > > + return 0; > > + } > > + walking = 1; > > + > > + bp = (unsigned long *)bp[0]; > > + return_addr = (void *)bp[2]; > > + > > + for (depth = 0; bp && depth < max_depth; depth++) { > > + return_addrs[depth] = return_addr; > > + if (return_addrs[depth] == 0) > > + break; > > + if (return_addrs[depth] == exception_stack_marker) { > > + struct pt_regs *regs; > > + > > + regs = (void *)bp + STACK_FRAME_OVERHEAD; > > + bp = (unsigned long *)bp[0]; > > + /* Represent interrupt frame with vector number */ > > + return_addr = (void *)regs->trap; > > + if (depth + 1 < max_depth) { > > + depth++; > > + return_addrs[depth] = return_addr; > > + return_addr = (void *)regs->nip; > > + } > > + } else { > > + bp = (unsigned long *)bp[0]; > > + return_addr = (void *)bp[2]; > > + } > > + } > > + > > + walking = 0; > > + return depth; > > +} > > + > > +int backtrace(const void **return_addrs, int max_depth) > > +{ > > + return backtrace_frame(__builtin_frame_address(0), return_addrs, > > + max_depth); > > +} > > I'm about to post a series which has a couple treewide tracing changes > in them. Depending on which series goes first the other will need to > accommodate. Yeah that's fine. Thanks, Nick