diff options
Diffstat (limited to 'kernel/trace/trace_functions_graph.c')
| -rw-r--r-- | kernel/trace/trace_functions_graph.c | 22 | 
1 files changed, 16 insertions, 6 deletions
| diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index 66e1a527cf1a..a7f4b9a47a71 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -27,14 +27,21 @@ struct fgraph_cpu_data {  	unsigned long	enter_funcs[FTRACE_RETFUNC_DEPTH];  }; +struct fgraph_ent_args { +	struct ftrace_graph_ent_entry	ent; +	/* Force the sizeof of args[] to have FTRACE_REGS_MAX_ARGS entries */ +	unsigned long			args[FTRACE_REGS_MAX_ARGS]; +}; +  struct fgraph_data {  	struct fgraph_cpu_data __percpu *cpu_data;  	/* Place to preserve last processed entry. */  	union { -		struct ftrace_graph_ent_entry	ent; +		struct fgraph_ent_args		ent; +		/* TODO allow retaddr to have args */  		struct fgraph_retaddr_ent_entry	rent; -	} ent; +	};  	struct ftrace_graph_ret_entry	ret;  	int				failed;  	int				cpu; @@ -627,10 +634,13 @@ get_return_for_leaf(struct trace_iterator *iter,  			 * Save current and next entries for later reference  			 * if the output fails.  			 */ -			if (unlikely(curr->ent.type == TRACE_GRAPH_RETADDR_ENT)) -				data->ent.rent = *(struct fgraph_retaddr_ent_entry *)curr; -			else -				data->ent.ent = *curr; +			if (unlikely(curr->ent.type == TRACE_GRAPH_RETADDR_ENT)) { +				data->rent = *(struct fgraph_retaddr_ent_entry *)curr; +			} else { +				int size = min((int)sizeof(data->ent), (int)iter->ent_size); + +				memcpy(&data->ent, curr, size); +			}  			/*  			 * If the next event is not a return type, then  			 * we only care about what type it is. Otherwise we can | 
