@@ -45,6 +45,39 @@ END(function_hook)
#endif
.endm
+#ifdef CONFIG_FRAME_POINTER
+/*
+ * Stack traces will stop at the ftrace trampoline if the frame pointer
+ * is not set up properly. If fentry is used, we need to save a frame
+ * pointer for the parent as well as the function traced, because the
+ * fentry is called before the stack frame is set up, where as mcount
+ * is called afterward.
+ */
+.macro create_frame parent rip
+#ifdef CC_USING_FENTRY
+ pushq \parent
+ pushq %rbp
+ movq %rsp, %rbp
+#endif
+ pushq \rip
+ pushq %rbp
+ movq %rsp, %rbp
+.endm
+
+.macro restore_frame
+#ifdef CC_USING_FENTRY
+ addq $16, %rsp
+#endif
+ popq %rbp
+ addq $8, %rsp
+.endm
+#else
+.macro create_frame parent rip
+.endm
+.macro restore_frame
+.endm
+#endif /* CONFIG_FRAME_POINTER */
+
ENTRY(ftrace_caller)
/* Check if tracing was disabled (quick check) */
cmpl $0, function_trace_stop
@@ -54,9 +87,13 @@ ENTRY(ftrace_caller)
/* regs go into 4th parameter (but make it NULL) */
movq $0, %rcx
+ create_frame %rsi, %rdi
+
GLOBAL(ftrace_call)
call ftrace_stub
+ restore_frame
+
MCOUNT_RESTORE_FRAME
ftrace_return:
@@ -104,9 +141,13 @@ ENTRY(ftrace_regs_caller)
/* regs go into 4th parameter */
leaq (%rsp), %rcx
+ create_frame %rsi, %rdi
+
GLOBAL(ftrace_regs_call)
call ftrace_stub
+ restore_frame
+
/* Copy flags back to SS, to restore them */
movq EFLAGS(%rsp), %rax
movq %rax, SS(%rsp)