1457c8996SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2548f1176SHelge Deller /*
3548f1176SHelge Deller * Stack trace management functions
4548f1176SHelge Deller *
5aeb1e833SHelge Deller * Copyright (C) 2009-2021 Helge Deller <deller@gmx.de>
6548f1176SHelge Deller * based on arch/x86/kernel/stacktrace.c by Ingo Molnar <mingo@redhat.com>
7548f1176SHelge Deller * and parisc unwind functions by Randolph Chung <tausq@debian.org>
8548f1176SHelge Deller *
9548f1176SHelge Deller * TODO: Userspace stacktrace (CONFIG_USER_STACKTRACE_SUPPORT)
10548f1176SHelge Deller */
11*f0d1cfacSHelge Deller #include <linux/kernel.h>
12548f1176SHelge Deller #include <linux/stacktrace.h>
13548f1176SHelge Deller
14548f1176SHelge Deller #include <asm/unwind.h>
15548f1176SHelge Deller
walk_stackframe(struct task_struct * task,struct pt_regs * regs,bool (* fn)(void *,unsigned long),void * cookie)16aeb1e833SHelge Deller static void notrace walk_stackframe(struct task_struct *task,
17aeb1e833SHelge Deller struct pt_regs *regs, bool (*fn)(void *, unsigned long), void *cookie)
18548f1176SHelge Deller {
19548f1176SHelge Deller struct unwind_frame_info info;
20548f1176SHelge Deller
219e0d5c45SHelge Deller unwind_frame_init_task(&info, task, NULL);
22aeb1e833SHelge Deller while (1) {
23548f1176SHelge Deller if (unwind_once(&info) < 0 || info.ip == 0)
24548f1176SHelge Deller break;
25548f1176SHelge Deller
26548f1176SHelge Deller if (__kernel_text_address(info.ip))
27aeb1e833SHelge Deller if (!fn(cookie, info.ip))
28aeb1e833SHelge Deller break;
29548f1176SHelge Deller }
30548f1176SHelge Deller }
31548f1176SHelge Deller
arch_stack_walk(stack_trace_consume_fn consume_entry,void * cookie,struct task_struct * task,struct pt_regs * regs)32aeb1e833SHelge Deller void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
33aeb1e833SHelge Deller struct task_struct *task, struct pt_regs *regs)
34548f1176SHelge Deller {
35aeb1e833SHelge Deller walk_stackframe(task, regs, consume_entry, cookie);
36548f1176SHelge Deller }
37548f1176SHelge Deller
arch_stack_walk_reliable(stack_trace_consume_fn consume_entry,void * cookie,struct task_struct * task)38aeb1e833SHelge Deller int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry, void *cookie,
39aeb1e833SHelge Deller struct task_struct *task)
40548f1176SHelge Deller {
41aeb1e833SHelge Deller walk_stackframe(task, NULL, consume_entry, cookie);
42aeb1e833SHelge Deller return 1;
43548f1176SHelge Deller }
44