unwind_prologue.c (4733f09d880745953b88c3358b49ad495aecd8e9) unwind_prologue.c (a51ac5246d2505b58229242959d2bc73d113ca50)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2022 Loongson Technology Corporation Limited
4 */
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2022 Loongson Technology Corporation Limited
4 */
5#include <linux/ftrace.h>
5#include <linux/kallsyms.h>
6
7#include <asm/inst.h>
8#include <asm/ptrace.h>
9#include <asm/unwind.h>
10
11static inline void unwind_state_fixup(struct unwind_state *state)
12{

--- 24 unchanged lines hidden (view full) ---

37{
38 struct stack_info *info = &state->stack_info;
39 unsigned long addr;
40
41 for (state->sp += sizeof(unsigned long);
42 state->sp < info->end;
43 state->sp += sizeof(unsigned long)) {
44 addr = *(unsigned long *)(state->sp);
6#include <linux/kallsyms.h>
7
8#include <asm/inst.h>
9#include <asm/ptrace.h>
10#include <asm/unwind.h>
11
12static inline void unwind_state_fixup(struct unwind_state *state)
13{

--- 24 unchanged lines hidden (view full) ---

38{
39 struct stack_info *info = &state->stack_info;
40 unsigned long addr;
41
42 for (state->sp += sizeof(unsigned long);
43 state->sp < info->end;
44 state->sp += sizeof(unsigned long)) {
45 addr = *(unsigned long *)(state->sp);
46 state->pc = ftrace_graph_ret_addr(state->task, &state->graph_idx,
47 addr, (unsigned long *)(state->sp - GRAPH_FAKE_OFFSET));
45 if (__kernel_text_address(addr))
46 return true;
47 }
48
49 return false;
50}
51
52static bool unwind_by_prologue(struct unwind_state *state)

--- 116 unchanged lines hidden (view full) ---

169 switch (state->type) {
170 case UNWINDER_GUESS:
171 state->first = false;
172 if (unwind_by_guess(state))
173 return true;
174 break;
175
176 case UNWINDER_PROLOGUE:
48 if (__kernel_text_address(addr))
49 return true;
50 }
51
52 return false;
53}
54
55static bool unwind_by_prologue(struct unwind_state *state)

--- 116 unchanged lines hidden (view full) ---

172 switch (state->type) {
173 case UNWINDER_GUESS:
174 state->first = false;
175 if (unwind_by_guess(state))
176 return true;
177 break;
178
179 case UNWINDER_PROLOGUE:
177 if (unwind_by_prologue(state))
180 if (unwind_by_prologue(state)) {
181 state->pc = ftrace_graph_ret_addr(state->task, &state->graph_idx,
182 state->pc, (unsigned long *)(state->sp - GRAPH_FAKE_OFFSET));
178 return true;
183 return true;
184 }
179
180 if (info->type == STACK_TYPE_IRQ &&
181 info->end == state->sp) {
182 regs = (struct pt_regs *)info->next_sp;
183 pc = regs->csr_era;
184
185 if (user_mode(regs) || !__kernel_text_address(pc))
186 return false;
187
185
186 if (info->type == STACK_TYPE_IRQ &&
187 info->end == state->sp) {
188 regs = (struct pt_regs *)info->next_sp;
189 pc = regs->csr_era;
190
191 if (user_mode(regs) || !__kernel_text_address(pc))
192 return false;
193
188 state->pc = pc;
189 state->sp = regs->regs[3];
190 state->ra = regs->regs[1];
191 state->first = true;
194 state->first = true;
195 state->ra = regs->regs[1];
196 state->sp = regs->regs[3];
197 state->pc = ftrace_graph_ret_addr(state->task, &state->graph_idx,
198 pc, (unsigned long *)(state->sp - GRAPH_FAKE_OFFSET));
192 get_stack_info(state->sp, state->task, info);
193
194 return true;
195 }
196 }
197
198 state->sp = info->next_sp;
199
200 } while (!get_stack_info(state->sp, state->task, info));
201
202 return false;
203}
204EXPORT_SYMBOL_GPL(unwind_next_frame);
199 get_stack_info(state->sp, state->task, info);
200
201 return true;
202 }
203 }
204
205 state->sp = info->next_sp;
206
207 } while (!get_stack_info(state->sp, state->task, info));
208
209 return false;
210}
211EXPORT_SYMBOL_GPL(unwind_next_frame);