Re: [PATCH] ftrace: fix function type mismatches

From: Steven Rostedt
Date: Tue Oct 15 2019 - 09:00:59 EST


On Mon, 14 Oct 2019 13:00:09 -0700
Sami Tolvanen <samitolvanen@xxxxxxxxxx> wrote:

> On Fri, Oct 11, 2019 at 11:26 AM Steven Rostedt <rostedt@xxxxxxxxxxx> wrote:
> > Unfortunately, this breaks function graph tracing.
>
> Thank you for pointing this out. I should have realized this solution
> wouldn't work.
>
> > Is there a way to do an alias or something that can fix whatever you
> > are trying to fix?
>
> Unfortunately, an alias doesn't work in this case either, because the
> compiler still looks at the type of the target function. I'll find
> another way to solve the issue.
>

Would this work for you?

-- Steve

diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index dae64600ccbf..33b36b34721b 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -111,15 +111,22 @@

#ifdef CONFIG_FTRACE_MCOUNT_RECORD
#ifdef CC_USING_PATCHABLE_FUNCTION_ENTRY
+/*
+ * Need to also make ftrace_graph_stub point to ftrace_stub
+ * so that the same stub location may have different protocols
+ * and not mess up with C verifiers.
+ */
#define MCOUNT_REC() . = ALIGN(8); \
__start_mcount_loc = .; \
KEEP(*(__patchable_function_entries)) \
- __stop_mcount_loc = .;
+ __stop_mcount_loc = .; \
+ ftrace_graph_stub = ftrace_stub;
#else
#define MCOUNT_REC() . = ALIGN(8); \
__start_mcount_loc = .; \
KEEP(*(__mcount_loc)) \
- __stop_mcount_loc = .;
+ __stop_mcount_loc = .; \
+ ftrace_graph_stub = ftrace_stub;
#endif
#else
#define MCOUNT_REC()
diff --git a/kernel/trace/fgraph.c b/kernel/trace/fgraph.c
index 7950a0356042..fa3ce10d0405 100644
--- a/kernel/trace/fgraph.c
+++ b/kernel/trace/fgraph.c
@@ -332,9 +332,14 @@ int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace)
return 0;
}

+/*
+ * Simply points to ftrace_stub, but with the proper protocol.
+ * Defined by the linker script in linux/vmlinux.lds.h
+ */
+extern void ftrace_graph_stub(struct ftrace_graph_ret *);
+
/* The callbacks that hook a function */
-trace_func_graph_ret_t ftrace_graph_return =
- (trace_func_graph_ret_t)ftrace_stub;
+trace_func_graph_ret_t ftrace_graph_return = ftrace_graph_stub;
trace_func_graph_ent_t ftrace_graph_entry = ftrace_graph_entry_stub;
static trace_func_graph_ent_t __ftrace_graph_entry = ftrace_graph_entry_stub;

@@ -614,7 +619,7 @@ void unregister_ftrace_graph(struct fgraph_ops *gops)
goto out;

ftrace_graph_active--;
- ftrace_graph_return = (trace_func_graph_ret_t)ftrace_stub;
+ ftrace_graph_return = ftrace_graph_stub;
ftrace_graph_entry = ftrace_graph_entry_stub;
__ftrace_graph_entry = ftrace_graph_entry_stub;
ftrace_shutdown(&graph_ops, FTRACE_STOP_FUNC_RET);