1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds * Provide a default dump_stack() function for architectures
41da177e4SLinus Torvalds * which don't implement their own.
51da177e4SLinus Torvalds */
61da177e4SLinus Torvalds
71da177e4SLinus Torvalds #include <linux/kernel.h>
822f4e66dSStephen Boyd #include <linux/buildid.h>
98bc3bcc9SPaul Gortmaker #include <linux/export.h>
10196779b9STejun Heo #include <linux/sched.h>
11b17b0153SIngo Molnar #include <linux/sched/debug.h>
12b58d9774SAlex Thorlton #include <linux/smp.h>
13b58d9774SAlex Thorlton #include <linux/atomic.h>
14e36df28fSDave Young #include <linux/kexec.h>
15e36df28fSDave Young #include <linux/utsname.h>
16a8b62fd0SPeter Zijlstra #include <linux/stop_machine.h>
17e36df28fSDave Young
18e36df28fSDave Young static char dump_stack_arch_desc_str[128];
19e36df28fSDave Young
20e36df28fSDave Young /**
21e36df28fSDave Young * dump_stack_set_arch_desc - set arch-specific str to show with task dumps
22e36df28fSDave Young * @fmt: printf-style format string
23e36df28fSDave Young * @...: arguments for the format string
24e36df28fSDave Young *
25e36df28fSDave Young * The configured string will be printed right after utsname during task
26e36df28fSDave Young * dumps. Usually used to add arch-specific system identifiers. If an
27e36df28fSDave Young * arch wants to make use of such an ID string, it should initialize this
28e36df28fSDave Young * as soon as possible during boot.
29e36df28fSDave Young */
dump_stack_set_arch_desc(const char * fmt,...)30e36df28fSDave Young void __init dump_stack_set_arch_desc(const char *fmt, ...)
31e36df28fSDave Young {
32e36df28fSDave Young va_list args;
33e36df28fSDave Young
34e36df28fSDave Young va_start(args, fmt);
35e36df28fSDave Young vsnprintf(dump_stack_arch_desc_str, sizeof(dump_stack_arch_desc_str),
36e36df28fSDave Young fmt, args);
37e36df28fSDave Young va_end(args);
38e36df28fSDave Young }
39e36df28fSDave Young
4022f4e66dSStephen Boyd #if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID)
4122f4e66dSStephen Boyd #define BUILD_ID_FMT " %20phN"
4222f4e66dSStephen Boyd #define BUILD_ID_VAL vmlinux_build_id
4322f4e66dSStephen Boyd #else
4422f4e66dSStephen Boyd #define BUILD_ID_FMT "%s"
4522f4e66dSStephen Boyd #define BUILD_ID_VAL ""
4622f4e66dSStephen Boyd #endif
4722f4e66dSStephen Boyd
48e36df28fSDave Young /**
49e36df28fSDave Young * dump_stack_print_info - print generic debug info for dump_stack()
50e36df28fSDave Young * @log_lvl: log level
51e36df28fSDave Young *
52e36df28fSDave Young * Arch-specific dump_stack() implementations can use this function to
53e36df28fSDave Young * print out the same debug information as the generic dump_stack().
54e36df28fSDave Young */
dump_stack_print_info(const char * log_lvl)55e36df28fSDave Young void dump_stack_print_info(const char *log_lvl)
56e36df28fSDave Young {
57*d167706fSSebastian Andrzej Siewior printk("%sCPU: %d UID: %u PID: %d Comm: %.20s %s%s %s %.*s %s " BUILD_ID_FMT "\n",
58d2917ff1SSuren Baghdasaryan log_lvl, raw_smp_processor_id(),
59d2917ff1SSuren Baghdasaryan __kuid_val(current_real_cred()->euid),
60d2917ff1SSuren Baghdasaryan current->pid, current->comm,
61e36df28fSDave Young kexec_crash_loaded() ? "Kdump: loaded " : "",
62e36df28fSDave Young print_tainted(),
63e36df28fSDave Young init_utsname()->release,
64e36df28fSDave Young (int)strcspn(init_utsname()->version, " "),
65*d167706fSSebastian Andrzej Siewior init_utsname()->version, preempt_model_str(), BUILD_ID_VAL);
66e36df28fSDave Young
672f183c68SJani Nikula if (get_taint())
682f183c68SJani Nikula printk("%s%s\n", log_lvl, print_tainted_verbose());
692f183c68SJani Nikula
70e36df28fSDave Young if (dump_stack_arch_desc_str[0] != '\0')
71e36df28fSDave Young printk("%sHardware name: %s\n",
72e36df28fSDave Young log_lvl, dump_stack_arch_desc_str);
73e36df28fSDave Young
74e36df28fSDave Young print_worker_info(log_lvl, current);
75a8b62fd0SPeter Zijlstra print_stop_info(log_lvl, current);
761538e339SDavid Vernet print_scx_info(log_lvl, current);
77e36df28fSDave Young }
78e36df28fSDave Young
79e36df28fSDave Young /**
80e36df28fSDave Young * show_regs_print_info - print generic debug info for show_regs()
81e36df28fSDave Young * @log_lvl: log level
82e36df28fSDave Young *
83e36df28fSDave Young * show_regs() implementations can use this function to print out generic
84e36df28fSDave Young * debug information.
85e36df28fSDave Young */
show_regs_print_info(const char * log_lvl)86e36df28fSDave Young void show_regs_print_info(const char *log_lvl)
87e36df28fSDave Young {
88e36df28fSDave Young dump_stack_print_info(log_lvl);
89e36df28fSDave Young }
90b58d9774SAlex Thorlton
__dump_stack(const char * log_lvl)914469c0f1SAlexander Potapenko static void __dump_stack(const char *log_lvl)
92b58d9774SAlex Thorlton {
934469c0f1SAlexander Potapenko dump_stack_print_info(log_lvl);
944469c0f1SAlexander Potapenko show_stack(NULL, NULL, log_lvl);
95b58d9774SAlex Thorlton }
961da177e4SLinus Torvalds
97196779b9STejun Heo /**
9883a29bebSRandy Dunlap * dump_stack_lvl - dump the current task information and its stack trace
9983a29bebSRandy Dunlap * @log_lvl: log level
100196779b9STejun Heo *
101196779b9STejun Heo * Architectures can override this implementation by implementing its own.
102196779b9STejun Heo */
dump_stack_lvl(const char * log_lvl)1034469c0f1SAlexander Potapenko asmlinkage __visible void dump_stack_lvl(const char *log_lvl)
1041da177e4SLinus Torvalds {
1057412dc6dSJohn Ogness bool in_panic = this_cpu_in_panic();
106d7ce3692SEric Dumazet unsigned long flags;
107b58d9774SAlex Thorlton
108b58d9774SAlex Thorlton /*
109b58d9774SAlex Thorlton * Permit this cpu to perform nested stack dumps while serialising
1107412dc6dSJohn Ogness * against other CPUs, unless this CPU is in panic.
1117412dc6dSJohn Ogness *
1127412dc6dSJohn Ogness * When in panic, non-panic CPUs are not permitted to store new
1137412dc6dSJohn Ogness * printk messages so there is no need to synchronize the output.
1147412dc6dSJohn Ogness * This avoids potential deadlock in panic() if another CPU is
1157412dc6dSJohn Ogness * holding and unable to release the printk_cpu_sync.
116b58d9774SAlex Thorlton */
1177412dc6dSJohn Ogness if (!in_panic)
118faebd693SJohn Ogness printk_cpu_sync_get_irqsave(flags);
1197412dc6dSJohn Ogness
1204469c0f1SAlexander Potapenko __dump_stack(log_lvl);
1217412dc6dSJohn Ogness
1227412dc6dSJohn Ogness if (!in_panic)
123faebd693SJohn Ogness printk_cpu_sync_put_irqrestore(flags);
124b58d9774SAlex Thorlton }
1254469c0f1SAlexander Potapenko EXPORT_SYMBOL(dump_stack_lvl);
1264469c0f1SAlexander Potapenko
dump_stack(void)1274469c0f1SAlexander Potapenko asmlinkage __visible void dump_stack(void)
1284469c0f1SAlexander Potapenko {
1294469c0f1SAlexander Potapenko dump_stack_lvl(KERN_DEFAULT);
1304469c0f1SAlexander Potapenko }
1311da177e4SLinus Torvalds EXPORT_SYMBOL(dump_stack);
132