Function graph tracer has modified the return address to
'return_to_handler' on stack, and provide the 'ftrace_graph_ret_addr' to
get the real return address.

Signed-off-by: Zong Li <z...@andestech.com>
---
 arch/nds32/kernel/stacktrace.c |  4 ++++
 arch/nds32/kernel/traps.c      | 30 ++++++------------------------
 2 files changed, 10 insertions(+), 24 deletions(-)

diff --git a/arch/nds32/kernel/stacktrace.c b/arch/nds32/kernel/stacktrace.c
index 8b231e9..36bc870 100644
--- a/arch/nds32/kernel/stacktrace.c
+++ b/arch/nds32/kernel/stacktrace.c
@@ -4,6 +4,7 @@
 #include <linux/sched/debug.h>
 #include <linux/sched/task_stack.h>
 #include <linux/stacktrace.h>
+#include <linux/ftrace.h>
 
 void save_stack_trace(struct stack_trace *trace)
 {
@@ -16,6 +17,7 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct 
stack_trace *trace)
        unsigned long *fpn;
        int skip = trace->skip;
        int savesched;
+       int graph_idx = 0;
 
        if (tsk == current) {
                __asm__ __volatile__("\tori\t%0, $fp, #0\n":"=r"(fpn));
@@ -33,6 +35,8 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct 
stack_trace *trace)
                fpp = fpn[FP_OFFSET];
                if (!__kernel_text_address(lpp))
                        break;
+               else
+                       lpp = ftrace_graph_ret_addr(tsk, &graph_idx, lpp, NULL);
 
                if (savesched || !in_sched_functions(lpp)) {
                        if (skip) {
diff --git a/arch/nds32/kernel/traps.c b/arch/nds32/kernel/traps.c
index f0e9743..7684c8f 100644
--- a/arch/nds32/kernel/traps.c
+++ b/arch/nds32/kernel/traps.c
@@ -8,6 +8,7 @@
 #include <linux/kdebug.h>
 #include <linux/sched/task_stack.h>
 #include <linux/uaccess.h>
+#include <linux/ftrace.h>
 
 #include <asm/proc-fns.h>
 #include <asm/unistd.h>
@@ -94,28 +95,6 @@ static void dump_instr(struct pt_regs *regs)
        set_fs(fs);
 }
 
-#ifdef CONFIG_FUNCTION_GRAPH_TRACER
-#include <linux/ftrace.h>
-static void
-get_real_ret_addr(unsigned long *addr, struct task_struct *tsk, int *graph)
-{
-       if (*addr == (unsigned long)return_to_handler) {
-               int index = tsk->curr_ret_stack;
-
-               if (tsk->ret_stack && index >= *graph) {
-                       index -= *graph;
-                       *addr = tsk->ret_stack[index].ret;
-                       (*graph)++;
-               }
-       }
-}
-#else
-static inline void
-get_real_ret_addr(unsigned long *addr, struct task_struct *tsk, int *graph)
-{
-}
-#endif
-
 #define LOOP_TIMES (100)
 static void __dump(struct task_struct *tsk, unsigned long *base_reg)
 {
@@ -126,7 +105,8 @@ static void __dump(struct task_struct *tsk, unsigned long 
*base_reg)
                while (!kstack_end(base_reg)) {
                        ret_addr = *base_reg++;
                        if (__kernel_text_address(ret_addr)) {
-                               get_real_ret_addr(&ret_addr, tsk, &graph);
+                               ret_addr = ftrace_graph_ret_addr(
+                                               tsk, &graph, ret_addr, NULL);
                                print_ip_sym(ret_addr);
                        }
                        if (--cnt < 0)
@@ -145,7 +125,9 @@ static void __dump(struct task_struct *tsk, unsigned long 
*base_reg)
                        next_fp = base_reg[FP_OFFSET];
 #endif
                        if (__kernel_text_address(ret_addr)) {
-                               get_real_ret_addr(&ret_addr, tsk, &graph);
+
+                               ret_addr = ftrace_graph_ret_addr(
+                                               tsk, &graph, ret_addr, NULL);
                                print_ip_sym(ret_addr);
                        }
                        if (--cnt < 0)
-- 
2.7.4

Reply via email to