summaryrefslogtreecommitdiffstats
path: root/arch/loongarch/kernel/unwind_prologue.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/loongarch/kernel/unwind_prologue.c')
-rw-r--r--arch/loongarch/kernel/unwind_prologue.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/arch/loongarch/kernel/unwind_prologue.c b/arch/loongarch/kernel/unwind_prologue.c
index e98b00432c88..613545ce6a97 100644
--- a/arch/loongarch/kernel/unwind_prologue.c
+++ b/arch/loongarch/kernel/unwind_prologue.c
@@ -146,12 +146,22 @@ void unwind_start(struct unwind_state *state, struct task_struct *task,
struct pt_regs *regs)
{
memset(state, 0, sizeof(*state));
+ state->type = UNWINDER_PROLOGUE;
- if (regs && __kernel_text_address(regs->csr_era)) {
- state->pc = regs->csr_era;
+ if (regs) {
state->sp = regs->regs[3];
+ state->pc = regs->csr_era;
state->ra = regs->regs[1];
- state->type = UNWINDER_PROLOGUE;
+ if (!__kernel_text_address(state->pc))
+ state->type = UNWINDER_GUESS;
+ } else if (task && task != current) {
+ state->sp = thread_saved_fp(task);
+ state->pc = thread_saved_ra(task);
+ state->ra = 0;
+ } else {
+ state->sp = (unsigned long)__builtin_frame_address(0);
+ state->pc = (unsigned long)__builtin_return_address(0);
+ state->ra = 0;
}
state->task = task;