Skip to content

Commit 9e0f085

Browse files
brooniewilldeacon
authored andcommitted
arm64: Move console stack display code to stacktrace.c
Currently the code for displaying a stack trace on the console is located in traps.c rather than stacktrace.c, using the unwinding code that is in stacktrace.c. This can be confusing and make the code hard to find since such output is often referred to as a stack trace which might mislead the unwary. Due to this and since traps.c doesn't interact with this code except for via the public interfaces move the code to stacktrace.c to make it easier to find. Signed-off-by: Mark Brown <broonie@kernel.org> Link: https://lore.kernel.org/r/20200921122341.11280-1-broonie@kernel.org Signed-off-by: Will Deacon <will@kernel.org>
1 parent 5fc57df commit 9e0f085

2 files changed

Lines changed: 65 additions & 65 deletions

File tree

arch/arm64/kernel/stacktrace.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,71 @@ void notrace walk_stackframe(struct task_struct *tsk, struct stackframe *frame,
132132
}
133133
NOKPROBE_SYMBOL(walk_stackframe);
134134

135+
static void dump_backtrace_entry(unsigned long where, const char *loglvl)
136+
{
137+
printk("%s %pS\n", loglvl, (void *)where);
138+
}
139+
140+
void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
141+
const char *loglvl)
142+
{
143+
struct stackframe frame;
144+
int skip = 0;
145+
146+
pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
147+
148+
if (regs) {
149+
if (user_mode(regs))
150+
return;
151+
skip = 1;
152+
}
153+
154+
if (!tsk)
155+
tsk = current;
156+
157+
if (!try_get_task_stack(tsk))
158+
return;
159+
160+
if (tsk == current) {
161+
start_backtrace(&frame,
162+
(unsigned long)__builtin_frame_address(0),
163+
(unsigned long)dump_backtrace);
164+
} else {
165+
/*
166+
* task blocked in __switch_to
167+
*/
168+
start_backtrace(&frame,
169+
thread_saved_fp(tsk),
170+
thread_saved_pc(tsk));
171+
}
172+
173+
printk("%sCall trace:\n", loglvl);
174+
do {
175+
/* skip until specified stack frame */
176+
if (!skip) {
177+
dump_backtrace_entry(frame.pc, loglvl);
178+
} else if (frame.fp == regs->regs[29]) {
179+
skip = 0;
180+
/*
181+
* Mostly, this is the case where this function is
182+
* called in panic/abort. As exception handler's
183+
* stack frame does not contain the corresponding pc
184+
* at which an exception has taken place, use regs->pc
185+
* instead.
186+
*/
187+
dump_backtrace_entry(regs->pc, loglvl);
188+
}
189+
} while (!unwind_frame(tsk, &frame));
190+
191+
put_task_stack(tsk);
192+
}
193+
194+
void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl)
195+
{
196+
dump_backtrace(NULL, tsk, loglvl);
197+
barrier();
198+
}
199+
135200
#ifdef CONFIG_STACKTRACE
136201

137202
void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,

arch/arm64/kernel/traps.c

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,6 @@ static const char *handler[]= {
5353

5454
int show_unhandled_signals = 0;
5555

56-
static void dump_backtrace_entry(unsigned long where, const char *loglvl)
57-
{
58-
printk("%s %pS\n", loglvl, (void *)where);
59-
}
60-
6156
static void dump_kernel_instr(const char *lvl, struct pt_regs *regs)
6257
{
6358
unsigned long addr = instruction_pointer(regs);
@@ -83,66 +78,6 @@ static void dump_kernel_instr(const char *lvl, struct pt_regs *regs)
8378
printk("%sCode: %s\n", lvl, str);
8479
}
8580

86-
void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
87-
const char *loglvl)
88-
{
89-
struct stackframe frame;
90-
int skip = 0;
91-
92-
pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
93-
94-
if (regs) {
95-
if (user_mode(regs))
96-
return;
97-
skip = 1;
98-
}
99-
100-
if (!tsk)
101-
tsk = current;
102-
103-
if (!try_get_task_stack(tsk))
104-
return;
105-
106-
if (tsk == current) {
107-
start_backtrace(&frame,
108-
(unsigned long)__builtin_frame_address(0),
109-
(unsigned long)dump_backtrace);
110-
} else {
111-
/*
112-
* task blocked in __switch_to
113-
*/
114-
start_backtrace(&frame,
115-
thread_saved_fp(tsk),
116-
thread_saved_pc(tsk));
117-
}
118-
119-
printk("%sCall trace:\n", loglvl);
120-
do {
121-
/* skip until specified stack frame */
122-
if (!skip) {
123-
dump_backtrace_entry(frame.pc, loglvl);
124-
} else if (frame.fp == regs->regs[29]) {
125-
skip = 0;
126-
/*
127-
* Mostly, this is the case where this function is
128-
* called in panic/abort. As exception handler's
129-
* stack frame does not contain the corresponding pc
130-
* at which an exception has taken place, use regs->pc
131-
* instead.
132-
*/
133-
dump_backtrace_entry(regs->pc, loglvl);
134-
}
135-
} while (!unwind_frame(tsk, &frame));
136-
137-
put_task_stack(tsk);
138-
}
139-
140-
void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl)
141-
{
142-
dump_backtrace(NULL, tsk, loglvl);
143-
barrier();
144-
}
145-
14681
#ifdef CONFIG_PREEMPT
14782
#define S_PREEMPT " PREEMPT"
14883
#elif defined(CONFIG_PREEMPT_RT)

0 commit comments

Comments
 (0)