提交 5b6b0847 编写于 作者: C Corey Minyard 提交者: Ralf Baechle

mips: Save all registers when saving the frame

The MIPS frame save code was just saving a few registers, enough to
do a backtrace if every function set up a frame.  However, this is
not working if you are using DWARF unwinding, because most of the
registers are wrong.  This was causing kdump backtraces to be short
or bogus.

So save all the registers.
Signed-off-by: NCorey Minyard <cminyard@mvista.com>
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/16989/Signed-off-by: NRalf Baechle <ralf@linux-mips.org>
上级 866b6a89
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
#define _ASM_STACKTRACE_H #define _ASM_STACKTRACE_H
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/asm.h>
#include <linux/stringify.h>
#ifdef CONFIG_KALLSYMS #ifdef CONFIG_KALLSYMS
extern int raw_show_trace; extern int raw_show_trace;
...@@ -20,6 +22,14 @@ static inline unsigned long unwind_stack(struct task_struct *task, ...@@ -20,6 +22,14 @@ static inline unsigned long unwind_stack(struct task_struct *task,
} }
#endif #endif
#define STR_PTR_LA __stringify(PTR_LA)
#define STR_LONG_S __stringify(LONG_S)
#define STR_LONG_L __stringify(LONG_L)
#define STR_LONGSIZE __stringify(LONGSIZE)
#define STORE_ONE_REG(r) \
STR_LONG_S " $" __stringify(r)",("STR_LONGSIZE"*"__stringify(r)")(%1)\n\t"
static __always_inline void prepare_frametrace(struct pt_regs *regs) static __always_inline void prepare_frametrace(struct pt_regs *regs)
{ {
#ifndef CONFIG_KALLSYMS #ifndef CONFIG_KALLSYMS
...@@ -32,21 +42,47 @@ static __always_inline void prepare_frametrace(struct pt_regs *regs) ...@@ -32,21 +42,47 @@ static __always_inline void prepare_frametrace(struct pt_regs *regs)
__asm__ __volatile__( __asm__ __volatile__(
".set push\n\t" ".set push\n\t"
".set noat\n\t" ".set noat\n\t"
#ifdef CONFIG_64BIT /* Store $1 so we can use it */
"1: dla $1, 1b\n\t" STR_LONG_S " $1,"STR_LONGSIZE"(%1)\n\t"
"sd $1, %0\n\t" /* Store the PC */
"sd $29, %1\n\t" "1: " STR_PTR_LA " $1, 1b\n\t"
"sd $31, %2\n\t" STR_LONG_S " $1,%0\n\t"
#else STORE_ONE_REG(2)
"1: la $1, 1b\n\t" STORE_ONE_REG(3)
"sw $1, %0\n\t" STORE_ONE_REG(4)
"sw $29, %1\n\t" STORE_ONE_REG(5)
"sw $31, %2\n\t" STORE_ONE_REG(6)
#endif STORE_ONE_REG(7)
STORE_ONE_REG(8)
STORE_ONE_REG(9)
STORE_ONE_REG(10)
STORE_ONE_REG(11)
STORE_ONE_REG(12)
STORE_ONE_REG(13)
STORE_ONE_REG(14)
STORE_ONE_REG(15)
STORE_ONE_REG(16)
STORE_ONE_REG(17)
STORE_ONE_REG(18)
STORE_ONE_REG(19)
STORE_ONE_REG(20)
STORE_ONE_REG(21)
STORE_ONE_REG(22)
STORE_ONE_REG(23)
STORE_ONE_REG(24)
STORE_ONE_REG(25)
STORE_ONE_REG(26)
STORE_ONE_REG(27)
STORE_ONE_REG(28)
STORE_ONE_REG(29)
STORE_ONE_REG(30)
STORE_ONE_REG(31)
/* Restore $1 */
STR_LONG_L " $1,"STR_LONGSIZE"(%1)\n\t"
".set pop\n\t" ".set pop\n\t"
: "=m" (regs->cp0_epc), : "=m" (regs->cp0_epc)
"=m" (regs->regs[29]), "=m" (regs->regs[31]) : "r" (regs->regs)
: : "memory"); : "memory");
} }
#endif /* _ASM_STACKTRACE_H */ #endif /* _ASM_STACKTRACE_H */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册