From: Masami Hiramatsu (Google) <mhiramat@xxxxxxxxxx> Make the fgraph_retrieve_data() returns the reverved data size via size_byte parameter. Signed-off-by: Masami Hiramatsu (Google) <mhiramat@xxxxxxxxxx> --- include/linux/ftrace.h | 2 +- kernel/trace/fgraph.c | 5 ++++- kernel/trace/trace_selftest.c | 10 +++++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 115758fe9fec..2e24a2611ca8 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -1050,7 +1050,7 @@ struct fgraph_ops { }; void *fgraph_reserve_data(int size_bytes); -void *fgraph_retrieve_data(void); +void *fgraph_retrieve_data(int *size_bytes); /* * Stack of return addresses for functions diff --git a/kernel/trace/fgraph.c b/kernel/trace/fgraph.c index e51695441476..0b8a1daef733 100644 --- a/kernel/trace/fgraph.c +++ b/kernel/trace/fgraph.c @@ -289,6 +289,7 @@ void *fgraph_reserve_data(int size_bytes) /** * fgraph_retrieve_data - Retrieve stored data from fgraph_reserve_data() + * @size_bytes: pointer to retrieved data size. * * This is to be called by a fgraph_ops retfunc(), to retrieve data that * was stored by the fgraph_ops entryfunc() on the function entry. @@ -300,7 +301,7 @@ void *fgraph_reserve_data(int size_bytes) * matching entryfunc() for the retfunc() this is called from. * Or NULL if there was nothing stored. */ -void *fgraph_retrieve_data(void) +void *fgraph_retrieve_data(int *size_bytes) { unsigned long val; int curr_ret_stack = current->curr_ret_stack; @@ -313,6 +314,8 @@ void *fgraph_retrieve_data(void) val = current->ret_stack[curr_ret_stack - 2]; if (__get_type(val) != FGRAPH_TYPE_DATA) return NULL; + if (size_bytes) + *size_bytes = (__get_data(val) - 1) * sizeof(long); return ¤t->ret_stack[curr_ret_stack - (__get_data(val) + 1)]; diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 14966d8509ed..c656ec5b3348 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -807,15 +807,23 @@ static __init void store_return(struct ftrace_graph_ret *trace, const char *type = fgraph_store_type_name; long long expect = 0; long long found = -1; + int size; char *p; - p = fgraph_retrieve_data(); + p = fgraph_retrieve_data(&size); if (!p) { snprintf(fgraph_error_str_buf, sizeof(fgraph_error_str_buf), "Failed to retrieve %s\n", type); fgraph_error_str = fgraph_error_str_buf; return; } + if (fgraph_store_size > size) { + snprintf(fgraph_error_str_buf, sizeof(fgraph_error_str_buf), + "Retrieved size %d is smaller than expected %d\n", + size, (int)fgraph_store_size); + fgraph_error_str = fgraph_error_str_buf; + return; + } switch (fgraph_store_size) { case 1: