diff options
Diffstat (limited to 'arch/arm64/kernel/stacktrace.c')
-rw-r--r-- | arch/arm64/kernel/stacktrace.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index 4989f7ea1e59..1a29f2695ff2 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c | |||
@@ -59,18 +59,17 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame) | |||
59 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 59 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
60 | if (tsk->ret_stack && | 60 | if (tsk->ret_stack && |
61 | (frame->pc == (unsigned long)return_to_handler)) { | 61 | (frame->pc == (unsigned long)return_to_handler)) { |
62 | if (WARN_ON_ONCE(frame->graph == -1)) | 62 | struct ftrace_ret_stack *ret_stack; |
63 | return -EINVAL; | ||
64 | if (frame->graph < -1) | ||
65 | frame->graph += FTRACE_NOTRACE_DEPTH; | ||
66 | |||
67 | /* | 63 | /* |
68 | * This is a case where function graph tracer has | 64 | * This is a case where function graph tracer has |
69 | * modified a return address (LR) in a stack frame | 65 | * modified a return address (LR) in a stack frame |
70 | * to hook a function return. | 66 | * to hook a function return. |
71 | * So replace it to an original value. | 67 | * So replace it to an original value. |
72 | */ | 68 | */ |
73 | frame->pc = tsk->ret_stack[frame->graph--].ret; | 69 | ret_stack = ftrace_graph_get_ret_stack(tsk, frame->graph++); |
70 | if (WARN_ON_ONCE(!ret_stack)) | ||
71 | return -EINVAL; | ||
72 | frame->pc = ret_stack->ret; | ||
74 | } | 73 | } |
75 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | 74 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
76 | 75 | ||
@@ -137,7 +136,7 @@ void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace) | |||
137 | frame.fp = regs->regs[29]; | 136 | frame.fp = regs->regs[29]; |
138 | frame.pc = regs->pc; | 137 | frame.pc = regs->pc; |
139 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 138 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
140 | frame.graph = current->curr_ret_stack; | 139 | frame.graph = 0; |
141 | #endif | 140 | #endif |
142 | 141 | ||
143 | walk_stackframe(current, &frame, save_trace, &data); | 142 | walk_stackframe(current, &frame, save_trace, &data); |
@@ -168,7 +167,7 @@ static noinline void __save_stack_trace(struct task_struct *tsk, | |||
168 | frame.pc = (unsigned long)__save_stack_trace; | 167 | frame.pc = (unsigned long)__save_stack_trace; |
169 | } | 168 | } |
170 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 169 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
171 | frame.graph = tsk->curr_ret_stack; | 170 | frame.graph = 0; |
172 | #endif | 171 | #endif |
173 | 172 | ||
174 | walk_stackframe(tsk, &frame, save_trace, &data); | 173 | walk_stackframe(tsk, &frame, save_trace, &data); |