Skip to content

Commit 3646970

Browse files
Donglin Pengrostedt
authored andcommitted
arm64: ftrace: Enable HAVE_FUNCTION_GRAPH_RETVAL
The previous patch ("function_graph: Support recording and printing the return value of function") has laid the groundwork for the for the funcgraph-retval, and this modification makes it available on the ARM64 platform. We introduce a new structure called fgraph_ret_regs for the ARM64 platform to hold return registers and the frame pointer. We then fill its content in the return_to_handler and pass its address to the function ftrace_return_to_handler to record the return value. Link: https://lkml.kernel.org/r/c78366416ce93f704ae7000c4ee60eb4258c38f7.1680954589.git.pengdonglin@sangfor.com.cn Reviewed-by: Mark Rutland <[email protected]> Tested-by: Mark Rutland <[email protected]> Acked-by: Catalin Marinas <[email protected]> Signed-off-by: Donglin Peng <[email protected]> Signed-off-by: Steven Rostedt (Google) <[email protected]>
1 parent 21c094d commit 3646970

File tree

4 files changed

+50
-13
lines changed

4 files changed

+50
-13
lines changed

arch/arm64/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ config ARM64
201201
select HAVE_FTRACE_MCOUNT_RECORD
202202
select HAVE_FUNCTION_TRACER
203203
select HAVE_FUNCTION_ERROR_INJECTION
204+
select HAVE_FUNCTION_GRAPH_RETVAL if HAVE_FUNCTION_GRAPH_TRACER
204205
select HAVE_FUNCTION_GRAPH_TRACER
205206
select HAVE_GCC_PLUGINS
206207
select HAVE_HW_BREAKPOINT if PERF_EVENTS

arch/arm64/include/asm/ftrace.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,4 +192,26 @@ static inline bool arch_syscall_match_sym_name(const char *sym,
192192
}
193193
#endif /* ifndef __ASSEMBLY__ */
194194

195+
#ifndef __ASSEMBLY__
196+
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
197+
struct fgraph_ret_regs {
198+
/* x0 - x7 */
199+
unsigned long regs[8];
200+
201+
unsigned long fp;
202+
unsigned long __unused;
203+
};
204+
205+
static inline unsigned long fgraph_ret_regs_return_value(struct fgraph_ret_regs *ret_regs)
206+
{
207+
return ret_regs->regs[0];
208+
}
209+
210+
static inline unsigned long fgraph_ret_regs_frame_pointer(struct fgraph_ret_regs *ret_regs)
211+
{
212+
return ret_regs->fp;
213+
}
214+
#endif /* ifdef CONFIG_FUNCTION_GRAPH_TRACER */
215+
#endif
216+
195217
#endif /* __ASM_FTRACE_H */

arch/arm64/kernel/asm-offsets.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,19 @@ int main(void)
200200
#endif
201201
#ifdef CONFIG_FUNCTION_TRACER
202202
DEFINE(FTRACE_OPS_FUNC, offsetof(struct ftrace_ops, func));
203+
#endif
204+
BLANK();
205+
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
206+
DEFINE(FGRET_REGS_X0, offsetof(struct fgraph_ret_regs, regs[0]));
207+
DEFINE(FGRET_REGS_X1, offsetof(struct fgraph_ret_regs, regs[1]));
208+
DEFINE(FGRET_REGS_X2, offsetof(struct fgraph_ret_regs, regs[2]));
209+
DEFINE(FGRET_REGS_X3, offsetof(struct fgraph_ret_regs, regs[3]));
210+
DEFINE(FGRET_REGS_X4, offsetof(struct fgraph_ret_regs, regs[4]));
211+
DEFINE(FGRET_REGS_X5, offsetof(struct fgraph_ret_regs, regs[5]));
212+
DEFINE(FGRET_REGS_X6, offsetof(struct fgraph_ret_regs, regs[6]));
213+
DEFINE(FGRET_REGS_X7, offsetof(struct fgraph_ret_regs, regs[7]));
214+
DEFINE(FGRET_REGS_FP, offsetof(struct fgraph_ret_regs, fp));
215+
DEFINE(FGRET_REGS_SIZE, sizeof(struct fgraph_ret_regs));
203216
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
204217
DEFINE(FTRACE_OPS_DIRECT_CALL, offsetof(struct ftrace_ops, direct_call));
205218
#endif

arch/arm64/kernel/entry-ftrace.S

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -330,22 +330,23 @@ SYM_FUNC_END(ftrace_stub_graph)
330330
*/
331331
SYM_CODE_START(return_to_handler)
332332
/* save return value regs */
333-
sub sp, sp, #64
334-
stp x0, x1, [sp]
335-
stp x2, x3, [sp, #16]
336-
stp x4, x5, [sp, #32]
337-
stp x6, x7, [sp, #48]
333+
sub sp, sp, #FGRET_REGS_SIZE
334+
stp x0, x1, [sp, #FGRET_REGS_X0]
335+
stp x2, x3, [sp, #FGRET_REGS_X2]
336+
stp x4, x5, [sp, #FGRET_REGS_X4]
337+
stp x6, x7, [sp, #FGRET_REGS_X6]
338+
str x29, [sp, #FGRET_REGS_FP] // parent's fp
338339

339-
mov x0, x29 // parent's fp
340-
bl ftrace_return_to_handler// addr = ftrace_return_to_hander(fp);
341-
mov x30, x0 // restore the original return address
340+
mov x0, sp
341+
bl ftrace_return_to_handler // addr = ftrace_return_to_hander(regs);
342+
mov x30, x0 // restore the original return address
342343

343344
/* restore return value regs */
344-
ldp x0, x1, [sp]
345-
ldp x2, x3, [sp, #16]
346-
ldp x4, x5, [sp, #32]
347-
ldp x6, x7, [sp, #48]
348-
add sp, sp, #64
345+
ldp x0, x1, [sp, #FGRET_REGS_X0]
346+
ldp x2, x3, [sp, #FGRET_REGS_X2]
347+
ldp x4, x5, [sp, #FGRET_REGS_X4]
348+
ldp x6, x7, [sp, #FGRET_REGS_X6]
349+
add sp, sp, #FGRET_REGS_SIZE
349350

350351
ret
351352
SYM_CODE_END(return_to_handler)

0 commit comments

Comments
 (0)