To record function parameter and return value, we need the arch specific
code to pass the saved register context. It is only valid if the
CONFIG_FTRACE_FUNC_PROTOTYPE feature is enabled. This patch only changes
the interfaces, real implementation will be added later.

Signed-off-by: Changbin Du <changbin...@gmail.com>
---
 arch/arm/kernel/ftrace.c             |  2 +-
 arch/arm64/kernel/ftrace.c           |  2 +-
 arch/csky/kernel/ftrace.c            |  2 +-
 arch/microblaze/kernel/ftrace.c      |  2 +-
 arch/mips/kernel/ftrace.c            |  2 +-
 arch/nds32/kernel/ftrace.c           |  5 +++--
 arch/parisc/kernel/ftrace.c          |  2 +-
 arch/powerpc/kernel/trace/ftrace.c   |  2 +-
 arch/riscv/kernel/ftrace.c           |  2 +-
 arch/s390/kernel/ftrace.c            |  2 +-
 arch/sh/kernel/ftrace.c              |  2 +-
 arch/sparc/kernel/ftrace.c           |  2 +-
 arch/x86/kernel/ftrace.c             |  2 +-
 include/linux/ftrace.h               | 10 +++++++---
 kernel/trace/fgraph.c                | 21 +++++++++++++++------
 kernel/trace/ftrace.c                |  4 +++-
 kernel/trace/trace.h                 |  2 +-
 kernel/trace/trace_functions_graph.c |  2 +-
 kernel/trace/trace_irqsoff.c         |  3 ++-
 kernel/trace/trace_sched_wakeup.c    |  3 ++-
 20 files changed, 46 insertions(+), 28 deletions(-)

diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index bda949fd84e8..fd01c08b2dcb 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -191,7 +191,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned 
long self_addr,
        old = *parent;
        *parent = return_hooker;
 
-       if (function_graph_enter(old, self_addr, frame_pointer, NULL))
+       if (function_graph_enter(old, self_addr, frame_pointer, NULL, NULL))
                *parent = old;
 }
 
diff --git a/arch/arm64/kernel/ftrace.c b/arch/arm64/kernel/ftrace.c
index 171773257974..dc8cc516c00a 100644
--- a/arch/arm64/kernel/ftrace.c
+++ b/arch/arm64/kernel/ftrace.c
@@ -233,7 +233,7 @@ void prepare_ftrace_return(unsigned long self_addr, 
unsigned long *parent,
         */
        old = *parent;
 
-       if (!function_graph_enter(old, self_addr, frame_pointer, NULL))
+       if (!function_graph_enter(old, self_addr, frame_pointer, NULL, NULL))
                *parent = return_hooker;
 }
 
diff --git a/arch/csky/kernel/ftrace.c b/arch/csky/kernel/ftrace.c
index 44f4880179b7..5bc67f447e78 100644
--- a/arch/csky/kernel/ftrace.c
+++ b/arch/csky/kernel/ftrace.c
@@ -148,7 +148,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned 
long self_addr,
        old = *parent;
 
        if (!function_graph_enter(old, self_addr,
-                       *(unsigned long *)frame_pointer, parent)) {
+                       *(unsigned long *)frame_pointer, parent, NULL)) {
                /*
                 * For csky-gcc function has sub-call:
                 * subi sp,     sp, 8
diff --git a/arch/microblaze/kernel/ftrace.c b/arch/microblaze/kernel/ftrace.c
index 224eea40e1ee..9722e98cd01d 100644
--- a/arch/microblaze/kernel/ftrace.c
+++ b/arch/microblaze/kernel/ftrace.c
@@ -62,7 +62,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned 
long self_addr)
                return;
        }
 
-       if (function_graph_enter(old, self_addr, 0, NULL))
+       if (function_graph_enter(old, self_addr, 0, NULL, NULL))
                *parent = old;
 }
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c
index 2625232bfe52..24668bf079d2 100644
--- a/arch/mips/kernel/ftrace.c
+++ b/arch/mips/kernel/ftrace.c
@@ -378,7 +378,7 @@ void prepare_ftrace_return(unsigned long *parent_ra_addr, 
unsigned long self_ra,
        insns = core_kernel_text(self_ra) ? 2 : MCOUNT_OFFSET_INSNS + 1;
        self_ra -= (MCOUNT_INSN_SIZE * insns);
 
-       if (function_graph_enter(old_parent_ra, self_ra, fp, NULL))
+       if (function_graph_enter(old_parent_ra, self_ra, fp, NULL, NULL))
                *parent_ra_addr = old_parent_ra;
        return;
 out:
diff --git a/arch/nds32/kernel/ftrace.c b/arch/nds32/kernel/ftrace.c
index fd2a54b8cd57..3dbf0017dfdf 100644
--- a/arch/nds32/kernel/ftrace.c
+++ b/arch/nds32/kernel/ftrace.c
@@ -217,7 +217,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned 
long self_addr,
 
        old = *parent;
 
-       if (!function_graph_enter(old, self_addr, frame_pointer, NULL))
+       if (!function_graph_enter(old, self_addr, frame_pointer, NULL, NULL))
                *parent = return_hooker;
 }
 
@@ -235,7 +235,8 @@ noinline void ftrace_graph_caller(void)
        prepare_ftrace_return(parent_ip, selfpc, frame_pointer);
 }
 
-extern unsigned long ftrace_return_to_handler(unsigned long frame_pointer);
+extern unsigned long ftrace_return_to_handler(unsigned long frame_pointer,
+                                             unsigned long retval);
 void __naked return_to_handler(void)
 {
        __asm__ __volatile__ (
diff --git a/arch/parisc/kernel/ftrace.c b/arch/parisc/kernel/ftrace.c
index b6fb30f2e4bf..ea02f36e4f84 100644
--- a/arch/parisc/kernel/ftrace.c
+++ b/arch/parisc/kernel/ftrace.c
@@ -40,7 +40,7 @@ static void __hot prepare_ftrace_return(unsigned long *parent,
 
        old = *parent;
 
-       if (!function_graph_enter(old, self_addr, 0, NULL))
+       if (!function_graph_enter(old, self_addr, 0, NULL, NULL))
                /* activate parisc_return_to_handler() as return point */
                *parent = (unsigned long) &parisc_return_to_handler;
 }
diff --git a/arch/powerpc/kernel/trace/ftrace.c 
b/arch/powerpc/kernel/trace/ftrace.c
index be1ca98fce5c..78174bbb257e 100644
--- a/arch/powerpc/kernel/trace/ftrace.c
+++ b/arch/powerpc/kernel/trace/ftrace.c
@@ -956,7 +956,7 @@ unsigned long prepare_ftrace_return(unsigned long parent, 
unsigned long ip)
 
        return_hooker = ppc_function_entry(return_to_handler);
 
-       if (!function_graph_enter(parent, ip, 0, NULL))
+       if (!function_graph_enter(parent, ip, 0, NULL, NULL))
                parent = return_hooker;
 out:
        return parent;
diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c
index b94d8db5ddcc..18f836727950 100644
--- a/arch/riscv/kernel/ftrace.c
+++ b/arch/riscv/kernel/ftrace.c
@@ -142,7 +142,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned 
long self_addr,
         */
        old = *parent;
 
-       if (function_graph_enter(old, self_addr, frame_pointer, parent))
+       if (function_graph_enter(old, self_addr, frame_pointer, parent, NULL))
                *parent = return_hooker;
 }
 
diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c
index 1bb85f60c0dd..5021a23c5089 100644
--- a/arch/s390/kernel/ftrace.c
+++ b/arch/s390/kernel/ftrace.c
@@ -209,7 +209,7 @@ unsigned long prepare_ftrace_return(unsigned long ra, 
unsigned long sp,
        if (unlikely(atomic_read(&current->tracing_graph_pause)))
                goto out;
        ip -= MCOUNT_INSN_SIZE;
-       if (!function_graph_enter(ra, ip, 0, (void *) sp))
+       if (!function_graph_enter(ra, ip, 0, (void *) sp), NULL)
                ra = (unsigned long) return_to_handler;
 out:
        return ra;
diff --git a/arch/sh/kernel/ftrace.c b/arch/sh/kernel/ftrace.c
index 1b04270e5460..3a8271993e9c 100644
--- a/arch/sh/kernel/ftrace.c
+++ b/arch/sh/kernel/ftrace.c
@@ -364,7 +364,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned 
long self_addr)
                return;
        }
 
-       if (function_graph_enter(old, self_addr, 0, NULL))
+       if (function_graph_enter(old, self_addr, 0, NULL, NULL))
                __raw_writel(old, parent);
 }
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
diff --git a/arch/sparc/kernel/ftrace.c b/arch/sparc/kernel/ftrace.c
index 684b84ce397f..2783185719ba 100644
--- a/arch/sparc/kernel/ftrace.c
+++ b/arch/sparc/kernel/ftrace.c
@@ -130,7 +130,7 @@ unsigned long prepare_ftrace_return(unsigned long parent,
        if (unlikely(atomic_read(&current->tracing_graph_pause)))
                return parent + 8UL;
 
-       if (function_graph_enter(parent, self_addr, frame_pointer, NULL))
+       if (function_graph_enter(parent, self_addr, frame_pointer, NULL, NULL))
                return parent + 8UL;
 
        return return_hooker;
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
index 024c3053dbba..a044734167af 100644
--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -1072,7 +1072,7 @@ void prepare_ftrace_return(unsigned long self_addr, 
unsigned long *parent,
                return;
        }
 
-       if (function_graph_enter(old, self_addr, frame_pointer, parent))
+       if (function_graph_enter(old, self_addr, frame_pointer, parent, NULL))
                *parent = old;
 }
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index f5aab37a8c34..e615b5e639aa 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -757,9 +757,12 @@ struct ftrace_graph_ret {
 
 /* Type of the callback handlers for tracing function graph*/
 typedef void (*trace_func_graph_ret_t)(struct ftrace_graph_ret *); /* return */
-typedef int (*trace_func_graph_ent_t)(struct ftrace_graph_ent *); /* entry */
+/* @pt_regs is only available for CONFIG_FTRACE_FUNC_PROTOTYPE. */
+typedef int (*trace_func_graph_ent_t)(struct ftrace_graph_ent *,
+                                     struct pt_regs *); /* entry */
 
-extern int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace);
+int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace,
+                           struct pt_regs *pt_regs);
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 
@@ -797,7 +800,8 @@ extern void return_to_handler(void);
 
 extern int
 function_graph_enter(unsigned long ret, unsigned long func,
-                    unsigned long frame_pointer, unsigned long *retp);
+                    unsigned long frame_pointer, unsigned long *retp,
+                    struct pt_regs *pt_regs);
 
 struct ftrace_ret_stack *
 ftrace_graph_get_ret_stack(struct task_struct *task, int idx);
diff --git a/kernel/trace/fgraph.c b/kernel/trace/fgraph.c
index 8dfd5021b933..7451dba84fee 100644
--- a/kernel/trace/fgraph.c
+++ b/kernel/trace/fgraph.c
@@ -96,8 +96,13 @@ ftrace_push_return_trace(unsigned long ret, unsigned long 
func,
        return 0;
 }
 
+/*
+ * Called from arch specific code. @pt_regs is only available for
+ * CONFIG_FTRACE_FUNC_PROTOTYPE.
+ */
 int function_graph_enter(unsigned long ret, unsigned long func,
-                        unsigned long frame_pointer, unsigned long *retp)
+                        unsigned long frame_pointer, unsigned long *retp,
+                        struct pt_regs *pt_regs)
 {
        struct ftrace_graph_ent trace;
 
@@ -108,7 +113,7 @@ int function_graph_enter(unsigned long ret, unsigned long 
func,
                goto out;
 
        /* Only trace if the calling function expects to */
-       if (!ftrace_graph_entry(&trace))
+       if (!ftrace_graph_entry(&trace, pt_regs))
                goto out_ret;
 
        return 0;
@@ -204,9 +209,11 @@ static struct notifier_block ftrace_suspend_notifier = {
 
 /*
  * Send the trace to the ring-buffer.
+ * @retval is only available for CONFIG_FTRACE_FUNC_PROTOTYPE.
  * @return the original return address.
  */
-unsigned long ftrace_return_to_handler(unsigned long frame_pointer)
+unsigned long ftrace_return_to_handler(unsigned long frame_pointer,
+                                      unsigned long retval)
 {
        struct ftrace_graph_ret trace;
        unsigned long ret;
@@ -327,7 +334,8 @@ void ftrace_graph_sleep_time_control(bool enable)
        fgraph_sleep_time = enable;
 }
 
-int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace)
+int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace,
+                           struct pt_regs *pt_regs)
 {
        return 0;
 }
@@ -417,11 +425,12 @@ ftrace_graph_probe_sched_switch(void *ignore, bool 
preempt,
                next->ret_stack[index].calltime += timestamp;
 }
 
-static int ftrace_graph_entry_test(struct ftrace_graph_ent *trace)
+static int ftrace_graph_entry_test(struct ftrace_graph_ent *trace,
+                                  struct pt_regs *pt_regs)
 {
        if (!ftrace_ops_test(&global_ops, trace->func, NULL))
                return 0;
-       return __ftrace_graph_entry(trace);
+       return __ftrace_graph_entry(trace, pt_regs);
 }
 
 /*
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 438b8b47198f..a1683cc55838 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -794,7 +794,9 @@ void ftrace_graph_graph_time_control(bool enable)
        fgraph_graph_time = enable;
 }
 
-static int profile_graph_entry(struct ftrace_graph_ent *trace)
+/* @pt_regs is only available for CONFIG_FTRACE_FUNC_PROTOTYPE. */
+static int profile_graph_entry(struct ftrace_graph_ent *trace,
+                              struct pt_regs *pt_regs)
 {
        struct ftrace_ret_stack *ret_stack;
 
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 22433a15e340..4b31176d443e 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -737,7 +737,7 @@ void print_trace_header(struct seq_file *m, struct 
trace_iterator *iter);
 int trace_empty(struct trace_iterator *iter);
 
 void trace_graph_return(struct ftrace_graph_ret *trace);
-int trace_graph_entry(struct ftrace_graph_ent *trace);
+int trace_graph_entry(struct ftrace_graph_ent *trace, struct pt_regs *pt_regs);
 void set_graph_array(struct trace_array *tr);
 
 void tracing_start_cmdline_record(void);
diff --git a/kernel/trace/trace_functions_graph.c 
b/kernel/trace/trace_functions_graph.c
index 78af97163147..f331a9ba946d 100644
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -124,7 +124,7 @@ static inline int ftrace_graph_ignore_irqs(void)
        return in_irq();
 }
 
-int trace_graph_entry(struct ftrace_graph_ent *trace)
+int trace_graph_entry(struct ftrace_graph_ent *trace, struct pt_regs *pt_regs)
 {
        struct trace_array *tr = graph_array;
        struct trace_array_cpu *data;
diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c
index a745b0cee5d3..513e3544a45a 100644
--- a/kernel/trace/trace_irqsoff.c
+++ b/kernel/trace/trace_irqsoff.c
@@ -172,7 +172,8 @@ static int irqsoff_display_graph(struct trace_array *tr, 
int set)
        return start_irqsoff_tracer(irqsoff_trace, set);
 }
 
-static int irqsoff_graph_entry(struct ftrace_graph_ent *trace)
+static int irqsoff_graph_entry(struct ftrace_graph_ent *trace,
+                              struct pt_regs *pt_regs)
 {
        struct trace_array *tr = irqsoff_trace;
        struct trace_array_cpu *data;
diff --git a/kernel/trace/trace_sched_wakeup.c 
b/kernel/trace/trace_sched_wakeup.c
index 743b2b520d34..ce18f679930c 100644
--- a/kernel/trace/trace_sched_wakeup.c
+++ b/kernel/trace/trace_sched_wakeup.c
@@ -112,7 +112,8 @@ static int wakeup_display_graph(struct trace_array *tr, int 
set)
        return start_func_tracer(tr, set);
 }
 
-static int wakeup_graph_entry(struct ftrace_graph_ent *trace)
+static int wakeup_graph_entry(struct ftrace_graph_ent *trace,
+                             struct pt_regs *pt_regs)
 {
        struct trace_array *tr = wakeup_trace;
        struct trace_array_cpu *data;
-- 
2.20.1

Reply via email to