diff options
Diffstat (limited to 'arch/csky/kernel/dumpstack.c')
-rw-r--r-- | arch/csky/kernel/dumpstack.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/arch/csky/kernel/dumpstack.c b/arch/csky/kernel/dumpstack.c new file mode 100644 index 000000000000..d67f9777cfd9 --- /dev/null +++ b/arch/csky/kernel/dumpstack.c @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. + +#include <linux/ptrace.h> + +int kstack_depth_to_print = 48; + +void show_trace(unsigned long *stack) +{ + unsigned long *stack_end; + unsigned long *stack_start; + unsigned long *fp; + unsigned long addr; + + addr = (unsigned long) stack & THREAD_MASK; + stack_start = (unsigned long *) addr; + stack_end = (unsigned long *) (addr + THREAD_SIZE); + + fp = stack; + pr_info("\nCall Trace:"); + + while (fp > stack_start && fp < stack_end) { +#ifdef CONFIG_STACKTRACE + addr = fp[1]; + fp = (unsigned long *) fp[0]; +#else + addr = *fp++; +#endif + if (__kernel_text_address(addr)) + pr_cont("\n[<%08lx>] %pS", addr, (void *)addr); + } + pr_cont("\n"); +} + +void show_stack(struct task_struct *task, unsigned long *stack) +{ + if (!stack) { + if (task) + stack = (unsigned long *)thread_saved_fp(task); + else +#ifdef CONFIG_STACKTRACE + asm volatile("mov %0, r8\n":"=r"(stack)::"memory"); +#else + stack = (unsigned long *)&stack; +#endif + } + + show_trace(stack); +} |