Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/arch/x86/kernel/ds_selftest.c (Version 2.6.31.13) and /linux/arch/i386/kernel/ds_selftest.c (Version 2.6.11.8)


  1 /*                                                  1 
  2  * Debug Store support - selftest                 
  3  *                                                
  4  *                                                
  5  * Copyright (C) 2009 Intel Corporation.          
  6  * Markus Metzger <markus.t.metzger@intel.com>    
  7  */                                               
  8                                                   
  9 #include "ds_selftest.h"                          
 10                                                   
 11 #include <linux/kernel.h>                         
 12 #include <linux/string.h>                         
 13 #include <linux/smp.h>                            
 14 #include <linux/cpu.h>                            
 15                                                   
 16 #include <asm/ds.h>                               
 17                                                   
 18                                                   
 19 #define BUFFER_SIZE             521     /* Int    
 20 #define SMALL_BUFFER_SIZE       24      /* A s    
 21                                                   
 22 struct ds_selftest_bts_conf {                     
 23         struct bts_tracer *tracer;                
 24         int error;                                
 25         int (*suspend)(struct bts_tracer *);      
 26         int (*resume)(struct bts_tracer *);       
 27 };                                                
 28                                                   
 29 static int ds_selftest_bts_consistency(const s    
 30 {                                                 
 31         int error = 0;                            
 32                                                   
 33         if (!trace) {                             
 34                 printk(KERN_CONT "failed to ac    
 35                 /* Bail out. Other tests are p    
 36                 return -1;                        
 37         }                                         
 38                                                   
 39         if (!trace->read) {                       
 40                 printk(KERN_CONT "bts read not    
 41                 error = -1;                       
 42         }                                         
 43                                                   
 44         /* Do some sanity checks on the trace     
 45         if (!trace->ds.n) {                       
 46                 printk(KERN_CONT "empty bts bu    
 47                 error = -1;                       
 48         }                                         
 49         if (!trace->ds.size) {                    
 50                 printk(KERN_CONT "bad bts trac    
 51                 error = -1;                       
 52         }                                         
 53         if (trace->ds.end !=                      
 54             (char *)trace->ds.begin + (trace->    
 55                 printk(KERN_CONT "bad bts buff    
 56                 error = -1;                       
 57         }                                         
 58         /*                                        
 59          * We allow top in [begin; end], since    
 60          * overflow adjustment happens: after     
 61          * write.                                 
 62          */                                       
 63         if ((trace->ds.top < trace->ds.begin)     
 64             (trace->ds.end < trace->ds.top)) {    
 65                 printk(KERN_CONT "bts top out     
 66                 error = -1;                       
 67         }                                         
 68                                                   
 69         return error;                             
 70 }                                                 
 71                                                   
 72 static int ds_selftest_bts_read(struct bts_tra    
 73                                 const struct b    
 74                                 const void *fr    
 75 {                                                 
 76         const unsigned char *at;                  
 77                                                   
 78         /*                                        
 79          * Check a few things which do not bel    
 80          * They should be covered by other tes    
 81          */                                       
 82         if (!trace)                               
 83                 return -1;                        
 84                                                   
 85         if (!trace->read)                         
 86                 return -1;                        
 87                                                   
 88         if (to < from)                            
 89                 return -1;                        
 90                                                   
 91         if (from < trace->ds.begin)               
 92                 return -1;                        
 93                                                   
 94         if (trace->ds.end < to)                   
 95                 return -1;                        
 96                                                   
 97         if (!trace->ds.size)                      
 98                 return -1;                        
 99                                                   
100         /* Now to the test itself. */             
101         for (at = from; (void *)at < to; at +=    
102                 struct bts_struct bts;            
103                 unsigned long index;              
104                 int error;                        
105                                                   
106                 if (((void *)at - trace->ds.be    
107                         printk(KERN_CONT          
108                                "read from non-    
109                         return -1;                
110                 }                                 
111                 index = ((void *)at - trace->d    
112                                                   
113                 memset(&bts, 0, sizeof(bts));     
114                 error = trace->read(tracer, at    
115                 if (error < 0) {                  
116                         printk(KERN_CONT          
117                                "error reading     
118                                index, at);        
119                         return error;             
120                 }                                 
121                                                   
122                 switch (bts.qualifier) {          
123                 case BTS_BRANCH:                  
124                         break;                    
125                 default:                          
126                         printk(KERN_CONT          
127                                "unexpected bts    
128                                bts.qualifier,     
129                         return -1;                
130                 }                                 
131         }                                         
132                                                   
133         return 0;                                 
134 }                                                 
135                                                   
136 static void ds_selftest_bts_cpu(void *arg)        
137 {                                                 
138         struct ds_selftest_bts_conf *conf = ar    
139         const struct bts_trace *trace;            
140         void *top;                                
141                                                   
142         if (IS_ERR(conf->tracer)) {               
143                 conf->error = PTR_ERR(conf->tr    
144                 conf->tracer = NULL;              
145                                                   
146                 printk(KERN_CONT                  
147                        "initialization failed     
148                 return;                           
149         }                                         
150                                                   
151         /* We should meanwhile have enough tra    
152         conf->error = conf->suspend(conf->trac    
153         if (conf->error < 0)                      
154                 return;                           
155                                                   
156         /* Let's see if we can access the trac    
157         trace = ds_read_bts(conf->tracer);        
158                                                   
159         conf->error = ds_selftest_bts_consiste    
160         if (conf->error < 0)                      
161                 return;                           
162                                                   
163         /* If everything went well, we should     
164         if (trace->ds.top == trace->ds.begin)     
165                 /*                                
166                  * It is possible but highly u    
167                  * buffer overflow and end up     
168                  * position we started from.      
169                  * Let's issue a warning, but     
170                  */                               
171                 printk(KERN_CONT "no trace/ove    
172         }                                         
173                                                   
174         /* Let's try to read the trace we coll    
175         conf->error =                             
176                 ds_selftest_bts_read(conf->tra    
177                                      trace->ds    
178         if (conf->error < 0)                      
179                 return;                           
180                                                   
181         /*                                        
182          * Let's read the trace again.            
183          * Since we suspended tracing, we shou    
184          */                                       
185         top = trace->ds.top;                      
186                                                   
187         trace = ds_read_bts(conf->tracer);        
188         conf->error = ds_selftest_bts_consiste    
189         if (conf->error < 0)                      
190                 return;                           
191                                                   
192         if (top != trace->ds.top) {               
193                 printk(KERN_CONT "suspend not     
194                 conf->error = -1;                 
195                 return;                           
196         }                                         
197                                                   
198         /* Let's collect some more trace - see    
199         conf->error = conf->resume(conf->trace    
200         if (conf->error < 0)                      
201                 return;                           
202                                                   
203         conf->error = conf->suspend(conf->trac    
204         if (conf->error < 0)                      
205                 return;                           
206                                                   
207         trace = ds_read_bts(conf->tracer);        
208                                                   
209         conf->error = ds_selftest_bts_consiste    
210         if (conf->error < 0)                      
211                 return;                           
212                                                   
213         if (trace->ds.top == top) {               
214                 /*                                
215                  * It is possible but highly u    
216                  * buffer overflow and end up     
217                  * position we started from.      
218                  * Let's issue a warning and c    
219                  */                               
220                 printk(KERN_CONT                  
221                        "no resume progress/ove    
222                                                   
223                 conf->error =                     
224                         ds_selftest_bts_read(c    
225                                              t    
226         } else if (trace->ds.top < top) {         
227                 /*                                
228                  * We had a buffer overflow -     
229                  * contain trace records.         
230                  */                               
231                 conf->error =                     
232                         ds_selftest_bts_read(c    
233                                              t    
234         } else {                                  
235                 /*                                
236                  * It is quite likely that the    
237                  * Let's just check the delta     
238                  */                               
239                 conf->error =                     
240                         ds_selftest_bts_read(c    
241                                              t    
242         }                                         
243         if (conf->error < 0)                      
244                 return;                           
245                                                   
246         conf->error = 0;                          
247 }                                                 
248                                                   
249 static int ds_suspend_bts_wrap(struct bts_trac    
250 {                                                 
251         ds_suspend_bts(tracer);                   
252         return 0;                                 
253 }                                                 
254                                                   
255 static int ds_resume_bts_wrap(struct bts_trace    
256 {                                                 
257         ds_resume_bts(tracer);                    
258         return 0;                                 
259 }                                                 
260                                                   
261 static void ds_release_bts_noirq_wrap(void *tr    
262 {                                                 
263         (void)ds_release_bts_noirq(tracer);       
264 }                                                 
265                                                   
266 static int ds_selftest_bts_bad_release_noirq(i    
267                                              s    
268 {                                                 
269         int error = -EPERM;                       
270                                                   
271         /* Try to release the tracer on the wr    
272         get_cpu();                                
273         if (cpu != smp_processor_id()) {          
274                 error = ds_release_bts_noirq(t    
275                 if (error != -EPERM)              
276                         printk(KERN_CONT "rele    
277         }                                         
278         put_cpu();                                
279                                                   
280         return error ? 0 : -1;                    
281 }                                                 
282                                                   
283 static int ds_selftest_bts_bad_request_cpu(int    
284 {                                                 
285         struct bts_tracer *tracer;                
286         int error;                                
287                                                   
288         /* Try to request cpu tracing while ta    
289         tracer = ds_request_bts_cpu(cpu, buffe    
290                                     (size_t)-1    
291         error = PTR_ERR(tracer);                  
292         if (!IS_ERR(tracer)) {                    
293                 ds_release_bts(tracer);           
294                 error = 0;                        
295         }                                         
296                                                   
297         if (error != -EPERM)                      
298                 printk(KERN_CONT "cpu/task tra    
299                                                   
300         return error ? 0 : -1;                    
301 }                                                 
302                                                   
303 static int ds_selftest_bts_bad_request_task(vo    
304 {                                                 
305         struct bts_tracer *tracer;                
306         int error;                                
307                                                   
308         /* Try to request cpu tracing while ta    
309         tracer = ds_request_bts_task(current,     
310                                     (size_t)-1    
311         error = PTR_ERR(tracer);                  
312         if (!IS_ERR(tracer)) {                    
313                 error = 0;                        
314                 ds_release_bts(tracer);           
315         }                                         
316                                                   
317         if (error != -EPERM)                      
318                 printk(KERN_CONT "task/cpu tra    
319                                                   
320         return error ? 0 : -1;                    
321 }                                                 
322                                                   
323 int ds_selftest_bts(void)                         
324 {                                                 
325         struct ds_selftest_bts_conf conf;         
326         unsigned char buffer[BUFFER_SIZE], *sm    
327         unsigned long irq;                        
328         int cpu;                                  
329                                                   
330         printk(KERN_INFO "[ds] bts selftest...    
331         conf.error = 0;                           
332                                                   
333         small_buffer = (unsigned char *)ALIGN(    
334                                                   
335         get_online_cpus();                        
336         for_each_online_cpu(cpu) {                
337                 conf.suspend = ds_suspend_bts_    
338                 conf.resume = ds_resume_bts_wr    
339                 conf.tracer =                     
340                         ds_request_bts_cpu(cpu    
341                                            NUL    
342                 ds_selftest_bts_cpu(&conf);       
343                 if (conf.error >= 0)              
344                         conf.error = ds_selfte    
345                 ds_release_bts(conf.tracer);      
346                 if (conf.error < 0)               
347                         goto out;                 
348                                                   
349                 conf.suspend = ds_suspend_bts_    
350                 conf.resume = ds_resume_bts_no    
351                 conf.tracer =                     
352                         ds_request_bts_cpu(cpu    
353                                            NUL    
354                 smp_call_function_single(cpu,     
355                 if (conf.error >= 0) {            
356                         conf.error =              
357                                 ds_selftest_bt    
358                                                   
359                         /* We must not release    
360                         if (conf.error < 0)       
361                                 conf.tracer =     
362                 }                                 
363                 if (conf.error >= 0)              
364                         conf.error = ds_selfte    
365                 smp_call_function_single(cpu,     
366                                          conf.    
367                 if (conf.error < 0)               
368                         goto out;                 
369         }                                         
370                                                   
371         conf.suspend = ds_suspend_bts_wrap;       
372         conf.resume = ds_resume_bts_wrap;         
373         conf.tracer =                             
374                 ds_request_bts_task(current, b    
375                                     NULL, (siz    
376         ds_selftest_bts_cpu(&conf);               
377         if (conf.error >= 0)                      
378                 conf.error = ds_selftest_bts_b    
379         ds_release_bts(conf.tracer);              
380         if (conf.error < 0)                       
381                 goto out;                         
382                                                   
383         conf.suspend = ds_suspend_bts_noirq;      
384         conf.resume = ds_resume_bts_noirq;        
385         conf.tracer =                             
386                 ds_request_bts_task(current, s    
387                                    NULL, (size    
388         local_irq_save(irq);                      
389         ds_selftest_bts_cpu(&conf);               
390         if (conf.error >= 0)                      
391                 conf.error = ds_selftest_bts_b    
392         ds_release_bts_noirq(conf.tracer);        
393         local_irq_restore(irq);                   
394         if (conf.error < 0)                       
395                 goto out;                         
396                                                   
397         conf.error = 0;                           
398  out:                                             
399         put_online_cpus();                        
400         printk(KERN_CONT "%s.\n", (conf.error     
401                                                   
402         return conf.error;                        
403 }                                                 
404                                                   
405 int ds_selftest_pebs(void)                        
406 {                                                 
407         return 0;                                 
408 }                                                 
409                                                   
  This page was automatically generated by the LXR engine.