parisc: Switch to ARCH_STACKWALK implementation
authorHelge Deller <deller@gmx.de>
Tue, 4 May 2021 12:49:14 +0000 (14:49 +0200)
committerHelge Deller <deller@gmx.de>
Sat, 30 Oct 2021 21:11:00 +0000 (23:11 +0200)
It's shorter and kfence currently depends on this stack unwinding
implementation.

Signed-off-by: Helge Deller <deller@gmx.de>
arch/parisc/Kconfig
arch/parisc/kernel/stacktrace.c

index 27a8b49..aee25be 100644 (file)
@@ -13,6 +13,8 @@ config PARISC
        select ARCH_NO_SG_CHAIN
        select ARCH_SUPPORTS_HUGETLBFS if PA20
        select ARCH_SUPPORTS_MEMORY_FAILURE
+       select ARCH_STACKWALK
+       select HAVE_RELIABLE_STACKTRACE
        select DMA_OPS
        select RTC_CLASS
        select RTC_DRV_GENERIC
index 34bf6d6..6b4ca91 100644 (file)
@@ -2,45 +2,41 @@
 /*
  * Stack trace management functions
  *
- *  Copyright (C) 2009 Helge Deller <deller@gmx.de>
+ *  Copyright (C) 2009-2021 Helge Deller <deller@gmx.de>
  *  based on arch/x86/kernel/stacktrace.c by Ingo Molnar <mingo@redhat.com>
  *  and parisc unwind functions by Randolph Chung <tausq@debian.org>
  *
  *  TODO: Userspace stacktrace (CONFIG_USER_STACKTRACE_SUPPORT)
  */
-#include <linux/module.h>
 #include <linux/stacktrace.h>
 
 #include <asm/unwind.h>
 
-static void dump_trace(struct task_struct *task, struct stack_trace *trace)
+static void notrace walk_stackframe(struct task_struct *task,
+       struct pt_regs *regs, bool (*fn)(void *, unsigned long), void *cookie)
 {
        struct unwind_frame_info info;
 
        unwind_frame_init_task(&info, task, NULL);
-
-       /* unwind stack and save entries in stack_trace struct */
-       trace->nr_entries = 0;
-       while (trace->nr_entries < trace->max_entries) {
+       while (1) {
                if (unwind_once(&info) < 0 || info.ip == 0)
                        break;
 
                if (__kernel_text_address(info.ip))
-                       trace->entries[trace->nr_entries++] = info.ip;
+                       if (!fn(cookie, info.ip))
+                               break;
        }
 }
 
-/*
- * Save stack-backtrace addresses into a stack_trace buffer.
- */
-void save_stack_trace(struct stack_trace *trace)
+void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
+                    struct task_struct *task, struct pt_regs *regs)
 {
-       dump_trace(current, trace);
+       walk_stackframe(task, regs, consume_entry, cookie);
 }
-EXPORT_SYMBOL_GPL(save_stack_trace);
 
-void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
+int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry, void *cookie,
+                            struct task_struct *task)
 {
-       dump_trace(tsk, trace);
+       walk_stackframe(task, NULL, consume_entry, cookie);
+       return 1;
 }
-EXPORT_SYMBOL_GPL(save_stack_trace_tsk);