Commit 429a9671 authored by Jinyang He's avatar Jinyang He Committed by Huacai Chen
Browse files

LoongArch: Get frame info in unwind_start() when regs is not available



At unwind_start(), it is better to get its frame info here rather than
get them outside, even we don't have 'regs'. In this way we can simply
use unwind_{start, next_frame, done} outside.

Signed-off-by: default avatarJinyang He <hejinyang@loongson.cn>
Signed-off-by: default avatarHuacai Chen <chenhuacai@loongson.cn>
parent e2f27392
Loading
Loading
Loading
Loading
+3 −9
Original line number Diff line number Diff line
@@ -191,20 +191,14 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)

unsigned long __get_wchan(struct task_struct *task)
{
	unsigned long pc;
	unsigned long pc = 0;
	struct unwind_state state;

	if (!try_get_task_stack(task))
		return 0;

	unwind_start(&state, task, NULL);
	state.sp = thread_saved_fp(task);
	get_stack_info(state.sp, state.task, &state.stack_info);
	state.pc = thread_saved_ra(task);
#ifdef CONFIG_UNWINDER_PROLOGUE
	state.type = UNWINDER_PROLOGUE;
#endif
	for (; !unwind_done(&state); unwind_next_frame(&state)) {
	for (unwind_start(&state, task, NULL);
	     !unwind_done(&state); unwind_next_frame(&state)) {
		pc = unwind_get_return_address(&state);
		if (!pc)
			break;
+6 −0
Original line number Diff line number Diff line
@@ -26,6 +26,12 @@ void unwind_start(struct unwind_state *state, struct task_struct *task,
	if (regs) {
		state->sp = regs->regs[3];
		state->pc = regs->csr_era;
	} else if (task && task != current) {
		state->sp = thread_saved_fp(task);
		state->pc = thread_saved_ra(task);
	} else {
		state->sp = (unsigned long)__builtin_frame_address(0);
		state->pc = (unsigned long)__builtin_return_address(0);
	}

	state->task = task;
+13 −3
Original line number Diff line number Diff line
@@ -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;