OSDN Git Service

x86/ftrace: Enable HAVE_FUNCTION_GRAPH_RETVAL
authorDonglin Peng <pengdonglin@sangfor.com.cn>
Sat, 8 Apr 2023 12:42:20 +0000 (05:42 -0700)
committerSteven Rostedt (Google) <rostedt@goodmis.org>
Tue, 20 Jun 2023 22:38:38 +0000 (18:38 -0400)
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 x86 platform.

We introduce a new structure called fgraph_ret_regs for the x86
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/53a506f0f18ff4b7aeb0feb762f1c9a5e9b83ee9.1680954589.git.pengdonglin@sangfor.com.cn
Signed-off-by: Donglin Peng <pengdonglin@sangfor.com.cn>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
arch/x86/Kconfig
arch/x86/include/asm/ftrace.h
arch/x86/kernel/ftrace_32.S
arch/x86/kernel/ftrace_64.S

index 53bab12..da5c081 100644 (file)
@@ -216,6 +216,7 @@ config X86
        select HAVE_FAST_GUP
        select HAVE_FENTRY                      if X86_64 || DYNAMIC_FTRACE
        select HAVE_FTRACE_MCOUNT_RECORD
+       select HAVE_FUNCTION_GRAPH_RETVAL       if HAVE_FUNCTION_GRAPH_TRACER
        select HAVE_FUNCTION_GRAPH_TRACER       if X86_32 || (X86_64 && DYNAMIC_FTRACE)
        select HAVE_FUNCTION_TRACER
        select HAVE_GCC_PLUGINS
index 5061ac9..38d1df9 100644 (file)
@@ -147,4 +147,24 @@ static inline bool arch_trace_is_compat_syscall(struct pt_regs *regs)
 #endif /* !COMPILE_OFFSETS */
 #endif /* !__ASSEMBLY__ */
 
+#ifndef __ASSEMBLY__
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+struct fgraph_ret_regs {
+       unsigned long ax;
+       unsigned long dx;
+       unsigned long bp;
+};
+
+static inline unsigned long fgraph_ret_regs_return_value(struct fgraph_ret_regs *ret_regs)
+{
+       return ret_regs->ax;
+}
+
+static inline unsigned long fgraph_ret_regs_frame_pointer(struct fgraph_ret_regs *ret_regs)
+{
+       return ret_regs->bp;
+}
+#endif /* ifdef CONFIG_FUNCTION_GRAPH_TRACER */
+#endif
+
 #endif /* _ASM_X86_FTRACE_H */
index 0d9a145..24c1175 100644 (file)
@@ -187,12 +187,14 @@ SYM_CODE_END(ftrace_graph_caller)
 
 .globl return_to_handler
 return_to_handler:
-       pushl   %eax
+       pushl   $0
        pushl   %edx
-       movl    $0, %eax
+       pushl   %eax
+       movl    %esp, %eax
        call    ftrace_return_to_handler
        movl    %eax, %ecx
-       popl    %edx
        popl    %eax
+       popl    %edx
+       addl    $4, %esp                # skip ebp
        JMP_NOSPEC ecx
 #endif
index b8c720b..945cfa5 100644 (file)
@@ -348,12 +348,13 @@ STACK_FRAME_NON_STANDARD_FP(__fentry__)
 SYM_CODE_START(return_to_handler)
        UNWIND_HINT_UNDEFINED
        ANNOTATE_NOENDBR
-       subq  $16, %rsp
+       subq  $24, %rsp
 
        /* Save the return values */
        movq %rax, (%rsp)
        movq %rdx, 8(%rsp)
-       movq %rbp, %rdi
+       movq %rbp, 16(%rsp)
+       movq %rsp, %rdi
 
        call ftrace_return_to_handler
 
@@ -361,7 +362,7 @@ SYM_CODE_START(return_to_handler)
        movq 8(%rsp), %rdx
        movq (%rsp), %rax
 
-       addq $16, %rsp
+       addq $24, %rsp
        /*
         * Jump back to the old return address. This cannot be JMP_NOSPEC rdi
         * since IBT would demand that contain ENDBR, which simply isn't so for