On Tue, 18 Nov 2014, Steven Rostedt wrote: > From: "Steven Rostedt (Red Hat)" <rost...@goodmis.org> > > When CONFIG_FRAME_POINTERS are enabled, it is required that the > ftrace_caller and ftrace_regs_caller trampolines set up frame pointers > otherwise a stack trace from a function call wont print the functions > that called the trampoline. This is due to a check in > __save_stack_address(): > > #ifdef CONFIG_FRAME_POINTER > if (!reliable) > return; > #endif > > The "reliable" variable is only set if the function address is equal to > contents of the address before the address the frame pointer register > points to. If the frame pointer is not set up for the ftrace caller > then this will fail the reliable test. It will miss the function that > called the trampoline. Worse yet, if fentry is used (gcc 4.6 and > beyond), it will also miss the parent, as the fentry is called before > the stack frame is set up. That means the bp frame pointer points > to the stack of just before the parent function was called. > > Cc: Thomas Gleixner <t...@linutronix.de> > Cc: Ingo Molnar <mi...@redhat.com> > Cc: "H. Peter Anvin" <h...@zytor.com> > Cc: x...@kernel.org > Signed-off-by: Steven Rostedt <rost...@goodmis.org>
Shouldn't this be tagged stable? Acked-by: Thomas Gleixner <t...@linutronix.de> > --- > arch/x86/kernel/mcount_64.S | 41 +++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 41 insertions(+) > > diff --git a/arch/x86/kernel/mcount_64.S b/arch/x86/kernel/mcount_64.S > index 42f0cdd20baf..35a793fa4bba 100644 > --- a/arch/x86/kernel/mcount_64.S > +++ b/arch/x86/kernel/mcount_64.S > @@ -47,14 +47,51 @@ GLOBAL(\trace_label) > #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) > ftrace_caller_setup ftrace_caller_op_ptr > /* 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 > > /* > @@ -105,9 +142,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) > -- > 2.1.1 > > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/