hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/kernel/stacktrace.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * kernel/stacktrace.c
34 *
....@@ -5,41 +6,56 @@
56 *
67 * Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
78 */
9
+#include <linux/sched/task_stack.h>
10
+#include <linux/sched/debug.h>
811 #include <linux/sched.h>
912 #include <linux/kernel.h>
1013 #include <linux/export.h>
1114 #include <linux/kallsyms.h>
1215 #include <linux/stacktrace.h>
1316
14
-void print_stack_trace(struct stack_trace *trace, int spaces)
17
+/**
18
+ * stack_trace_print - Print the entries in the stack trace
19
+ * @entries: Pointer to storage array
20
+ * @nr_entries: Number of entries in the storage array
21
+ * @spaces: Number of leading spaces to print
22
+ */
23
+void stack_trace_print(const unsigned long *entries, unsigned int nr_entries,
24
+ int spaces)
1525 {
16
- int i;
26
+ unsigned int i;
1727
18
- if (WARN_ON(!trace->entries))
28
+ if (WARN_ON(!entries))
1929 return;
2030
21
- for (i = 0; i < trace->nr_entries; i++)
22
- printk("%*c%pS\n", 1 + spaces, ' ', (void *)trace->entries[i]);
31
+ for (i = 0; i < nr_entries; i++)
32
+ printk("%*c%pS\n", 1 + spaces, ' ', (void *)entries[i]);
2333 }
24
-EXPORT_SYMBOL_GPL(print_stack_trace);
34
+EXPORT_SYMBOL_GPL(stack_trace_print);
2535
26
-int snprint_stack_trace(char *buf, size_t size,
27
- struct stack_trace *trace, int spaces)
36
+/**
37
+ * stack_trace_snprint - Print the entries in the stack trace into a buffer
38
+ * @buf: Pointer to the print buffer
39
+ * @size: Size of the print buffer
40
+ * @entries: Pointer to storage array
41
+ * @nr_entries: Number of entries in the storage array
42
+ * @spaces: Number of leading spaces to print
43
+ *
44
+ * Return: Number of bytes printed.
45
+ */
46
+int stack_trace_snprint(char *buf, size_t size, const unsigned long *entries,
47
+ unsigned int nr_entries, int spaces)
2848 {
29
- int i;
30
- int generated;
31
- int total = 0;
49
+ unsigned int generated, i, total = 0;
3250
33
- if (WARN_ON(!trace->entries))
51
+ if (WARN_ON(!entries))
3452 return 0;
3553
36
- for (i = 0; i < trace->nr_entries; i++) {
54
+ for (i = 0; i < nr_entries && size; i++) {
3755 generated = snprintf(buf, size, "%*c%pS\n", 1 + spaces, ' ',
38
- (void *)trace->entries[i]);
56
+ (void *)entries[i]);
3957
4058 total += generated;
41
-
42
- /* Assume that generated isn't a negative number */
4359 if (generated >= size) {
4460 buf += size;
4561 size = 0;
....@@ -51,7 +67,181 @@
5167
5268 return total;
5369 }
54
-EXPORT_SYMBOL_GPL(snprint_stack_trace);
70
+EXPORT_SYMBOL_GPL(stack_trace_snprint);
71
+
72
+#ifdef CONFIG_ARCH_STACKWALK
73
+
74
+struct stacktrace_cookie {
75
+ unsigned long *store;
76
+ unsigned int size;
77
+ unsigned int skip;
78
+ unsigned int len;
79
+};
80
+
81
+static bool stack_trace_consume_entry(void *cookie, unsigned long addr)
82
+{
83
+ struct stacktrace_cookie *c = cookie;
84
+
85
+ if (c->len >= c->size)
86
+ return false;
87
+
88
+ if (c->skip > 0) {
89
+ c->skip--;
90
+ return true;
91
+ }
92
+ c->store[c->len++] = addr;
93
+ return c->len < c->size;
94
+}
95
+
96
+static bool stack_trace_consume_entry_nosched(void *cookie, unsigned long addr)
97
+{
98
+ if (in_sched_functions(addr))
99
+ return true;
100
+ return stack_trace_consume_entry(cookie, addr);
101
+}
102
+
103
+/**
104
+ * stack_trace_save - Save a stack trace into a storage array
105
+ * @store: Pointer to storage array
106
+ * @size: Size of the storage array
107
+ * @skipnr: Number of entries to skip at the start of the stack trace
108
+ *
109
+ * Return: Number of trace entries stored.
110
+ */
111
+unsigned int stack_trace_save(unsigned long *store, unsigned int size,
112
+ unsigned int skipnr)
113
+{
114
+ stack_trace_consume_fn consume_entry = stack_trace_consume_entry;
115
+ struct stacktrace_cookie c = {
116
+ .store = store,
117
+ .size = size,
118
+ .skip = skipnr + 1,
119
+ };
120
+
121
+ arch_stack_walk(consume_entry, &c, current, NULL);
122
+ return c.len;
123
+}
124
+EXPORT_SYMBOL_GPL(stack_trace_save);
125
+
126
+/**
127
+ * stack_trace_save_tsk - Save a task stack trace into a storage array
128
+ * @task: The task to examine
129
+ * @store: Pointer to storage array
130
+ * @size: Size of the storage array
131
+ * @skipnr: Number of entries to skip at the start of the stack trace
132
+ *
133
+ * Return: Number of trace entries stored.
134
+ */
135
+unsigned int stack_trace_save_tsk(struct task_struct *tsk, unsigned long *store,
136
+ unsigned int size, unsigned int skipnr)
137
+{
138
+ stack_trace_consume_fn consume_entry = stack_trace_consume_entry_nosched;
139
+ struct stacktrace_cookie c = {
140
+ .store = store,
141
+ .size = size,
142
+ /* skip this function if they are tracing us */
143
+ .skip = skipnr + (current == tsk),
144
+ };
145
+
146
+ if (!try_get_task_stack(tsk))
147
+ return 0;
148
+
149
+ arch_stack_walk(consume_entry, &c, tsk, NULL);
150
+ put_task_stack(tsk);
151
+ return c.len;
152
+}
153
+EXPORT_SYMBOL_GPL(stack_trace_save_tsk);
154
+
155
+/**
156
+ * stack_trace_save_regs - Save a stack trace based on pt_regs into a storage array
157
+ * @regs: Pointer to pt_regs to examine
158
+ * @store: Pointer to storage array
159
+ * @size: Size of the storage array
160
+ * @skipnr: Number of entries to skip at the start of the stack trace
161
+ *
162
+ * Return: Number of trace entries stored.
163
+ */
164
+unsigned int stack_trace_save_regs(struct pt_regs *regs, unsigned long *store,
165
+ unsigned int size, unsigned int skipnr)
166
+{
167
+ stack_trace_consume_fn consume_entry = stack_trace_consume_entry;
168
+ struct stacktrace_cookie c = {
169
+ .store = store,
170
+ .size = size,
171
+ .skip = skipnr,
172
+ };
173
+
174
+ arch_stack_walk(consume_entry, &c, current, regs);
175
+ return c.len;
176
+}
177
+EXPORT_SYMBOL_GPL(stack_trace_save_regs);
178
+
179
+#ifdef CONFIG_HAVE_RELIABLE_STACKTRACE
180
+/**
181
+ * stack_trace_save_tsk_reliable - Save task stack with verification
182
+ * @tsk: Pointer to the task to examine
183
+ * @store: Pointer to storage array
184
+ * @size: Size of the storage array
185
+ *
186
+ * Return: An error if it detects any unreliable features of the
187
+ * stack. Otherwise it guarantees that the stack trace is
188
+ * reliable and returns the number of entries stored.
189
+ *
190
+ * If the task is not 'current', the caller *must* ensure the task is inactive.
191
+ */
192
+int stack_trace_save_tsk_reliable(struct task_struct *tsk, unsigned long *store,
193
+ unsigned int size)
194
+{
195
+ stack_trace_consume_fn consume_entry = stack_trace_consume_entry;
196
+ struct stacktrace_cookie c = {
197
+ .store = store,
198
+ .size = size,
199
+ };
200
+ int ret;
201
+
202
+ /*
203
+ * If the task doesn't have a stack (e.g., a zombie), the stack is
204
+ * "reliably" empty.
205
+ */
206
+ if (!try_get_task_stack(tsk))
207
+ return 0;
208
+
209
+ ret = arch_stack_walk_reliable(consume_entry, &c, tsk);
210
+ put_task_stack(tsk);
211
+ return ret ? ret : c.len;
212
+}
213
+#endif
214
+
215
+#ifdef CONFIG_USER_STACKTRACE_SUPPORT
216
+/**
217
+ * stack_trace_save_user - Save a user space stack trace into a storage array
218
+ * @store: Pointer to storage array
219
+ * @size: Size of the storage array
220
+ *
221
+ * Return: Number of trace entries stored.
222
+ */
223
+unsigned int stack_trace_save_user(unsigned long *store, unsigned int size)
224
+{
225
+ stack_trace_consume_fn consume_entry = stack_trace_consume_entry;
226
+ struct stacktrace_cookie c = {
227
+ .store = store,
228
+ .size = size,
229
+ };
230
+ mm_segment_t fs;
231
+
232
+ /* Trace user stack if not a kernel thread */
233
+ if (current->flags & PF_KTHREAD)
234
+ return 0;
235
+
236
+ fs = force_uaccess_begin();
237
+ arch_stack_walk_user(consume_entry, &c, task_pt_regs(current));
238
+ force_uaccess_end(fs);
239
+
240
+ return c.len;
241
+}
242
+#endif
243
+
244
+#else /* CONFIG_ARCH_STACKWALK */
55245
56246 /*
57247 * Architectures that do not implement save_stack_trace_*()
....@@ -70,10 +260,118 @@
70260 WARN_ONCE(1, KERN_INFO "save_stack_trace_regs() not implemented yet.\n");
71261 }
72262
73
-__weak int
74
-save_stack_trace_tsk_reliable(struct task_struct *tsk,
75
- struct stack_trace *trace)
263
+/**
264
+ * stack_trace_save - Save a stack trace into a storage array
265
+ * @store: Pointer to storage array
266
+ * @size: Size of the storage array
267
+ * @skipnr: Number of entries to skip at the start of the stack trace
268
+ *
269
+ * Return: Number of trace entries stored
270
+ */
271
+unsigned int stack_trace_save(unsigned long *store, unsigned int size,
272
+ unsigned int skipnr)
76273 {
77
- WARN_ONCE(1, KERN_INFO "save_stack_tsk_reliable() not implemented yet.\n");
78
- return -ENOSYS;
274
+ struct stack_trace trace = {
275
+ .entries = store,
276
+ .max_entries = size,
277
+ .skip = skipnr + 1,
278
+ };
279
+
280
+ save_stack_trace(&trace);
281
+ return trace.nr_entries;
79282 }
283
+EXPORT_SYMBOL_GPL(stack_trace_save);
284
+
285
+/**
286
+ * stack_trace_save_tsk - Save a task stack trace into a storage array
287
+ * @task: The task to examine
288
+ * @store: Pointer to storage array
289
+ * @size: Size of the storage array
290
+ * @skipnr: Number of entries to skip at the start of the stack trace
291
+ *
292
+ * Return: Number of trace entries stored
293
+ */
294
+unsigned int stack_trace_save_tsk(struct task_struct *task,
295
+ unsigned long *store, unsigned int size,
296
+ unsigned int skipnr)
297
+{
298
+ struct stack_trace trace = {
299
+ .entries = store,
300
+ .max_entries = size,
301
+ /* skip this function if they are tracing us */
302
+ .skip = skipnr + (current == task),
303
+ };
304
+
305
+ save_stack_trace_tsk(task, &trace);
306
+ return trace.nr_entries;
307
+}
308
+
309
+/**
310
+ * stack_trace_save_regs - Save a stack trace based on pt_regs into a storage array
311
+ * @regs: Pointer to pt_regs to examine
312
+ * @store: Pointer to storage array
313
+ * @size: Size of the storage array
314
+ * @skipnr: Number of entries to skip at the start of the stack trace
315
+ *
316
+ * Return: Number of trace entries stored
317
+ */
318
+unsigned int stack_trace_save_regs(struct pt_regs *regs, unsigned long *store,
319
+ unsigned int size, unsigned int skipnr)
320
+{
321
+ struct stack_trace trace = {
322
+ .entries = store,
323
+ .max_entries = size,
324
+ .skip = skipnr,
325
+ };
326
+
327
+ save_stack_trace_regs(regs, &trace);
328
+ return trace.nr_entries;
329
+}
330
+
331
+#ifdef CONFIG_HAVE_RELIABLE_STACKTRACE
332
+/**
333
+ * stack_trace_save_tsk_reliable - Save task stack with verification
334
+ * @tsk: Pointer to the task to examine
335
+ * @store: Pointer to storage array
336
+ * @size: Size of the storage array
337
+ *
338
+ * Return: An error if it detects any unreliable features of the
339
+ * stack. Otherwise it guarantees that the stack trace is
340
+ * reliable and returns the number of entries stored.
341
+ *
342
+ * If the task is not 'current', the caller *must* ensure the task is inactive.
343
+ */
344
+int stack_trace_save_tsk_reliable(struct task_struct *tsk, unsigned long *store,
345
+ unsigned int size)
346
+{
347
+ struct stack_trace trace = {
348
+ .entries = store,
349
+ .max_entries = size,
350
+ };
351
+ int ret = save_stack_trace_tsk_reliable(tsk, &trace);
352
+
353
+ return ret ? ret : trace.nr_entries;
354
+}
355
+#endif
356
+
357
+#ifdef CONFIG_USER_STACKTRACE_SUPPORT
358
+/**
359
+ * stack_trace_save_user - Save a user space stack trace into a storage array
360
+ * @store: Pointer to storage array
361
+ * @size: Size of the storage array
362
+ *
363
+ * Return: Number of trace entries stored
364
+ */
365
+unsigned int stack_trace_save_user(unsigned long *store, unsigned int size)
366
+{
367
+ struct stack_trace trace = {
368
+ .entries = store,
369
+ .max_entries = size,
370
+ };
371
+
372
+ save_stack_trace_user(&trace);
373
+ return trace.nr_entries;
374
+}
375
+#endif /* CONFIG_USER_STACKTRACE_SUPPORT */
376
+
377
+#endif /* !CONFIG_ARCH_STACKWALK */