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