38
38
* @kr_cur: When KRETPROBES is selected, holds the kretprobe instance
39
39
* associated with the most recently encountered replacement lr
40
40
* value.
41
+ *
42
+ * @task: The task being unwound.
41
43
*/
42
44
struct unwind_state {
43
45
unsigned long fp ;
@@ -48,10 +50,13 @@ struct unwind_state {
48
50
#ifdef CONFIG_KRETPROBES
49
51
struct llist_node * kr_cur ;
50
52
#endif
53
+ struct task_struct * task ;
51
54
};
52
55
53
- static void unwind_init_common (struct unwind_state * state )
56
+ static void unwind_init_common (struct unwind_state * state ,
57
+ struct task_struct * task )
54
58
{
59
+ state -> task = task ;
55
60
#ifdef CONFIG_KRETPROBES
56
61
state -> kr_cur = NULL ;
57
62
#endif
@@ -80,7 +85,7 @@ static void unwind_init_common(struct unwind_state *state)
80
85
static inline void unwind_init_from_regs (struct unwind_state * state ,
81
86
struct pt_regs * regs )
82
87
{
83
- unwind_init_common (state );
88
+ unwind_init_common (state , current );
84
89
85
90
state -> fp = regs -> regs [29 ];
86
91
state -> pc = regs -> pc ;
@@ -96,7 +101,7 @@ static inline void unwind_init_from_regs(struct unwind_state *state,
96
101
*/
97
102
static __always_inline void unwind_init_from_caller (struct unwind_state * state )
98
103
{
99
- unwind_init_common (state );
104
+ unwind_init_common (state , current );
100
105
101
106
state -> fp = (unsigned long )__builtin_frame_address (1 );
102
107
state -> pc = (unsigned long )__builtin_return_address (0 );
@@ -115,7 +120,7 @@ static __always_inline void unwind_init_from_caller(struct unwind_state *state)
115
120
static inline void unwind_init_from_task (struct unwind_state * state ,
116
121
struct task_struct * task )
117
122
{
118
- unwind_init_common (state );
123
+ unwind_init_common (state , task );
119
124
120
125
state -> fp = thread_saved_fp (task );
121
126
state -> pc = thread_saved_pc (task );
@@ -128,9 +133,9 @@ static inline void unwind_init_from_task(struct unwind_state *state,
128
133
* records (e.g. a cycle), determined based on the location and fp value of A
129
134
* and the location (but not the fp value) of B.
130
135
*/
131
- static int notrace unwind_next (struct task_struct * tsk ,
132
- struct unwind_state * state )
136
+ static int notrace unwind_next (struct unwind_state * state )
133
137
{
138
+ struct task_struct * tsk = state -> task ;
134
139
unsigned long fp = state -> fp ;
135
140
struct stack_info info ;
136
141
@@ -204,16 +209,15 @@ static int notrace unwind_next(struct task_struct *tsk,
204
209
}
205
210
NOKPROBE_SYMBOL (unwind_next );
206
211
207
- static void notrace unwind (struct task_struct * tsk ,
208
- struct unwind_state * state ,
212
+ static void notrace unwind (struct unwind_state * state ,
209
213
stack_trace_consume_fn consume_entry , void * cookie )
210
214
{
211
215
while (1 ) {
212
216
int ret ;
213
217
214
218
if (!consume_entry (cookie , state -> pc ))
215
219
break ;
216
- ret = unwind_next (tsk , state );
220
+ ret = unwind_next (state );
217
221
if (ret < 0 )
218
222
break ;
219
223
}
@@ -259,12 +263,15 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
259
263
{
260
264
struct unwind_state state ;
261
265
262
- if (regs )
266
+ if (regs ) {
267
+ if (task != current )
268
+ return ;
263
269
unwind_init_from_regs (& state , regs );
264
- else if (task == current )
270
+ } else if (task == current ) {
265
271
unwind_init_from_caller (& state );
266
- else
272
+ } else {
267
273
unwind_init_from_task (& state , task );
274
+ }
268
275
269
- unwind (task , & state , consume_entry , cookie );
276
+ unwind (& state , consume_entry , cookie );
270
277
}
0 commit comments