diff options
Diffstat (limited to 'kernel/trace/fgraph.c')
| -rw-r--r-- | kernel/trace/fgraph.c | 20 | 
1 files changed, 17 insertions, 3 deletions
diff --git a/kernel/trace/fgraph.c b/kernel/trace/fgraph.c index 7950a0356042..a2659735db73 100644 --- a/kernel/trace/fgraph.c +++ b/kernel/trace/fgraph.c @@ -101,6 +101,15 @@ int function_graph_enter(unsigned long ret, unsigned long func,  {  	struct ftrace_graph_ent trace; +	/* +	 * Skip graph tracing if the return location is served by direct trampoline, +	 * since call sequence and return addresses is unpredicatable anymore. +	 * Ex: BPF trampoline may call original function and may skip frame +	 * depending on type of BPF programs attached. +	 */ +	if (ftrace_direct_func_count && +	    ftrace_find_rec_direct(ret - MCOUNT_INSN_SIZE)) +		return -EBUSY;  	trace.func = func;  	trace.depth = ++current->curr_ret_depth; @@ -332,9 +341,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_stub_graph(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_stub_graph;  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 +628,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_stub_graph;  	ftrace_graph_entry = ftrace_graph_entry_stub;  	__ftrace_graph_entry = ftrace_graph_entry_stub;  	ftrace_shutdown(&graph_ops, FTRACE_STOP_FUNC_RET);  |