2525 *
2626 * The regs must be on a stack currently owned by the calling task.
2727 */
28- static __always_inline void unwind_init_from_regs (struct unwind_state * state ,
29- struct pt_regs * regs )
28+ static __always_inline void
29+ unwind_init_from_regs (struct unwind_state * state ,
30+ struct pt_regs * regs )
3031{
3132 unwind_init_common (state , current );
3233
@@ -42,7 +43,8 @@ static __always_inline void unwind_init_from_regs(struct unwind_state *state,
4243 *
4344 * The function which invokes this must be noinline.
4445 */
45- static __always_inline void unwind_init_from_caller (struct unwind_state * state )
46+ static __always_inline void
47+ unwind_init_from_caller (struct unwind_state * state )
4648{
4749 unwind_init_common (state , current );
4850
@@ -60,23 +62,51 @@ static __always_inline void unwind_init_from_caller(struct unwind_state *state)
6062 * duration of the unwind, or the unwind will be bogus. It is never valid to
6163 * call this for the current task.
6264 */
63- static __always_inline void unwind_init_from_task (struct unwind_state * state ,
64- struct task_struct * task )
65+ static __always_inline void
66+ unwind_init_from_task (struct unwind_state * state ,
67+ struct task_struct * task )
6568{
6669 unwind_init_common (state , task );
6770
6871 state -> fp = thread_saved_fp (task );
6972 state -> pc = thread_saved_pc (task );
7073}
7174
75+ static __always_inline int
76+ unwind_recover_return_address (struct unwind_state * state )
77+ {
78+ #ifdef CONFIG_FUNCTION_GRAPH_TRACER
79+ if (state -> task -> ret_stack &&
80+ (state -> pc == (unsigned long )return_to_handler )) {
81+ unsigned long orig_pc ;
82+ orig_pc = ftrace_graph_ret_addr (state -> task , NULL , state -> pc ,
83+ (void * )state -> fp );
84+ if (WARN_ON_ONCE (state -> pc == orig_pc ))
85+ return - EINVAL ;
86+ state -> pc = orig_pc ;
87+ }
88+ #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
89+
90+ #ifdef CONFIG_KRETPROBES
91+ if (is_kretprobe_trampoline (state -> pc )) {
92+ state -> pc = kretprobe_find_ret_addr (state -> task ,
93+ (void * )state -> fp ,
94+ & state -> kr_cur );
95+ }
96+ #endif /* CONFIG_KRETPROBES */
97+
98+ return 0 ;
99+ }
100+
72101/*
73102 * Unwind from one frame record (A) to the next frame record (B).
74103 *
75104 * We terminate early if the location of B indicates a malformed chain of frame
76105 * records (e.g. a cycle), determined based on the location and fp value of A
77106 * and the location (but not the fp value) of B.
78107 */
79- static int notrace unwind_next (struct unwind_state * state )
108+ static __always_inline int
109+ unwind_next (struct unwind_state * state )
80110{
81111 struct task_struct * tsk = state -> task ;
82112 unsigned long fp = state -> fp ;
@@ -90,37 +120,18 @@ static int notrace unwind_next(struct unwind_state *state)
90120 if (err )
91121 return err ;
92122
93- state -> pc = ptrauth_strip_insn_pac (state -> pc );
94-
95- #ifdef CONFIG_FUNCTION_GRAPH_TRACER
96- if (tsk -> ret_stack &&
97- (state -> pc == (unsigned long )return_to_handler )) {
98- unsigned long orig_pc ;
99- /*
100- * This is a case where function graph tracer has
101- * modified a return address (LR) in a stack frame
102- * to hook a function return.
103- * So replace it to an original value.
104- */
105- orig_pc = ftrace_graph_ret_addr (tsk , NULL , state -> pc ,
106- (void * )state -> fp );
107- if (WARN_ON_ONCE (state -> pc == orig_pc ))
108- return - EINVAL ;
109- state -> pc = orig_pc ;
110- }
111- #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
112- #ifdef CONFIG_KRETPROBES
113- if (is_kretprobe_trampoline (state -> pc ))
114- state -> pc = kretprobe_find_ret_addr (tsk , (void * )state -> fp , & state -> kr_cur );
115- #endif
123+ state -> pc = ptrauth_strip_kernel_insn_pac (state -> pc );
116124
117- return 0 ;
125+ return unwind_recover_return_address ( state ) ;
118126}
119- NOKPROBE_SYMBOL (unwind_next );
120127
121- static void notrace unwind (struct unwind_state * state ,
122- stack_trace_consume_fn consume_entry , void * cookie )
128+ static __always_inline void
129+ unwind (struct unwind_state * state , stack_trace_consume_fn consume_entry ,
130+ void * cookie )
123131{
132+ if (unwind_recover_return_address (state ))
133+ return ;
134+
124135 while (1 ) {
125136 int ret ;
126137
@@ -131,40 +142,6 @@ static void notrace unwind(struct unwind_state *state,
131142 break ;
132143 }
133144}
134- NOKPROBE_SYMBOL (unwind );
135-
136- static bool dump_backtrace_entry (void * arg , unsigned long where )
137- {
138- char * loglvl = arg ;
139- printk ("%s %pSb\n" , loglvl , (void * )where );
140- return true;
141- }
142-
143- void dump_backtrace (struct pt_regs * regs , struct task_struct * tsk ,
144- const char * loglvl )
145- {
146- pr_debug ("%s(regs = %p tsk = %p)\n" , __func__ , regs , tsk );
147-
148- if (regs && user_mode (regs ))
149- return ;
150-
151- if (!tsk )
152- tsk = current ;
153-
154- if (!try_get_task_stack (tsk ))
155- return ;
156-
157- printk ("%sCall trace:\n" , loglvl );
158- arch_stack_walk (dump_backtrace_entry , (void * )loglvl , tsk , regs );
159-
160- put_task_stack (tsk );
161- }
162-
163- void show_stack (struct task_struct * tsk , unsigned long * sp , const char * loglvl )
164- {
165- dump_backtrace (NULL , tsk , loglvl );
166- barrier ();
167- }
168145
169146/*
170147 * Per-cpu stacks are only accessible when unwinding the current task in a
@@ -230,3 +207,36 @@ noinline noinstr void arch_stack_walk(stack_trace_consume_fn consume_entry,
230207
231208 unwind (& state , consume_entry , cookie );
232209}
210+
211+ static bool dump_backtrace_entry (void * arg , unsigned long where )
212+ {
213+ char * loglvl = arg ;
214+ printk ("%s %pSb\n" , loglvl , (void * )where );
215+ return true;
216+ }
217+
218+ void dump_backtrace (struct pt_regs * regs , struct task_struct * tsk ,
219+ const char * loglvl )
220+ {
221+ pr_debug ("%s(regs = %p tsk = %p)\n" , __func__ , regs , tsk );
222+
223+ if (regs && user_mode (regs ))
224+ return ;
225+
226+ if (!tsk )
227+ tsk = current ;
228+
229+ if (!try_get_task_stack (tsk ))
230+ return ;
231+
232+ printk ("%sCall trace:\n" , loglvl );
233+ arch_stack_walk (dump_backtrace_entry , (void * )loglvl , tsk , regs );
234+
235+ put_task_stack (tsk );
236+ }
237+
238+ void show_stack (struct task_struct * tsk , unsigned long * sp , const char * loglvl )
239+ {
240+ dump_backtrace (NULL , tsk , loglvl );
241+ barrier ();
242+ }
0 commit comments