1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright (C) 1991, 1992 Linus Torvalds |
4 | * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs |
5 | */ |
6 | #include <linux/sched/debug.h> |
7 | #include <linux/kallsyms.h> |
8 | #include <linux/kprobes.h> |
9 | #include <linux/uaccess.h> |
10 | #include <linux/hardirq.h> |
11 | #include <linux/kdebug.h> |
12 | #include <linux/export.h> |
13 | #include <linux/ptrace.h> |
14 | #include <linux/kexec.h> |
15 | #include <linux/sysfs.h> |
16 | #include <linux/bug.h> |
17 | #include <linux/nmi.h> |
18 | |
19 | #include <asm/cpu_entry_area.h> |
20 | #include <asm/stacktrace.h> |
21 | |
22 | static const char * const exception_stack_names[] = { |
23 | [ ESTACK_DF ] = "#DF" , |
24 | [ ESTACK_NMI ] = "NMI" , |
25 | [ ESTACK_DB ] = "#DB" , |
26 | [ ESTACK_MCE ] = "#MC" , |
27 | [ ESTACK_VC ] = "#VC" , |
28 | [ ESTACK_VC2 ] = "#VC2" , |
29 | }; |
30 | |
31 | const char *stack_type_name(enum stack_type type) |
32 | { |
33 | BUILD_BUG_ON(N_EXCEPTION_STACKS != 6); |
34 | |
35 | if (type == STACK_TYPE_TASK) |
36 | return "TASK" ; |
37 | |
38 | if (type == STACK_TYPE_IRQ) |
39 | return "IRQ" ; |
40 | |
41 | if (type == STACK_TYPE_SOFTIRQ) |
42 | return "SOFTIRQ" ; |
43 | |
44 | if (type == STACK_TYPE_ENTRY) { |
45 | /* |
46 | * On 64-bit, we have a generic entry stack that we |
47 | * use for all the kernel entry points, including |
48 | * SYSENTER. |
49 | */ |
50 | return "ENTRY_TRAMPOLINE" ; |
51 | } |
52 | |
53 | if (type >= STACK_TYPE_EXCEPTION && type <= STACK_TYPE_EXCEPTION_LAST) |
54 | return exception_stack_names[type - STACK_TYPE_EXCEPTION]; |
55 | |
56 | return NULL; |
57 | } |
58 | |
59 | /** |
60 | * struct estack_pages - Page descriptor for exception stacks |
61 | * @offs: Offset from the start of the exception stack area |
62 | * @size: Size of the exception stack |
63 | * @type: Type to store in the stack_info struct |
64 | */ |
65 | struct estack_pages { |
66 | u32 offs; |
67 | u16 size; |
68 | u16 type; |
69 | }; |
70 | |
71 | #define (st) \ |
72 | [PFN_DOWN(CEA_ESTACK_OFFS(st)) ... \ |
73 | PFN_DOWN(CEA_ESTACK_OFFS(st) + CEA_ESTACK_SIZE(st) - 1)] = { \ |
74 | .offs = CEA_ESTACK_OFFS(st), \ |
75 | .size = CEA_ESTACK_SIZE(st), \ |
76 | .type = STACK_TYPE_EXCEPTION + ESTACK_ ##st, } |
77 | |
78 | /* |
79 | * Array of exception stack page descriptors. If the stack is larger than |
80 | * PAGE_SIZE, all pages covering a particular stack will have the same |
81 | * info. The guard pages including the not mapped DB2 stack are zeroed |
82 | * out. |
83 | */ |
84 | static const |
85 | struct estack_pages estack_pages[CEA_ESTACK_PAGES] ____cacheline_aligned = { |
86 | EPAGERANGE(DF), |
87 | EPAGERANGE(NMI), |
88 | EPAGERANGE(DB), |
89 | EPAGERANGE(MCE), |
90 | EPAGERANGE(VC), |
91 | EPAGERANGE(VC2), |
92 | }; |
93 | |
94 | static __always_inline bool in_exception_stack(unsigned long *stack, struct stack_info *info) |
95 | { |
96 | unsigned long begin, end, stk = (unsigned long)stack; |
97 | const struct estack_pages *ep; |
98 | struct pt_regs *regs; |
99 | unsigned int k; |
100 | |
101 | BUILD_BUG_ON(N_EXCEPTION_STACKS != 6); |
102 | |
103 | begin = (unsigned long)__this_cpu_read(cea_exception_stacks); |
104 | /* |
105 | * Handle the case where stack trace is collected _before_ |
106 | * cea_exception_stacks had been initialized. |
107 | */ |
108 | if (!begin) |
109 | return false; |
110 | |
111 | end = begin + sizeof(struct cea_exception_stacks); |
112 | /* Bail if @stack is outside the exception stack area. */ |
113 | if (stk < begin || stk >= end) |
114 | return false; |
115 | |
116 | /* Calc page offset from start of exception stacks */ |
117 | k = (stk - begin) >> PAGE_SHIFT; |
118 | /* Lookup the page descriptor */ |
119 | ep = &estack_pages[k]; |
120 | /* Guard page? */ |
121 | if (!ep->size) |
122 | return false; |
123 | |
124 | begin += (unsigned long)ep->offs; |
125 | end = begin + (unsigned long)ep->size; |
126 | regs = (struct pt_regs *)end - 1; |
127 | |
128 | info->type = ep->type; |
129 | info->begin = (unsigned long *)begin; |
130 | info->end = (unsigned long *)end; |
131 | info->next_sp = (unsigned long *)regs->sp; |
132 | return true; |
133 | } |
134 | |
135 | static __always_inline bool in_irq_stack(unsigned long *stack, struct stack_info *info) |
136 | { |
137 | unsigned long *end = (unsigned long *)this_cpu_read(pcpu_hot.hardirq_stack_ptr); |
138 | unsigned long *begin; |
139 | |
140 | /* |
141 | * @end points directly to the top most stack entry to avoid a -8 |
142 | * adjustment in the stack switch hotpath. Adjust it back before |
143 | * calculating @begin. |
144 | */ |
145 | end++; |
146 | begin = end - (IRQ_STACK_SIZE / sizeof(long)); |
147 | |
148 | /* |
149 | * Due to the switching logic RSP can never be == @end because the |
150 | * final operation is 'popq %rsp' which means after that RSP points |
151 | * to the original stack and not to @end. |
152 | */ |
153 | if (stack < begin || stack >= end) |
154 | return false; |
155 | |
156 | info->type = STACK_TYPE_IRQ; |
157 | info->begin = begin; |
158 | info->end = end; |
159 | |
160 | /* |
161 | * The next stack pointer is stored at the top of the irq stack |
162 | * before switching to the irq stack. Actual stack entries are all |
163 | * below that. |
164 | */ |
165 | info->next_sp = (unsigned long *)*(end - 1); |
166 | |
167 | return true; |
168 | } |
169 | |
170 | bool noinstr get_stack_info_noinstr(unsigned long *stack, struct task_struct *task, |
171 | struct stack_info *info) |
172 | { |
173 | if (in_task_stack(stack, task, info)) |
174 | return true; |
175 | |
176 | if (task != current) |
177 | return false; |
178 | |
179 | if (in_exception_stack(stack, info)) |
180 | return true; |
181 | |
182 | if (in_irq_stack(stack, info)) |
183 | return true; |
184 | |
185 | if (in_entry_stack(stack, info)) |
186 | return true; |
187 | |
188 | return false; |
189 | } |
190 | |
191 | int get_stack_info(unsigned long *stack, struct task_struct *task, |
192 | struct stack_info *info, unsigned long *visit_mask) |
193 | { |
194 | task = task ? : current; |
195 | |
196 | if (!stack) |
197 | goto unknown; |
198 | |
199 | if (!get_stack_info_noinstr(stack, task, info)) |
200 | goto unknown; |
201 | |
202 | /* |
203 | * Make sure we don't iterate through any given stack more than once. |
204 | * If it comes up a second time then there's something wrong going on: |
205 | * just break out and report an unknown stack type. |
206 | */ |
207 | if (visit_mask) { |
208 | if (*visit_mask & (1UL << info->type)) { |
209 | if (task == current) |
210 | printk_deferred_once(KERN_WARNING "WARNING: stack recursion on stack type %d\n" , info->type); |
211 | goto unknown; |
212 | } |
213 | *visit_mask |= 1UL << info->type; |
214 | } |
215 | |
216 | return 0; |
217 | |
218 | unknown: |
219 | info->type = STACK_TYPE_UNKNOWN; |
220 | return -EINVAL; |
221 | } |
222 | |