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

TOMOYO Linux Cross Reference
Linux/arch/parisc/kernel/ptrace.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/parisc/kernel/ptrace.c (Version linux-6.12-rc7) and /arch/ppc/kernel/ptrace.c (Version linux-4.15.18)


  1 // SPDX-License-Identifier: GPL-2.0                 1 
  2 /*                                                
  3  * Kernel support for the ptrace() and syscall    
  4  *                                                
  5  * Copyright (C) 2000 Hewlett-Packard Co, Linu    
  6  * Copyright (C) 2000 Matthew Wilcox <matthew@    
  7  * Copyright (C) 2000 David Huggins-Daines <dh    
  8  * Copyright (C) 2008-2016 Helge Deller <delle    
  9  */                                               
 10                                                   
 11 #include <linux/kernel.h>                         
 12 #include <linux/sched.h>                          
 13 #include <linux/mm.h>                             
 14 #include <linux/smp.h>                            
 15 #include <linux/elf.h>                            
 16 #include <linux/errno.h>                          
 17 #include <linux/ptrace.h>                         
 18 #include <linux/user.h>                           
 19 #include <linux/personality.h>                    
 20 #include <linux/regset.h>                         
 21 #include <linux/security.h>                       
 22 #include <linux/seccomp.h>                        
 23 #include <linux/compat.h>                         
 24 #include <linux/signal.h>                         
 25 #include <linux/audit.h>                          
 26                                                   
 27 #include <linux/uaccess.h>                        
 28 #include <asm/processor.h>                        
 29 #include <asm/asm-offsets.h>                      
 30                                                   
 31 /* PSW bits we allow the debugger to modify */    
 32 #define USER_PSW_BITS   (PSW_N | PSW_B | PSW_V    
 33                                                   
 34 #define CREATE_TRACE_POINTS                       
 35 #include <trace/events/syscalls.h>                
 36                                                   
 37 /*                                                
 38  * These are our native regset flavors.           
 39  */                                               
 40 enum parisc_regset {                              
 41         REGSET_GENERAL,                           
 42         REGSET_FP                                 
 43 };                                                
 44                                                   
 45 /*                                                
 46  * Called by kernel/ptrace.c when detaching..     
 47  *                                                
 48  * Make sure single step bits etc are not set.    
 49  */                                               
 50 void ptrace_disable(struct task_struct *task)     
 51 {                                                 
 52         clear_tsk_thread_flag(task, TIF_SINGLE    
 53         clear_tsk_thread_flag(task, TIF_BLOCKS    
 54                                                   
 55         /* make sure the trap bits are not set    
 56         pa_psw(task)->r = 0;                      
 57         pa_psw(task)->t = 0;                      
 58         pa_psw(task)->h = 0;                      
 59         pa_psw(task)->l = 0;                      
 60 }                                                 
 61                                                   
 62 /*                                                
 63  * The following functions are called by ptrac    
 64  * enabling or disabling single/block tracing.    
 65  */                                               
 66 void user_disable_single_step(struct task_stru    
 67 {                                                 
 68         ptrace_disable(task);                     
 69 }                                                 
 70                                                   
 71 void user_enable_single_step(struct task_struc    
 72 {                                                 
 73         clear_tsk_thread_flag(task, TIF_BLOCKS    
 74         set_tsk_thread_flag(task, TIF_SINGLEST    
 75                                                   
 76         if (pa_psw(task)->n) {                    
 77                 /* Nullified, just crank over     
 78                 task_regs(task)->iaoq[0] = tas    
 79                 task_regs(task)->iasq[0] = tas    
 80                 task_regs(task)->iaoq[1] = tas    
 81                 pa_psw(task)->n = 0;              
 82                 pa_psw(task)->x = 0;              
 83                 pa_psw(task)->y = 0;              
 84                 pa_psw(task)->z = 0;              
 85                 pa_psw(task)->b = 0;              
 86                 ptrace_disable(task);             
 87                 /* Don't wake up the task, but    
 88                    parent know something happe    
 89                 force_sig_fault_to_task(SIGTRA    
 90                                         (void     
 91                                         task);    
 92                 /* notify_parent(task, SIGCHLD    
 93                 return;                           
 94         }                                         
 95                                                   
 96         /* Enable recovery counter traps.  The    
 97          * itself will be set to zero on a tas    
 98          * task is suspended on a syscall then    
 99          * path will overwrite the recovery co    
100          * value such that it traps once back     
101          * disable interrupts in the tasks PSW    
102          * interrupts while the recovery count    
103          */                                       
104         pa_psw(task)->r = 1;                      
105         pa_psw(task)->t = 0;                      
106         pa_psw(task)->h = 0;                      
107         pa_psw(task)->l = 0;                      
108 }                                                 
109                                                   
110 void user_enable_block_step(struct task_struct    
111 {                                                 
112         clear_tsk_thread_flag(task, TIF_SINGLE    
113         set_tsk_thread_flag(task, TIF_BLOCKSTE    
114                                                   
115         /* Enable taken branch trap. */           
116         pa_psw(task)->r = 0;                      
117         pa_psw(task)->t = 1;                      
118         pa_psw(task)->h = 0;                      
119         pa_psw(task)->l = 0;                      
120 }                                                 
121                                                   
122 long arch_ptrace(struct task_struct *child, lo    
123                  unsigned long addr, unsigned     
124 {                                                 
125         unsigned long __user *datap = (unsigne    
126         unsigned long tmp;                        
127         long ret = -EIO;                          
128                                                   
129         unsigned long user_regs_struct_size =     
130 #ifdef CONFIG_64BIT                               
131         if (is_compat_task())                     
132                 user_regs_struct_size /= 2;       
133 #endif                                            
134                                                   
135         switch (request) {                        
136                                                   
137         /* Read the word at location addr in t    
138            processes, the kernel saves all reg    
139         case PTRACE_PEEKUSR:                      
140                 if ((addr & (sizeof(unsigned l    
141                      addr >= sizeof(struct pt_    
142                         break;                    
143                 tmp = *(unsigned long *) ((cha    
144                 ret = put_user(tmp, datap);       
145                 break;                            
146                                                   
147         /* Write the word at location addr in     
148            to change when the kernel no longer    
149            FIXME.  There is a problem at the m    
150            saved if the process is ptraced on     
151            those values are overwritten by act    
152            exit. */                               
153         case PTRACE_POKEUSR:                      
154                 /* Some register values writte    
155                  * entry.S:syscall_restore_rfi    
156                  * r31/r31+4, and not with the    
157                  */                               
158                 if (addr == PT_PSW) {             
159                         /* Allow writing to Nu    
160                          * and carry/borrow bi    
161                          * BEWARE, if you set     
162                          * stop on the nullifi    
163                          */                       
164                         data &= USER_PSW_BITS;    
165                         task_regs(child)->gr[0    
166                         task_regs(child)->gr[0    
167                         ret = 0;                  
168                         break;                    
169                 }                                 
170                                                   
171                 if ((addr & (sizeof(unsigned l    
172                      addr >= sizeof(struct pt_    
173                         break;                    
174                 if (addr == PT_IAOQ0 || addr =    
175                         data |= PRIV_USER; /*     
176                 }                                 
177                 if ((addr >= PT_GR1 && addr <=    
178                                 addr == PT_IAO    
179                                 (addr >= PT_FR    
180                                 addr == PT_SAR    
181                         *(unsigned long *) ((c    
182                         ret = 0;                  
183                 }                                 
184                 break;                            
185                                                   
186         case PTRACE_GETREGS:    /* Get all gp     
187                 return copy_regset_to_user(chi    
188                                            tas    
189                                            REG    
190                                            0,     
191                                            dat    
192                                                   
193         case PTRACE_SETREGS:    /* Set all gp     
194                 return copy_regset_from_user(c    
195                                              t    
196                                              R    
197                                              0    
198                                              d    
199                                                   
200         case PTRACE_GETFPREGS:  /* Get the chi    
201                 return copy_regset_to_user(chi    
202                                            tas    
203                                            REG    
204                                            0,     
205                                            dat    
206                                                   
207         case PTRACE_SETFPREGS:  /* Set the chi    
208                 return copy_regset_from_user(c    
209                                              t    
210                                              R    
211                                              0    
212                                              d    
213                                                   
214         default:                                  
215                 ret = ptrace_request(child, re    
216                 break;                            
217         }                                         
218                                                   
219         return ret;                               
220 }                                                 
221                                                   
222                                                   
223 #ifdef CONFIG_COMPAT                              
224                                                   
225 /* This function is needed to translate 32 bit    
226  * 64 bit pt_regs offsets.  For example, a 32     
227  * will request offset 12 if it wants gr3, but    
228  * the 64 bit kernels view of gr3 will be at o    
229  * This code relies on a 32 bit pt_regs being     
230  * except for the fp registers which (a) are 6    
231  * the gr registers at the start of pt_regs.      
232  * be half the size of the 64 bit pt_regs, plu    
233  * being 64 bit in both cases.                    
234  */                                               
235                                                   
236 static compat_ulong_t translate_usr_offset(com    
237 {                                                 
238         compat_ulong_t pos;                       
239                                                   
240         if (offset < 32*4)      /* gr[0..31] *    
241                 pos = offset * 2 + 4;             
242         else if (offset < 32*4+32*8)    /* fr[    
243                 pos = (offset - 32*4) + PT_FR0    
244         else if (offset < sizeof(struct pt_reg    
245                 pos = (offset - 32*4 - 32*8) *    
246         else                                      
247                 pos = sizeof(struct pt_regs);     
248                                                   
249         return pos;                               
250 }                                                 
251                                                   
252 long compat_arch_ptrace(struct task_struct *ch    
253                         compat_ulong_t addr, c    
254 {                                                 
255         compat_uint_t tmp;                        
256         long ret = -EIO;                          
257                                                   
258         switch (request) {                        
259                                                   
260         case PTRACE_PEEKUSR:                      
261                 if (addr & (sizeof(compat_uint    
262                         break;                    
263                 addr = translate_usr_offset(ad    
264                 if (addr >= sizeof(struct pt_r    
265                         break;                    
266                                                   
267                 tmp = *(compat_uint_t *) ((cha    
268                 ret = put_user(tmp, (compat_ui    
269                 break;                            
270                                                   
271         /* Write the word at location addr in     
272            to change when the kernel no longer    
273            FIXME.  There is a problem at the m    
274            saved if the process is ptraced on     
275            those values are overwritten by act    
276            exit. */                               
277         case PTRACE_POKEUSR:                      
278                 /* Some register values writte    
279                  * entry.S:syscall_restore_rfi    
280                  * r31/r31+4, and not with the    
281                  */                               
282                 if (addr == PT_PSW) {             
283                         /* Since PT_PSW==0, it    
284                          * under 64 bit kernel    
285                          */                       
286                         ret = arch_ptrace(chil    
287                 } else {                          
288                         if (addr & (sizeof(com    
289                                 break;            
290                         addr = translate_usr_o    
291                         if (addr >= sizeof(str    
292                                 break;            
293                         if (addr == PT_IAOQ0+4    
294                                 data |= PRIV_U    
295                         }                         
296                         if (addr >= PT_FR0 &&     
297                                 /* Special cas    
298                                 *(__u32 *) ((c    
299                                 ret = 0;          
300                         }                         
301                         else if ((addr >= PT_G    
302                                         addr =    
303                                         addr =    
304                                 /* Zero the to    
305                                 *(__u32 *) ((c    
306                                 *(__u32 *) ((c    
307                                 ret = 0;          
308                         }                         
309                 }                                 
310                 break;                            
311         case PTRACE_GETREGS:                      
312         case PTRACE_SETREGS:                      
313         case PTRACE_GETFPREGS:                    
314         case PTRACE_SETFPREGS:                    
315                 return arch_ptrace(child, requ    
316                                                   
317         default:                                  
318                 ret = compat_ptrace_request(ch    
319                 break;                            
320         }                                         
321                                                   
322         return ret;                               
323 }                                                 
324 #endif                                            
325                                                   
326 long do_syscall_trace_enter(struct pt_regs *re    
327 {                                                 
328         if (test_thread_flag(TIF_SYSCALL_TRACE    
329                 int rc = ptrace_report_syscall    
330                                                   
331                 /*                                
332                  * As tracesys_next does not s    
333                  * when %r20 is set to -1, ini    
334                  */                               
335                 regs->gr[28] = -ENOSYS;           
336                                                   
337                 if (rc) {                         
338                         /*                        
339                          * A nonzero return co    
340                          * ptrace_report_sysca    
341                          * to prevent the sysc    
342                          * the syscall call an    
343                          *                        
344                          * Note that the trace    
345                          * regs->gr[20] to an     
346                          * that is handled by     
347                          */                       
348                         regs->gr[20] = -1UL;      
349                         return -1;                
350                 }                                 
351         }                                         
352                                                   
353         /* Do the secure computing check after    
354         if (secure_computing() == -1)             
355                 return -1;                        
356                                                   
357 #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS            
358         if (unlikely(test_thread_flag(TIF_SYSC    
359                 trace_sys_enter(regs, regs->gr    
360 #endif                                            
361                                                   
362 #ifdef CONFIG_64BIT                               
363         if (!is_compat_task())                    
364                 audit_syscall_entry(regs->gr[2    
365                                     regs->gr[2    
366         else                                      
367 #endif                                            
368                 audit_syscall_entry(regs->gr[2    
369                         regs->gr[26] & 0xfffff    
370                         regs->gr[25] & 0xfffff    
371                         regs->gr[24] & 0xfffff    
372                         regs->gr[23] & 0xfffff    
373                                                   
374         /*                                        
375          * Sign extend the syscall number to 6    
376          * modified by a compat ptrace call       
377          */                                       
378         return (int) ((u32) regs->gr[20]);        
379 }                                                 
380                                                   
381 void do_syscall_trace_exit(struct pt_regs *reg    
382 {                                                 
383         int stepping = test_thread_flag(TIF_SI    
384                 test_thread_flag(TIF_BLOCKSTEP    
385                                                   
386         audit_syscall_exit(regs);                 
387                                                   
388 #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS            
389         if (unlikely(test_thread_flag(TIF_SYSC    
390                 trace_sys_exit(regs, regs->gr[    
391 #endif                                            
392                                                   
393         if (stepping || test_thread_flag(TIF_S    
394                 ptrace_report_syscall_exit(reg    
395 }                                                 
396                                                   
397                                                   
398 /*                                                
399  * regset functions.                              
400  */                                               
401                                                   
402 static int fpr_get(struct task_struct *target,    
403                      const struct user_regset     
404                      struct membuf to)            
405 {                                                 
406         struct pt_regs *regs = task_regs(targe    
407                                                   
408         return membuf_write(&to, regs->fr, ELF    
409 }                                                 
410                                                   
411 static int fpr_set(struct task_struct *target,    
412                      const struct user_regset     
413                      unsigned int pos, unsigne    
414                      const void *kbuf, const v    
415 {                                                 
416         struct pt_regs *regs = task_regs(targe    
417         const __u64 *k = kbuf;                    
418         const __u64 __user *u = ubuf;             
419         __u64 reg;                                
420                                                   
421         pos /= sizeof(reg);                       
422         count /= sizeof(reg);                     
423                                                   
424         if (kbuf)                                 
425                 for (; count > 0 && pos < ELF_    
426                         regs->fr[pos++] = *k++    
427         else                                      
428                 for (; count > 0 && pos < ELF_    
429                         if (__get_user(reg, u+    
430                                 return -EFAULT    
431                         regs->fr[pos++] = reg;    
432                 }                                 
433                                                   
434         kbuf = k;                                 
435         ubuf = u;                                 
436         pos *= sizeof(reg);                       
437         count *= sizeof(reg);                     
438         user_regset_copyin_ignore(&pos, &count    
439                                   ELF_NFPREG *    
440         return 0;                                 
441 }                                                 
442                                                   
443 #define RI(reg) (offsetof(struct user_regs_str    
444                                                   
445 static unsigned long get_reg(struct pt_regs *r    
446 {                                                 
447         switch (num) {                            
448         case RI(gr[0]) ... RI(gr[31]):  return    
449         case RI(sr[0]) ... RI(sr[7]):   return    
450         case RI(iasq[0]):               return    
451         case RI(iasq[1]):               return    
452         case RI(iaoq[0]):               return    
453         case RI(iaoq[1]):               return    
454         case RI(sar):                   return    
455         case RI(iir):                   return    
456         case RI(isr):                   return    
457         case RI(ior):                   return    
458         case RI(ipsw):                  return    
459         case RI(cr27):                  return    
460         case RI(cr0):                   return    
461         case RI(cr24):                  return    
462         case RI(cr25):                  return    
463         case RI(cr26):                  return    
464         case RI(cr28):                  return    
465         case RI(cr29):                  return    
466         case RI(cr30):                  return    
467         case RI(cr31):                  return    
468         case RI(cr8):                   return    
469         case RI(cr9):                   return    
470         case RI(cr12):                  return    
471         case RI(cr13):                  return    
472         case RI(cr10):                  return    
473         case RI(cr15):                  return    
474         default:                        return    
475         }                                         
476 }                                                 
477                                                   
478 static void set_reg(struct pt_regs *regs, int     
479 {                                                 
480         switch (num) {                            
481         case RI(gr[0]): /*                        
482                          * PSW is in gr[0].       
483                          * Allow writing to Nu    
484                          * and carry/borrow bi    
485                          * BEWARE, if you set     
486                          * stop on the nullifi    
487                          */                       
488                         val &= USER_PSW_BITS;     
489                         regs->gr[0] &= ~USER_P    
490                         regs->gr[0] |= val;       
491                         return;                   
492         case RI(gr[1]) ... RI(gr[31]):            
493                         regs->gr[num - RI(gr[0    
494                         return;                   
495         case RI(iaoq[0]):                         
496         case RI(iaoq[1]):                         
497                         /* set 2 lowest bits t    
498                         regs->iaoq[num - RI(ia    
499                         return;                   
500         case RI(sar):   regs->sar = val;          
501                         return;                   
502         default:        return;                   
503 #if 0                                             
504         /* do not allow to change any of the f    
505         case RI(sr[0]) ... RI(sr[7]):   return    
506         case RI(iasq[0]):               return    
507         case RI(iasq[1]):               return    
508         case RI(iir):                   return    
509         case RI(isr):                   return    
510         case RI(ior):                   return    
511         case RI(ipsw):                  return    
512         case RI(cr27):                  return    
513         case cr0, cr24, cr25, cr26, cr27, cr28    
514         case cr8, cr9, cr12, cr13, cr10, cr15;    
515 #endif                                            
516         }                                         
517 }                                                 
518                                                   
519 static int gpr_get(struct task_struct *target,    
520                      const struct user_regset     
521                      struct membuf to)            
522 {                                                 
523         struct pt_regs *regs = task_regs(targe    
524         unsigned int pos;                         
525                                                   
526         for (pos = 0; pos < ELF_NGREG; pos++)     
527                 membuf_store(&to, get_reg(regs    
528         return 0;                                 
529 }                                                 
530                                                   
531 static int gpr_set(struct task_struct *target,    
532                      const struct user_regset     
533                      unsigned int pos, unsigne    
534                      const void *kbuf, const v    
535 {                                                 
536         struct pt_regs *regs = task_regs(targe    
537         const unsigned long *k = kbuf;            
538         const unsigned long __user *u = ubuf;     
539         unsigned long reg;                        
540                                                   
541         pos /= sizeof(reg);                       
542         count /= sizeof(reg);                     
543                                                   
544         if (kbuf)                                 
545                 for (; count > 0 && pos < ELF_    
546                         set_reg(regs, pos++, *    
547         else                                      
548                 for (; count > 0 && pos < ELF_    
549                         if (__get_user(reg, u+    
550                                 return -EFAULT    
551                         set_reg(regs, pos++, r    
552                 }                                 
553                                                   
554         kbuf = k;                                 
555         ubuf = u;                                 
556         pos *= sizeof(reg);                       
557         count *= sizeof(reg);                     
558         user_regset_copyin_ignore(&pos, &count    
559                                   ELF_NGREG *     
560         return 0;                                 
561 }                                                 
562                                                   
563 static const struct user_regset native_regsets    
564         [REGSET_GENERAL] = {                      
565                 .core_note_type = NT_PRSTATUS,    
566                 .size = sizeof(long), .align =    
567                 .regset_get = gpr_get, .set =     
568         },                                        
569         [REGSET_FP] = {                           
570                 .core_note_type = NT_PRFPREG,     
571                 .size = sizeof(__u64), .align     
572                 .regset_get = fpr_get, .set =     
573         }                                         
574 };                                                
575                                                   
576 static const struct user_regset_view user_pari    
577         .name = "parisc", .e_machine = ELF_ARC    
578         .regsets = native_regsets, .n = ARRAY_    
579 };                                                
580                                                   
581 #ifdef CONFIG_64BIT                               
582 static int gpr32_get(struct task_struct *targe    
583                      const struct user_regset     
584                      struct membuf to)            
585 {                                                 
586         struct pt_regs *regs = task_regs(targe    
587         unsigned int pos;                         
588                                                   
589         for (pos = 0; pos < ELF_NGREG; pos++)     
590                 membuf_store(&to, (compat_ulon    
591                                                   
592         return 0;                                 
593 }                                                 
594                                                   
595 static int gpr32_set(struct task_struct *targe    
596                      const struct user_regset     
597                      unsigned int pos, unsigne    
598                      const void *kbuf, const v    
599 {                                                 
600         struct pt_regs *regs = task_regs(targe    
601         const compat_ulong_t *k = kbuf;           
602         const compat_ulong_t __user *u = ubuf;    
603         compat_ulong_t reg;                       
604                                                   
605         pos /= sizeof(reg);                       
606         count /= sizeof(reg);                     
607                                                   
608         if (kbuf)                                 
609                 for (; count > 0 && pos < ELF_    
610                         set_reg(regs, pos++, *    
611         else                                      
612                 for (; count > 0 && pos < ELF_    
613                         if (__get_user(reg, u+    
614                                 return -EFAULT    
615                         set_reg(regs, pos++, r    
616                 }                                 
617                                                   
618         kbuf = k;                                 
619         ubuf = u;                                 
620         pos *= sizeof(reg);                       
621         count *= sizeof(reg);                     
622         user_regset_copyin_ignore(&pos, &count    
623                                   ELF_NGREG *     
624         return 0;                                 
625 }                                                 
626                                                   
627 /*                                                
628  * These are the regset flavors matching the 3    
629  */                                               
630 static const struct user_regset compat_regsets    
631         [REGSET_GENERAL] = {                      
632                 .core_note_type = NT_PRSTATUS,    
633                 .size = sizeof(compat_long_t),    
634                 .regset_get = gpr32_get, .set     
635         },                                        
636         [REGSET_FP] = {                           
637                 .core_note_type = NT_PRFPREG,     
638                 .size = sizeof(__u64), .align     
639                 .regset_get = fpr_get, .set =     
640         }                                         
641 };                                                
642                                                   
643 static const struct user_regset_view user_pari    
644         .name = "parisc", .e_machine = EM_PARI    
645         .regsets = compat_regsets, .n = ARRAY_    
646 };                                                
647 #endif  /* CONFIG_64BIT */                        
648                                                   
649 const struct user_regset_view *task_user_regse    
650 {                                                 
651         BUILD_BUG_ON(sizeof(struct user_regs_s    
652         BUILD_BUG_ON(sizeof(struct user_fp_str    
653 #ifdef CONFIG_64BIT                               
654         if (is_compat_task())                     
655                 return &user_parisc_compat_vie    
656 #endif                                            
657         return &user_parisc_native_view;          
658 }                                                 
659                                                   
660                                                   
661 /* HAVE_REGS_AND_STACK_ACCESS_API feature */      
662                                                   
663 struct pt_regs_offset {                           
664         const char *name;                         
665         int offset;                               
666 };                                                
667                                                   
668 #define REG_OFFSET_NAME(r)    {.name = #r, .of    
669 #define REG_OFFSET_INDEX(r,i) {.name = #r#i, .    
670 #define REG_OFFSET_END {.name = NULL, .offset     
671                                                   
672 static const struct pt_regs_offset regoffset_t    
673         REG_OFFSET_INDEX(gr,0),                   
674         REG_OFFSET_INDEX(gr,1),                   
675         REG_OFFSET_INDEX(gr,2),                   
676         REG_OFFSET_INDEX(gr,3),                   
677         REG_OFFSET_INDEX(gr,4),                   
678         REG_OFFSET_INDEX(gr,5),                   
679         REG_OFFSET_INDEX(gr,6),                   
680         REG_OFFSET_INDEX(gr,7),                   
681         REG_OFFSET_INDEX(gr,8),                   
682         REG_OFFSET_INDEX(gr,9),                   
683         REG_OFFSET_INDEX(gr,10),                  
684         REG_OFFSET_INDEX(gr,11),                  
685         REG_OFFSET_INDEX(gr,12),                  
686         REG_OFFSET_INDEX(gr,13),                  
687         REG_OFFSET_INDEX(gr,14),                  
688         REG_OFFSET_INDEX(gr,15),                  
689         REG_OFFSET_INDEX(gr,16),                  
690         REG_OFFSET_INDEX(gr,17),                  
691         REG_OFFSET_INDEX(gr,18),                  
692         REG_OFFSET_INDEX(gr,19),                  
693         REG_OFFSET_INDEX(gr,20),                  
694         REG_OFFSET_INDEX(gr,21),                  
695         REG_OFFSET_INDEX(gr,22),                  
696         REG_OFFSET_INDEX(gr,23),                  
697         REG_OFFSET_INDEX(gr,24),                  
698         REG_OFFSET_INDEX(gr,25),                  
699         REG_OFFSET_INDEX(gr,26),                  
700         REG_OFFSET_INDEX(gr,27),                  
701         REG_OFFSET_INDEX(gr,28),                  
702         REG_OFFSET_INDEX(gr,29),                  
703         REG_OFFSET_INDEX(gr,30),                  
704         REG_OFFSET_INDEX(gr,31),                  
705         REG_OFFSET_INDEX(sr,0),                   
706         REG_OFFSET_INDEX(sr,1),                   
707         REG_OFFSET_INDEX(sr,2),                   
708         REG_OFFSET_INDEX(sr,3),                   
709         REG_OFFSET_INDEX(sr,4),                   
710         REG_OFFSET_INDEX(sr,5),                   
711         REG_OFFSET_INDEX(sr,6),                   
712         REG_OFFSET_INDEX(sr,7),                   
713         REG_OFFSET_INDEX(iasq,0),                 
714         REG_OFFSET_INDEX(iasq,1),                 
715         REG_OFFSET_INDEX(iaoq,0),                 
716         REG_OFFSET_INDEX(iaoq,1),                 
717         REG_OFFSET_NAME(cr27),                    
718         REG_OFFSET_NAME(ksp),                     
719         REG_OFFSET_NAME(kpc),                     
720         REG_OFFSET_NAME(sar),                     
721         REG_OFFSET_NAME(iir),                     
722         REG_OFFSET_NAME(isr),                     
723         REG_OFFSET_NAME(ior),                     
724         REG_OFFSET_NAME(ipsw),                    
725         REG_OFFSET_END,                           
726 };                                                
727                                                   
728 /**                                               
729  * regs_query_register_offset() - query regist    
730  * @name:       the name of a register            
731  *                                                
732  * regs_query_register_offset() returns the of    
733  * pt_regs from its name. If the name is inval    
734  */                                               
735 int regs_query_register_offset(const char *nam    
736 {                                                 
737         const struct pt_regs_offset *roff;        
738         for (roff = regoffset_table; roff->nam    
739                 if (!strcmp(roff->name, name))    
740                         return roff->offset;      
741         return -EINVAL;                           
742 }                                                 
743                                                   
744 /**                                               
745  * regs_query_register_name() - query register    
746  * @offset:     the offset of a register in st    
747  *                                                
748  * regs_query_register_name() returns the name    
749  * offset in struct pt_regs. If the @offset is    
750  */                                               
751 const char *regs_query_register_name(unsigned     
752 {                                                 
753         const struct pt_regs_offset *roff;        
754         for (roff = regoffset_table; roff->nam    
755                 if (roff->offset == offset)       
756                         return roff->name;        
757         return NULL;                              
758 }                                                 
759                                                   
760 /**                                               
761  * regs_within_kernel_stack() - check the addr    
762  * @regs:      pt_regs which contains kernel s    
763  * @addr:      address which is checked.          
764  *                                                
765  * regs_within_kernel_stack() checks @addr is     
766  * If @addr is within the kernel stack, it ret    
767  */                                               
768 int regs_within_kernel_stack(struct pt_regs *r    
769 {                                                 
770         return ((addr & ~(THREAD_SIZE - 1))  =    
771                 (kernel_stack_pointer(regs) &     
772 }                                                 
773                                                   
774 /**                                               
775  * regs_get_kernel_stack_nth() - get Nth entry    
776  * @regs:       pt_regs which contains kernel     
777  * @n:          stack entry number.               
778  *                                                
779  * regs_get_kernel_stack_nth() returns @n th e    
780  * is specified by @regs. If the @n th entry i    
781  * this returns 0.                                
782  */                                               
783 unsigned long regs_get_kernel_stack_nth(struct    
784 {                                                 
785         unsigned long *addr = (unsigned long *    
786                                                   
787         addr -= n;                                
788                                                   
789         if (!regs_within_kernel_stack(regs, (u    
790                 return 0;                         
791                                                   
792         return *addr;                             
793 }                                                 
794                                                   

~ [ 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