~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arc/kernel/stacktrace.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/arc/kernel/stacktrace.c (Version linux-6.12-rc7) and /arch/sparc64/kernel/stacktrace.c (Version linux-4.11.12)


  1 // SPDX-License-Identifier: GPL-2.0-only            1 
  2 /*                                                
  3  *      stacktrace.c : stacktracing APIs neede    
  4  *                      (wrappers over ARC dwa    
  5  *                                                
  6  * Copyright (C) 2004, 2007-2010, 2011-2012 Sy    
  7  *                                                
  8  *  vineetg: aug 2009                             
  9  *  -Implemented CONFIG_STACKTRACE APIs, prima    
 10  *   for displaying task's kernel mode call st    
 11  *  -Iterator based approach to have single co    
 12  *   needing unwinding, implement the logic in    
 13  *      = which frame onwards to start capture    
 14  *      = which frame to stop capturing (wchan    
 15  *      = specifics of data structs where trac    
 16  *                                                
 17  *  vineetg: March 2009                           
 18  *  -Implemented correct versions of thread_sa    
 19  *                                                
 20  *  rajeshwarr: 2008                              
 21  *  -Initial implementation                       
 22  */                                               
 23                                                   
 24 #include <linux/ptrace.h>                         
 25 #include <linux/export.h>                         
 26 #include <linux/stacktrace.h>                     
 27 #include <linux/kallsyms.h>                       
 28 #include <linux/sched/debug.h>                    
 29                                                   
 30 #include <asm/arcregs.h>                          
 31 #include <asm/unwind.h>                           
 32 #include <asm/stacktrace.h>                       
 33 #include <asm/switch_to.h>                        
 34                                                   
 35 /*--------------------------------------------    
 36  *              Unwinder Iterator                 
 37  *--------------------------------------------    
 38  */                                               
 39                                                   
 40 #ifdef CONFIG_ARC_DW2_UNWIND                      
 41                                                   
 42 static int                                        
 43 seed_unwind_frame_info(struct task_struct *tsk    
 44                        struct unwind_frame_inf    
 45 {                                                 
 46         if (regs) {                               
 47                 /*                                
 48                  * Asynchronous unwinding of i    
 49                  *  - Just uses the pt_regs pa    
 50                  */                               
 51                 frame_info->task = tsk;           
 52                                                   
 53                 frame_info->regs.r27 = regs->f    
 54                 frame_info->regs.r28 = regs->s    
 55                 frame_info->regs.r31 = regs->b    
 56                 frame_info->regs.r63 = regs->r    
 57                 frame_info->call_frame = 0;       
 58         } else if (tsk == NULL || tsk == curre    
 59                 /*                                
 60                  * synchronous unwinding (e.g.    
 61                  *  - uses current values of S    
 62                  */                               
 63                 unsigned long fp, sp, blink, r    
 64                 frame_info->task = current;       
 65                                                   
 66                 __asm__ __volatile__(             
 67                         "mov %0,r27\n\t"          
 68                         "mov %1,r28\n\t"          
 69                         "mov %2,r31\n\t"          
 70                         "mov %3,r63\n\t"          
 71                         : "=r"(fp), "=r"(sp),     
 72                 );                                
 73                                                   
 74                 frame_info->regs.r27 = fp;        
 75                 frame_info->regs.r28 = sp;        
 76                 frame_info->regs.r31 = blink;     
 77                 frame_info->regs.r63 = ret;       
 78                 frame_info->call_frame = 0;       
 79         } else {                                  
 80                 /*                                
 81                  * Asynchronous unwinding of a    
 82                  *  - first ensure it is actua    
 83                  *  - if so, it will be in __s    
 84                  *    is safe-kept and BLINK a    
 85                  */                               
 86                                                   
 87                 if (task_is_running(tsk))         
 88                         return -1;                
 89                                                   
 90                 frame_info->task = tsk;           
 91                                                   
 92                 frame_info->regs.r27 = TSK_K_F    
 93                 frame_info->regs.r28 = TSK_K_E    
 94                 frame_info->regs.r31 = TSK_K_B    
 95                 frame_info->regs.r63 = (unsign    
 96                                                   
 97                 /* In the prologue of __switch    
 98                  * and then SP is copied to FP    
 99                  * but we didn't save FP. The     
100                  * state in previous frame.       
101                  * As a work around for this,     
102                  * and adjust SP accordingly.     
103                  * __switch_to macro is dwarf     
104                  * assembly code                  
105                  */                               
106                 frame_info->regs.r27 = 0;         
107                 frame_info->regs.r28 += 60;       
108                 frame_info->call_frame = 0;       
109                                                   
110         }                                         
111         return 0;                                 
112 }                                                 
113                                                   
114 #endif                                            
115                                                   
116 notrace noinline unsigned int                     
117 arc_unwind_core(struct task_struct *tsk, struc    
118                 int (*consumer_fn) (unsigned i    
119 {                                                 
120 #ifdef CONFIG_ARC_DW2_UNWIND                      
121         int ret = 0, cnt = 0;                     
122         unsigned int address;                     
123         struct unwind_frame_info frame_info;      
124                                                   
125         if (seed_unwind_frame_info(tsk, regs,     
126                 return 0;                         
127                                                   
128         while (1) {                               
129                 address = UNW_PC(&frame_info);    
130                                                   
131                 if (!address || !__kernel_text    
132                         break;                    
133                                                   
134                 if (consumer_fn(address, arg)     
135                         break;                    
136                                                   
137                 ret = arc_unwind(&frame_info);    
138                 if (ret)                          
139                         break;                    
140                                                   
141                 frame_info.regs.r63 = frame_in    
142                                                   
143                 if (cnt++ > 128) {                
144                         printk("unwinder loopi    
145                         return 0;                 
146                 }                                 
147         }                                         
148                                                   
149         return address;         /* return the     
150 #else                                             
151         /* On ARC, only Dward based unwinder w    
152          * not possible (-fno-omit-frame-point    
153          * prologue is setup (callee regs save    
154          * way around                             
155          */                                       
156         pr_warn_once("CONFIG_ARC_DW2_UNWIND ne    
157         return 0;                                 
158                                                   
159 #endif                                            
160 }                                                 
161                                                   
162 /*--------------------------------------------    
163  * callbacks called by unwinder iterator to im    
164  *                                                
165  * The callback can return -1 to force the ite    
166  * keeps going till the bottom-most frame.        
167  *--------------------------------------------    
168  */                                               
169                                                   
170 /* Call-back which plugs into unwinding core t    
171  * case of panic/OOPs/BUG etc                     
172  */                                               
173 static int __print_sym(unsigned int address, v    
174 {                                                 
175         const char *loglvl = arg;                 
176                                                   
177         printk("%s  %pS\n", loglvl, (void *)ad    
178         return 0;                                 
179 }                                                 
180                                                   
181 #ifdef CONFIG_STACKTRACE                          
182                                                   
183 /* Call-back which plugs into unwinding core t    
184  * traces needed by kernel on /proc/<pid>/stac    
185  */                                               
186 static int __collect_all(unsigned int address,    
187 {                                                 
188         struct stack_trace *trace = arg;          
189                                                   
190         if (trace->skip > 0)                      
191                 trace->skip--;                    
192         else                                      
193                 trace->entries[trace->nr_entri    
194                                                   
195         if (trace->nr_entries >= trace->max_en    
196                 return -1;                        
197                                                   
198         return 0;                                 
199 }                                                 
200                                                   
201 static int __collect_all_but_sched(unsigned in    
202 {                                                 
203         struct stack_trace *trace = arg;          
204                                                   
205         if (in_sched_functions(address))          
206                 return 0;                         
207                                                   
208         if (trace->skip > 0)                      
209                 trace->skip--;                    
210         else                                      
211                 trace->entries[trace->nr_entri    
212                                                   
213         if (trace->nr_entries >= trace->max_en    
214                 return -1;                        
215                                                   
216         return 0;                                 
217 }                                                 
218                                                   
219 #endif                                            
220                                                   
221 static int __get_first_nonsched(unsigned int a    
222 {                                                 
223         if (in_sched_functions(address))          
224                 return 0;                         
225                                                   
226         return -1;                                
227 }                                                 
228                                                   
229 /*--------------------------------------------    
230  *              APIs expected by various kerne    
231  *--------------------------------------------    
232  */                                               
233                                                   
234 noinline void show_stacktrace(struct task_stru    
235                               const char *logl    
236 {                                                 
237         printk("%s\nStack Trace:\n", loglvl);     
238         arc_unwind_core(tsk, regs, __print_sym    
239 }                                                 
240 EXPORT_SYMBOL(show_stacktrace);                   
241                                                   
242 /* Expected by sched Code */                      
243 void show_stack(struct task_struct *tsk, unsig    
244 {                                                 
245         show_stacktrace(tsk, NULL, loglvl);       
246 }                                                 
247                                                   
248 /* Another API expected by schedular, shows up    
249  * Of course just returning schedule( ) would     
250  * the function is not in schedular code          
251  */                                               
252 unsigned int __get_wchan(struct task_struct *t    
253 {                                                 
254         return arc_unwind_core(tsk, NULL, __ge    
255 }                                                 
256                                                   
257 #ifdef CONFIG_STACKTRACE                          
258                                                   
259 /*                                                
260  * API required by CONFIG_STACKTRACE, CONFIG_L    
261  * A typical use is when /proc/<pid>/stack is     
262  */                                               
263 void save_stack_trace_tsk(struct task_struct *    
264 {                                                 
265         /* Assumes @tsk is sleeping so unwinds    
266         arc_unwind_core(tsk, NULL, __collect_a    
267 }                                                 
268                                                   
269 void save_stack_trace(struct stack_trace *trac    
270 {                                                 
271         /* Pass NULL for task so it unwinds th    
272         arc_unwind_core(NULL, NULL, __collect_    
273 }                                                 
274 EXPORT_SYMBOL_GPL(save_stack_trace);              
275 #endif                                            
276                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php