Skip to content

Commit a51ac52

Browse files
zhangqingmychenhuacai
authored andcommitted
LoongArch/ftrace: Add HAVE_FUNCTION_GRAPH_RET_ADDR_PTR support
ftrace_graph_ret_addr() can be called by stack unwinding code to convert a found stack return address ('ret') to its original value, in case the function graph tracer has modified it to be 'return_to_handler'. If the hasn't been modified, the unchanged value of 'ret' is returned. Signed-off-by: Qing Zhang <[email protected]> Signed-off-by: Huacai Chen <[email protected]>
1 parent ac7127e commit a51ac52

File tree

5 files changed

+19
-6
lines changed

5 files changed

+19
-6
lines changed

arch/loongarch/include/asm/ftrace.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#ifndef _ASM_LOONGARCH_FTRACE_H
77
#define _ASM_LOONGARCH_FTRACE_H
88

9+
#define GRAPH_FAKE_OFFSET (sizeof(struct pt_regs) - offsetof(struct pt_regs, regs[1]))
10+
911
#ifdef CONFIG_FUNCTION_TRACER
1012

1113
#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */
@@ -24,6 +26,7 @@ struct dyn_ftrace;
2426
struct dyn_arch_ftrace { };
2527

2628
#define ARCH_SUPPORTS_FTRACE_OPS 1
29+
#define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
2730

2831
#define ftrace_init_nop ftrace_init_nop
2932
int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);

arch/loongarch/include/asm/unwind.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct unwind_state {
2121
struct stack_info stack_info;
2222
struct task_struct *task;
2323
bool first, error, is_ftrace;
24+
int graph_idx;
2425
unsigned long sp, pc, ra;
2526
};
2627

arch/loongarch/kernel/ftrace_dyn.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent)
135135

136136
old = *parent;
137137

138-
if (!function_graph_enter(old, self_addr, 0, NULL))
138+
if (!function_graph_enter(old, self_addr, 0, parent))
139139
*parent = return_hooker;
140140
}
141141

arch/loongarch/kernel/unwind_guess.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright (C) 2022 Loongson Technology Corporation Limited
44
*/
55
#include <linux/kernel.h>
6+
#include <linux/ftrace.h>
67

78
#include <asm/unwind.h>
89

@@ -53,7 +54,8 @@ bool unwind_next_frame(struct unwind_state *state)
5354
state->sp < info->end;
5455
state->sp += sizeof(unsigned long)) {
5556
addr = *(unsigned long *)(state->sp);
56-
57+
state->pc = ftrace_graph_ret_addr(state->task, &state->graph_idx,
58+
addr, (unsigned long *)(state->sp - GRAPH_FAKE_OFFSET));
5759
if (__kernel_text_address(addr))
5860
return true;
5961
}

arch/loongarch/kernel/unwind_prologue.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
/*
33
* Copyright (C) 2022 Loongson Technology Corporation Limited
44
*/
5+
#include <linux/ftrace.h>
56
#include <linux/kallsyms.h>
67

78
#include <asm/inst.h>
@@ -42,6 +43,8 @@ static bool unwind_by_guess(struct unwind_state *state)
4243
state->sp < info->end;
4344
state->sp += sizeof(unsigned long)) {
4445
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));
4548
if (__kernel_text_address(addr))
4649
return true;
4750
}
@@ -174,8 +177,11 @@ bool unwind_next_frame(struct unwind_state *state)
174177
break;
175178

176179
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));
178183
return true;
184+
}
179185

180186
if (info->type == STACK_TYPE_IRQ &&
181187
info->end == state->sp) {
@@ -185,10 +191,11 @@ bool unwind_next_frame(struct unwind_state *state)
185191
if (user_mode(regs) || !__kernel_text_address(pc))
186192
return false;
187193

188-
state->pc = pc;
189-
state->sp = regs->regs[3];
190-
state->ra = regs->regs[1];
191194
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));
192199
get_stack_info(state->sp, state->task, info);
193200

194201
return true;

0 commit comments

Comments
 (0)