GNU Linux-libre 4.14.332-gnu1
[releases.git] / arch / parisc / kernel / ptrace.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Kernel support for the ptrace() and syscall tracing interfaces.
4  *
5  * Copyright (C) 2000 Hewlett-Packard Co, Linuxcare Inc.
6  * Copyright (C) 2000 Matthew Wilcox <matthew@wil.cx>
7  * Copyright (C) 2000 David Huggins-Daines <dhd@debian.org>
8  * Copyright (C) 2008-2016 Helge Deller <deller@gmx.de>
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/tracehook.h>
19 #include <linux/user.h>
20 #include <linux/personality.h>
21 #include <linux/regset.h>
22 #include <linux/security.h>
23 #include <linux/seccomp.h>
24 #include <linux/compat.h>
25 #include <linux/signal.h>
26 #include <linux/audit.h>
27
28 #include <linux/uaccess.h>
29 #include <asm/pgtable.h>
30 #include <asm/processor.h>
31 #include <asm/asm-offsets.h>
32
33 /* PSW bits we allow the debugger to modify */
34 #define USER_PSW_BITS   (PSW_N | PSW_B | PSW_V | PSW_CB)
35
36 #define CREATE_TRACE_POINTS
37 #include <trace/events/syscalls.h>
38
39 /*
40  * These are our native regset flavors.
41  */
42 enum parisc_regset {
43         REGSET_GENERAL,
44         REGSET_FP
45 };
46
47 /*
48  * Called by kernel/ptrace.c when detaching..
49  *
50  * Make sure single step bits etc are not set.
51  */
52 void ptrace_disable(struct task_struct *task)
53 {
54         clear_tsk_thread_flag(task, TIF_SINGLESTEP);
55         clear_tsk_thread_flag(task, TIF_BLOCKSTEP);
56
57         /* make sure the trap bits are not set */
58         pa_psw(task)->r = 0;
59         pa_psw(task)->t = 0;
60         pa_psw(task)->h = 0;
61         pa_psw(task)->l = 0;
62 }
63
64 /*
65  * The following functions are called by ptrace_resume() when
66  * enabling or disabling single/block tracing.
67  */
68 void user_disable_single_step(struct task_struct *task)
69 {
70         ptrace_disable(task);
71 }
72
73 void user_enable_single_step(struct task_struct *task)
74 {
75         clear_tsk_thread_flag(task, TIF_BLOCKSTEP);
76         set_tsk_thread_flag(task, TIF_SINGLESTEP);
77
78         if (pa_psw(task)->n) {
79                 struct siginfo si;
80
81                 /* Nullified, just crank over the queue. */
82                 task_regs(task)->iaoq[0] = task_regs(task)->iaoq[1];
83                 task_regs(task)->iasq[0] = task_regs(task)->iasq[1];
84                 task_regs(task)->iaoq[1] = task_regs(task)->iaoq[0] + 4;
85                 pa_psw(task)->n = 0;
86                 pa_psw(task)->x = 0;
87                 pa_psw(task)->y = 0;
88                 pa_psw(task)->z = 0;
89                 pa_psw(task)->b = 0;
90                 ptrace_disable(task);
91                 /* Don't wake up the task, but let the
92                    parent know something happened. */
93                 si.si_code = TRAP_TRACE;
94                 si.si_addr = (void __user *) (task_regs(task)->iaoq[0] & ~3);
95                 si.si_signo = SIGTRAP;
96                 si.si_errno = 0;
97                 force_sig_info(SIGTRAP, &si, task);
98                 /* notify_parent(task, SIGCHLD); */
99                 return;
100         }
101
102         /* Enable recovery counter traps.  The recovery counter
103          * itself will be set to zero on a task switch.  If the
104          * task is suspended on a syscall then the syscall return
105          * path will overwrite the recovery counter with a suitable
106          * value such that it traps once back in user space.  We
107          * disable interrupts in the tasks PSW here also, to avoid
108          * interrupts while the recovery counter is decrementing.
109          */
110         pa_psw(task)->r = 1;
111         pa_psw(task)->t = 0;
112         pa_psw(task)->h = 0;
113         pa_psw(task)->l = 0;
114 }
115
116 void user_enable_block_step(struct task_struct *task)
117 {
118         clear_tsk_thread_flag(task, TIF_SINGLESTEP);
119         set_tsk_thread_flag(task, TIF_BLOCKSTEP);
120
121         /* Enable taken branch trap. */
122         pa_psw(task)->r = 0;
123         pa_psw(task)->t = 1;
124         pa_psw(task)->h = 0;
125         pa_psw(task)->l = 0;
126 }
127
128 long arch_ptrace(struct task_struct *child, long request,
129                  unsigned long addr, unsigned long data)
130 {
131         unsigned long __user *datap = (unsigned long __user *)data;
132         unsigned long tmp;
133         long ret = -EIO;
134
135         unsigned long user_regs_struct_size = sizeof(struct user_regs_struct);
136 #ifdef CONFIG_64BIT
137         if (is_compat_task())
138                 user_regs_struct_size /= 2;
139 #endif
140
141         switch (request) {
142
143         /* Read the word at location addr in the USER area.  For ptraced
144            processes, the kernel saves all regs on a syscall. */
145         case PTRACE_PEEKUSR:
146                 if ((addr & (sizeof(unsigned long)-1)) ||
147                      addr >= sizeof(struct pt_regs))
148                         break;
149                 tmp = *(unsigned long *) ((char *) task_regs(child) + addr);
150                 ret = put_user(tmp, datap);
151                 break;
152
153         /* Write the word at location addr in the USER area.  This will need
154            to change when the kernel no longer saves all regs on a syscall.
155            FIXME.  There is a problem at the moment in that r3-r18 are only
156            saved if the process is ptraced on syscall entry, and even then
157            those values are overwritten by actual register values on syscall
158            exit. */
159         case PTRACE_POKEUSR:
160                 /* Some register values written here may be ignored in
161                  * entry.S:syscall_restore_rfi; e.g. iaoq is written with
162                  * r31/r31+4, and not with the values in pt_regs.
163                  */
164                 if (addr == PT_PSW) {
165                         /* Allow writing to Nullify, Divide-step-correction,
166                          * and carry/borrow bits.
167                          * BEWARE, if you set N, and then single step, it won't
168                          * stop on the nullified instruction.
169                          */
170                         data &= USER_PSW_BITS;
171                         task_regs(child)->gr[0] &= ~USER_PSW_BITS;
172                         task_regs(child)->gr[0] |= data;
173                         ret = 0;
174                         break;
175                 }
176
177                 if ((addr & (sizeof(unsigned long)-1)) ||
178                      addr >= sizeof(struct pt_regs))
179                         break;
180                 if (addr == PT_IAOQ0 || addr == PT_IAOQ1) {
181                         data |= 3; /* ensure userspace privilege */
182                 }
183                 if ((addr >= PT_GR1 && addr <= PT_GR31) ||
184                                 addr == PT_IAOQ0 || addr == PT_IAOQ1 ||
185                                 (addr >= PT_FR0 && addr <= PT_FR31 + 4) ||
186                                 addr == PT_SAR) {
187                         *(unsigned long *) ((char *) task_regs(child) + addr) = data;
188                         ret = 0;
189                 }
190                 break;
191
192         case PTRACE_GETREGS:    /* Get all gp regs from the child. */
193                 return copy_regset_to_user(child,
194                                            task_user_regset_view(current),
195                                            REGSET_GENERAL,
196                                            0, user_regs_struct_size,
197                                            datap);
198
199         case PTRACE_SETREGS:    /* Set all gp regs in the child. */
200                 return copy_regset_from_user(child,
201                                              task_user_regset_view(current),
202                                              REGSET_GENERAL,
203                                              0, user_regs_struct_size,
204                                              datap);
205
206         case PTRACE_GETFPREGS:  /* Get the child FPU state. */
207                 return copy_regset_to_user(child,
208                                            task_user_regset_view(current),
209                                            REGSET_FP,
210                                            0, sizeof(struct user_fp_struct),
211                                            datap);
212
213         case PTRACE_SETFPREGS:  /* Set the child FPU state. */
214                 return copy_regset_from_user(child,
215                                              task_user_regset_view(current),
216                                              REGSET_FP,
217                                              0, sizeof(struct user_fp_struct),
218                                              datap);
219
220         default:
221                 ret = ptrace_request(child, request, addr, data);
222                 break;
223         }
224
225         return ret;
226 }
227
228
229 #ifdef CONFIG_COMPAT
230
231 /* This function is needed to translate 32 bit pt_regs offsets in to
232  * 64 bit pt_regs offsets.  For example, a 32 bit gdb under a 64 bit kernel
233  * will request offset 12 if it wants gr3, but the lower 32 bits of
234  * the 64 bit kernels view of gr3 will be at offset 28 (3*8 + 4).
235  * This code relies on a 32 bit pt_regs being comprised of 32 bit values
236  * except for the fp registers which (a) are 64 bits, and (b) follow
237  * the gr registers at the start of pt_regs.  The 32 bit pt_regs should
238  * be half the size of the 64 bit pt_regs, plus 32*4 to allow for fr[]
239  * being 64 bit in both cases.
240  */
241
242 static compat_ulong_t translate_usr_offset(compat_ulong_t offset)
243 {
244         compat_ulong_t pos;
245
246         if (offset < 32*4)      /* gr[0..31] */
247                 pos = offset * 2 + 4;
248         else if (offset < 32*4+32*8)    /* fr[0] ... fr[31] */
249                 pos = (offset - 32*4) + PT_FR0;
250         else if (offset < sizeof(struct pt_regs)/2 + 32*4) /* sr[0] ... ipsw */
251                 pos = (offset - 32*4 - 32*8) * 2 + PT_SR0 + 4;
252         else
253                 pos = sizeof(struct pt_regs);
254
255         return pos;
256 }
257
258 long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
259                         compat_ulong_t addr, compat_ulong_t data)
260 {
261         compat_uint_t tmp;
262         long ret = -EIO;
263
264         switch (request) {
265
266         case PTRACE_PEEKUSR:
267                 if (addr & (sizeof(compat_uint_t)-1))
268                         break;
269                 addr = translate_usr_offset(addr);
270                 if (addr >= sizeof(struct pt_regs))
271                         break;
272
273                 tmp = *(compat_uint_t *) ((char *) task_regs(child) + addr);
274                 ret = put_user(tmp, (compat_uint_t *) (unsigned long) data);
275                 break;
276
277         /* Write the word at location addr in the USER area.  This will need
278            to change when the kernel no longer saves all regs on a syscall.
279            FIXME.  There is a problem at the moment in that r3-r18 are only
280            saved if the process is ptraced on syscall entry, and even then
281            those values are overwritten by actual register values on syscall
282            exit. */
283         case PTRACE_POKEUSR:
284                 /* Some register values written here may be ignored in
285                  * entry.S:syscall_restore_rfi; e.g. iaoq is written with
286                  * r31/r31+4, and not with the values in pt_regs.
287                  */
288                 if (addr == PT_PSW) {
289                         /* Since PT_PSW==0, it is valid for 32 bit processes
290                          * under 64 bit kernels as well.
291                          */
292                         ret = arch_ptrace(child, request, addr, data);
293                 } else {
294                         if (addr & (sizeof(compat_uint_t)-1))
295                                 break;
296                         addr = translate_usr_offset(addr);
297                         if (addr >= sizeof(struct pt_regs))
298                                 break;
299                         if (addr == PT_IAOQ0+4 || addr == PT_IAOQ1+4) {
300                                 data |= 3; /* ensure userspace privilege */
301                         }
302                         if (addr >= PT_FR0 && addr <= PT_FR31 + 4) {
303                                 /* Special case, fp regs are 64 bits anyway */
304                                 *(__u32 *) ((char *) task_regs(child) + addr) = data;
305                                 ret = 0;
306                         }
307                         else if ((addr >= PT_GR1+4 && addr <= PT_GR31+4) ||
308                                         addr == PT_IAOQ0+4 || addr == PT_IAOQ1+4 ||
309                                         addr == PT_SAR+4) {
310                                 /* Zero the top 32 bits */
311                                 *(__u32 *) ((char *) task_regs(child) + addr - 4) = 0;
312                                 *(__u32 *) ((char *) task_regs(child) + addr) = data;
313                                 ret = 0;
314                         }
315                 }
316                 break;
317         case PTRACE_GETREGS:
318         case PTRACE_SETREGS:
319         case PTRACE_GETFPREGS:
320         case PTRACE_SETFPREGS:
321                 return arch_ptrace(child, request, addr, data);
322
323         default:
324                 ret = compat_ptrace_request(child, request, addr, data);
325                 break;
326         }
327
328         return ret;
329 }
330 #endif
331
332 long do_syscall_trace_enter(struct pt_regs *regs)
333 {
334         if (test_thread_flag(TIF_SYSCALL_TRACE)) {
335                 int rc = tracehook_report_syscall_entry(regs);
336
337                 /*
338                  * As tracesys_next does not set %r28 to -ENOSYS
339                  * when %r20 is set to -1, initialize it here.
340                  */
341                 regs->gr[28] = -ENOSYS;
342
343                 if (rc) {
344                         /*
345                          * A nonzero return code from
346                          * tracehook_report_syscall_entry() tells us
347                          * to prevent the syscall execution.  Skip
348                          * the syscall call and the syscall restart handling.
349                          *
350                          * Note that the tracer may also just change
351                          * regs->gr[20] to an invalid syscall number,
352                          * that is handled by tracesys_next.
353                          */
354                         regs->gr[20] = -1UL;
355                         return -1;
356                 }
357         }
358
359         /* Do the secure computing check after ptrace. */
360         if (secure_computing(NULL) == -1)
361                 return -1;
362
363 #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
364         if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
365                 trace_sys_enter(regs, regs->gr[20]);
366 #endif
367
368 #ifdef CONFIG_64BIT
369         if (!is_compat_task())
370                 audit_syscall_entry(regs->gr[20], regs->gr[26], regs->gr[25],
371                                     regs->gr[24], regs->gr[23]);
372         else
373 #endif
374                 audit_syscall_entry(regs->gr[20] & 0xffffffff,
375                         regs->gr[26] & 0xffffffff,
376                         regs->gr[25] & 0xffffffff,
377                         regs->gr[24] & 0xffffffff,
378                         regs->gr[23] & 0xffffffff);
379
380         /*
381          * Sign extend the syscall number to 64bit since it may have been
382          * modified by a compat ptrace call
383          */
384         return (int) ((u32) regs->gr[20]);
385 }
386
387 void do_syscall_trace_exit(struct pt_regs *regs)
388 {
389         int stepping = test_thread_flag(TIF_SINGLESTEP) ||
390                 test_thread_flag(TIF_BLOCKSTEP);
391
392         audit_syscall_exit(regs);
393
394 #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
395         if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
396                 trace_sys_exit(regs, regs->gr[20]);
397 #endif
398
399         if (stepping || test_thread_flag(TIF_SYSCALL_TRACE))
400                 tracehook_report_syscall_exit(regs, stepping);
401 }
402
403
404 /*
405  * regset functions.
406  */
407
408 static int fpr_get(struct task_struct *target,
409                      const struct user_regset *regset,
410                      unsigned int pos, unsigned int count,
411                      void *kbuf, void __user *ubuf)
412 {
413         struct pt_regs *regs = task_regs(target);
414         __u64 *k = kbuf;
415         __u64 __user *u = ubuf;
416         __u64 reg;
417
418         pos /= sizeof(reg);
419         count /= sizeof(reg);
420
421         if (kbuf)
422                 for (; count > 0 && pos < ELF_NFPREG; --count)
423                         *k++ = regs->fr[pos++];
424         else
425                 for (; count > 0 && pos < ELF_NFPREG; --count)
426                         if (__put_user(regs->fr[pos++], u++))
427                                 return -EFAULT;
428
429         kbuf = k;
430         ubuf = u;
431         pos *= sizeof(reg);
432         count *= sizeof(reg);
433         return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
434                                         ELF_NFPREG * sizeof(reg), -1);
435 }
436
437 static int fpr_set(struct task_struct *target,
438                      const struct user_regset *regset,
439                      unsigned int pos, unsigned int count,
440                      const void *kbuf, const void __user *ubuf)
441 {
442         struct pt_regs *regs = task_regs(target);
443         const __u64 *k = kbuf;
444         const __u64 __user *u = ubuf;
445         __u64 reg;
446
447         pos /= sizeof(reg);
448         count /= sizeof(reg);
449
450         if (kbuf)
451                 for (; count > 0 && pos < ELF_NFPREG; --count)
452                         regs->fr[pos++] = *k++;
453         else
454                 for (; count > 0 && pos < ELF_NFPREG; --count) {
455                         if (__get_user(reg, u++))
456                                 return -EFAULT;
457                         regs->fr[pos++] = reg;
458                 }
459
460         kbuf = k;
461         ubuf = u;
462         pos *= sizeof(reg);
463         count *= sizeof(reg);
464         return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
465                                          ELF_NFPREG * sizeof(reg), -1);
466 }
467
468 #define RI(reg) (offsetof(struct user_regs_struct,reg) / sizeof(long))
469
470 static unsigned long get_reg(struct pt_regs *regs, int num)
471 {
472         switch (num) {
473         case RI(gr[0]) ... RI(gr[31]):  return regs->gr[num - RI(gr[0])];
474         case RI(sr[0]) ... RI(sr[7]):   return regs->sr[num - RI(sr[0])];
475         case RI(iasq[0]):               return regs->iasq[0];
476         case RI(iasq[1]):               return regs->iasq[1];
477         case RI(iaoq[0]):               return regs->iaoq[0];
478         case RI(iaoq[1]):               return regs->iaoq[1];
479         case RI(sar):                   return regs->sar;
480         case RI(iir):                   return regs->iir;
481         case RI(isr):                   return regs->isr;
482         case RI(ior):                   return regs->ior;
483         case RI(ipsw):                  return regs->ipsw;
484         case RI(cr27):                  return regs->cr27;
485         case RI(cr0):                   return mfctl(0);
486         case RI(cr24):                  return mfctl(24);
487         case RI(cr25):                  return mfctl(25);
488         case RI(cr26):                  return mfctl(26);
489         case RI(cr28):                  return mfctl(28);
490         case RI(cr29):                  return mfctl(29);
491         case RI(cr30):                  return mfctl(30);
492         case RI(cr31):                  return mfctl(31);
493         case RI(cr8):                   return mfctl(8);
494         case RI(cr9):                   return mfctl(9);
495         case RI(cr12):                  return mfctl(12);
496         case RI(cr13):                  return mfctl(13);
497         case RI(cr10):                  return mfctl(10);
498         case RI(cr15):                  return mfctl(15);
499         default:                        return 0;
500         }
501 }
502
503 static void set_reg(struct pt_regs *regs, int num, unsigned long val)
504 {
505         switch (num) {
506         case RI(gr[0]): /*
507                          * PSW is in gr[0].
508                          * Allow writing to Nullify, Divide-step-correction,
509                          * and carry/borrow bits.
510                          * BEWARE, if you set N, and then single step, it won't
511                          * stop on the nullified instruction.
512                          */
513                         val &= USER_PSW_BITS;
514                         regs->gr[0] &= ~USER_PSW_BITS;
515                         regs->gr[0] |= val;
516                         return;
517         case RI(gr[1]) ... RI(gr[31]):
518                         regs->gr[num - RI(gr[0])] = val;
519                         return;
520         case RI(iaoq[0]):
521         case RI(iaoq[1]):
522                         /* set 2 lowest bits to ensure userspace privilege: */
523                         regs->iaoq[num - RI(iaoq[0])] = val | 3;
524                         return;
525         case RI(sar):   regs->sar = val;
526                         return;
527         default:        return;
528 #if 0
529         /* do not allow to change any of the following registers (yet) */
530         case RI(sr[0]) ... RI(sr[7]):   return regs->sr[num - RI(sr[0])];
531         case RI(iasq[0]):               return regs->iasq[0];
532         case RI(iasq[1]):               return regs->iasq[1];
533         case RI(iir):                   return regs->iir;
534         case RI(isr):                   return regs->isr;
535         case RI(ior):                   return regs->ior;
536         case RI(ipsw):                  return regs->ipsw;
537         case RI(cr27):                  return regs->cr27;
538         case cr0, cr24, cr25, cr26, cr27, cr28, cr29, cr30, cr31;
539         case cr8, cr9, cr12, cr13, cr10, cr15;
540 #endif
541         }
542 }
543
544 static int gpr_get(struct task_struct *target,
545                      const struct user_regset *regset,
546                      unsigned int pos, unsigned int count,
547                      void *kbuf, void __user *ubuf)
548 {
549         struct pt_regs *regs = task_regs(target);
550         unsigned long *k = kbuf;
551         unsigned long __user *u = ubuf;
552         unsigned long reg;
553
554         pos /= sizeof(reg);
555         count /= sizeof(reg);
556
557         if (kbuf)
558                 for (; count > 0 && pos < ELF_NGREG; --count)
559                         *k++ = get_reg(regs, pos++);
560         else
561                 for (; count > 0 && pos < ELF_NGREG; --count)
562                         if (__put_user(get_reg(regs, pos++), u++))
563                                 return -EFAULT;
564         kbuf = k;
565         ubuf = u;
566         pos *= sizeof(reg);
567         count *= sizeof(reg);
568         return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
569                                         ELF_NGREG * sizeof(reg), -1);
570 }
571
572 static int gpr_set(struct task_struct *target,
573                      const struct user_regset *regset,
574                      unsigned int pos, unsigned int count,
575                      const void *kbuf, const void __user *ubuf)
576 {
577         struct pt_regs *regs = task_regs(target);
578         const unsigned long *k = kbuf;
579         const unsigned long __user *u = ubuf;
580         unsigned long reg;
581
582         pos /= sizeof(reg);
583         count /= sizeof(reg);
584
585         if (kbuf)
586                 for (; count > 0 && pos < ELF_NGREG; --count)
587                         set_reg(regs, pos++, *k++);
588         else
589                 for (; count > 0 && pos < ELF_NGREG; --count) {
590                         if (__get_user(reg, u++))
591                                 return -EFAULT;
592                         set_reg(regs, pos++, reg);
593                 }
594
595         kbuf = k;
596         ubuf = u;
597         pos *= sizeof(reg);
598         count *= sizeof(reg);
599         return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
600                                          ELF_NGREG * sizeof(reg), -1);
601 }
602
603 static const struct user_regset native_regsets[] = {
604         [REGSET_GENERAL] = {
605                 .core_note_type = NT_PRSTATUS, .n = ELF_NGREG,
606                 .size = sizeof(long), .align = sizeof(long),
607                 .get = gpr_get, .set = gpr_set
608         },
609         [REGSET_FP] = {
610                 .core_note_type = NT_PRFPREG, .n = ELF_NFPREG,
611                 .size = sizeof(__u64), .align = sizeof(__u64),
612                 .get = fpr_get, .set = fpr_set
613         }
614 };
615
616 static const struct user_regset_view user_parisc_native_view = {
617         .name = "parisc", .e_machine = ELF_ARCH, .ei_osabi = ELFOSABI_LINUX,
618         .regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
619 };
620
621 #ifdef CONFIG_64BIT
622 #include <linux/compat.h>
623
624 static int gpr32_get(struct task_struct *target,
625                      const struct user_regset *regset,
626                      unsigned int pos, unsigned int count,
627                      void *kbuf, void __user *ubuf)
628 {
629         struct pt_regs *regs = task_regs(target);
630         compat_ulong_t *k = kbuf;
631         compat_ulong_t __user *u = ubuf;
632         compat_ulong_t reg;
633
634         pos /= sizeof(reg);
635         count /= sizeof(reg);
636
637         if (kbuf)
638                 for (; count > 0 && pos < ELF_NGREG; --count)
639                         *k++ = get_reg(regs, pos++);
640         else
641                 for (; count > 0 && pos < ELF_NGREG; --count)
642                         if (__put_user((compat_ulong_t) get_reg(regs, pos++), u++))
643                                 return -EFAULT;
644
645         kbuf = k;
646         ubuf = u;
647         pos *= sizeof(reg);
648         count *= sizeof(reg);
649         return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
650                                         ELF_NGREG * sizeof(reg), -1);
651 }
652
653 static int gpr32_set(struct task_struct *target,
654                      const struct user_regset *regset,
655                      unsigned int pos, unsigned int count,
656                      const void *kbuf, const void __user *ubuf)
657 {
658         struct pt_regs *regs = task_regs(target);
659         const compat_ulong_t *k = kbuf;
660         const compat_ulong_t __user *u = ubuf;
661         compat_ulong_t reg;
662
663         pos /= sizeof(reg);
664         count /= sizeof(reg);
665
666         if (kbuf)
667                 for (; count > 0 && pos < ELF_NGREG; --count)
668                         set_reg(regs, pos++, *k++);
669         else
670                 for (; count > 0 && pos < ELF_NGREG; --count) {
671                         if (__get_user(reg, u++))
672                                 return -EFAULT;
673                         set_reg(regs, pos++, reg);
674                 }
675
676         kbuf = k;
677         ubuf = u;
678         pos *= sizeof(reg);
679         count *= sizeof(reg);
680         return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
681                                          ELF_NGREG * sizeof(reg), -1);
682 }
683
684 /*
685  * These are the regset flavors matching the 32bit native set.
686  */
687 static const struct user_regset compat_regsets[] = {
688         [REGSET_GENERAL] = {
689                 .core_note_type = NT_PRSTATUS, .n = ELF_NGREG,
690                 .size = sizeof(compat_long_t), .align = sizeof(compat_long_t),
691                 .get = gpr32_get, .set = gpr32_set
692         },
693         [REGSET_FP] = {
694                 .core_note_type = NT_PRFPREG, .n = ELF_NFPREG,
695                 .size = sizeof(__u64), .align = sizeof(__u64),
696                 .get = fpr_get, .set = fpr_set
697         }
698 };
699
700 static const struct user_regset_view user_parisc_compat_view = {
701         .name = "parisc", .e_machine = EM_PARISC, .ei_osabi = ELFOSABI_LINUX,
702         .regsets = compat_regsets, .n = ARRAY_SIZE(compat_regsets)
703 };
704 #endif  /* CONFIG_64BIT */
705
706 const struct user_regset_view *task_user_regset_view(struct task_struct *task)
707 {
708         BUILD_BUG_ON(sizeof(struct user_regs_struct)/sizeof(long) != ELF_NGREG);
709         BUILD_BUG_ON(sizeof(struct user_fp_struct)/sizeof(__u64) != ELF_NFPREG);
710 #ifdef CONFIG_64BIT
711         if (is_compat_task())
712                 return &user_parisc_compat_view;
713 #endif
714         return &user_parisc_native_view;
715 }