xref: /openbmc/linux/arch/parisc/kernel/stacktrace.c (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
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