xref: /openbmc/linux/arch/s390/kernel/stacktrace.c (revision 34fa67e7)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Stack trace management functions
4  *
5  *  Copyright IBM Corp. 2006
6  *  Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
7  */
8 
9 #include <linux/stacktrace.h>
10 #include <asm/stacktrace.h>
11 #include <asm/unwind.h>
12 #include <asm/kprobes.h>
13 
14 void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
15 		     struct task_struct *task, struct pt_regs *regs)
16 {
17 	struct unwind_state state;
18 	unsigned long addr;
19 
20 	unwind_for_each_frame(&state, task, regs, 0) {
21 		addr = unwind_get_return_address(&state);
22 		if (!addr || !consume_entry(cookie, addr))
23 			break;
24 	}
25 }
26 
27 int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry,
28 			     void *cookie, struct task_struct *task)
29 {
30 	struct unwind_state state;
31 	unsigned long addr;
32 
33 	unwind_for_each_frame(&state, task, NULL, 0) {
34 		if (state.stack_info.type != STACK_TYPE_TASK)
35 			return -EINVAL;
36 
37 		if (state.regs)
38 			return -EINVAL;
39 
40 		addr = unwind_get_return_address(&state);
41 		if (!addr)
42 			return -EINVAL;
43 
44 #ifdef CONFIG_KPROBES
45 		/*
46 		 * Mark stacktraces with kretprobed functions on them
47 		 * as unreliable.
48 		 */
49 		if (state.ip == (unsigned long)__kretprobe_trampoline)
50 			return -EINVAL;
51 #endif
52 
53 		if (!consume_entry(cookie, addr))
54 			return -EINVAL;
55 	}
56 
57 	/* Check for stack corruption */
58 	if (unwind_error(&state))
59 		return -EINVAL;
60 	return 0;
61 }
62