LoongArch: Parse MADT to get multi-processor information
[linux-2.6-microblaze.git] / arch / sparc / kernel / ptrace_64.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* ptrace.c: Sparc process tracing support.
3  *
4  * Copyright (C) 1996, 2008 David S. Miller (davem@davemloft.net)
5  * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
6  *
7  * Based upon code written by Ross Biro, Linus Torvalds, Bob Manson,
8  * and David Mosberger.
9  *
10  * Added Linux support -miguel (weird, eh?, the original code was meant
11  * to emulate SunOS).
12  */
13
14 #include <linux/kernel.h>
15 #include <linux/sched.h>
16 #include <linux/sched/task_stack.h>
17 #include <linux/mm.h>
18 #include <linux/errno.h>
19 #include <linux/export.h>
20 #include <linux/ptrace.h>
21 #include <linux/user.h>
22 #include <linux/smp.h>
23 #include <linux/security.h>
24 #include <linux/seccomp.h>
25 #include <linux/audit.h>
26 #include <linux/signal.h>
27 #include <linux/regset.h>
28 #include <trace/syscall.h>
29 #include <linux/compat.h>
30 #include <linux/elf.h>
31 #include <linux/context_tracking.h>
32
33 #include <asm/asi.h>
34 #include <linux/uaccess.h>
35 #include <asm/psrcompat.h>
36 #include <asm/visasm.h>
37 #include <asm/spitfire.h>
38 #include <asm/page.h>
39 #include <asm/cpudata.h>
40 #include <asm/cacheflush.h>
41
42 #define CREATE_TRACE_POINTS
43 #include <trace/events/syscalls.h>
44
45 #include "entry.h"
46
47 /* #define ALLOW_INIT_TRACING */
48
49 struct pt_regs_offset {
50         const char *name;
51         int offset;
52 };
53
54 #define REG_OFFSET_NAME(n, r) \
55         {.name = n, .offset = (PT_V9_##r)}
56 #define REG_OFFSET_END {.name = NULL, .offset = 0}
57
58 static const struct pt_regs_offset regoffset_table[] = {
59         REG_OFFSET_NAME("g0", G0),
60         REG_OFFSET_NAME("g1", G1),
61         REG_OFFSET_NAME("g2", G2),
62         REG_OFFSET_NAME("g3", G3),
63         REG_OFFSET_NAME("g4", G4),
64         REG_OFFSET_NAME("g5", G5),
65         REG_OFFSET_NAME("g6", G6),
66         REG_OFFSET_NAME("g7", G7),
67
68         REG_OFFSET_NAME("i0", I0),
69         REG_OFFSET_NAME("i1", I1),
70         REG_OFFSET_NAME("i2", I2),
71         REG_OFFSET_NAME("i3", I3),
72         REG_OFFSET_NAME("i4", I4),
73         REG_OFFSET_NAME("i5", I5),
74         REG_OFFSET_NAME("i6", I6),
75         REG_OFFSET_NAME("i7", I7),
76
77         REG_OFFSET_NAME("tstate", TSTATE),
78         REG_OFFSET_NAME("pc", TPC),
79         REG_OFFSET_NAME("npc", TNPC),
80         REG_OFFSET_NAME("y", Y),
81         REG_OFFSET_NAME("lr", I7),
82
83         REG_OFFSET_END,
84 };
85
86 /*
87  * Called by kernel/ptrace.c when detaching..
88  *
89  * Make sure single step bits etc are not set.
90  */
91 void ptrace_disable(struct task_struct *child)
92 {
93         /* nothing to do */
94 }
95
96 /* To get the necessary page struct, access_process_vm() first calls
97  * get_user_pages().  This has done a flush_dcache_page() on the
98  * accessed page.  Then our caller (copy_{to,from}_user_page()) did
99  * to memcpy to read/write the data from that page.
100  *
101  * Now, the only thing we have to do is:
102  * 1) flush the D-cache if it's possible than an illegal alias
103  *    has been created
104  * 2) flush the I-cache if this is pre-cheetah and we did a write
105  */
106 void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
107                          unsigned long uaddr, void *kaddr,
108                          unsigned long len, int write)
109 {
110         BUG_ON(len > PAGE_SIZE);
111
112         if (tlb_type == hypervisor)
113                 return;
114
115         preempt_disable();
116
117 #ifdef DCACHE_ALIASING_POSSIBLE
118         /* If bit 13 of the kernel address we used to access the
119          * user page is the same as the virtual address that page
120          * is mapped to in the user's address space, we can skip the
121          * D-cache flush.
122          */
123         if ((uaddr ^ (unsigned long) kaddr) & (1UL << 13)) {
124                 unsigned long start = __pa(kaddr);
125                 unsigned long end = start + len;
126                 unsigned long dcache_line_size;
127
128                 dcache_line_size = local_cpu_data().dcache_line_size;
129
130                 if (tlb_type == spitfire) {
131                         for (; start < end; start += dcache_line_size)
132                                 spitfire_put_dcache_tag(start & 0x3fe0, 0x0);
133                 } else {
134                         start &= ~(dcache_line_size - 1);
135                         for (; start < end; start += dcache_line_size)
136                                 __asm__ __volatile__(
137                                         "stxa %%g0, [%0] %1\n\t"
138                                         "membar #Sync"
139                                         : /* no outputs */
140                                         : "r" (start),
141                                         "i" (ASI_DCACHE_INVALIDATE));
142                 }
143         }
144 #endif
145         if (write && tlb_type == spitfire) {
146                 unsigned long start = (unsigned long) kaddr;
147                 unsigned long end = start + len;
148                 unsigned long icache_line_size;
149
150                 icache_line_size = local_cpu_data().icache_line_size;
151
152                 for (; start < end; start += icache_line_size)
153                         flushi(start);
154         }
155
156         preempt_enable();
157 }
158 EXPORT_SYMBOL_GPL(flush_ptrace_access);
159
160 static int get_from_target(struct task_struct *target, unsigned long uaddr,
161                            void *kbuf, int len)
162 {
163         if (target == current) {
164                 if (copy_from_user(kbuf, (void __user *) uaddr, len))
165                         return -EFAULT;
166         } else {
167                 int len2 = access_process_vm(target, uaddr, kbuf, len,
168                                 FOLL_FORCE);
169                 if (len2 != len)
170                         return -EFAULT;
171         }
172         return 0;
173 }
174
175 static int set_to_target(struct task_struct *target, unsigned long uaddr,
176                          void *kbuf, int len)
177 {
178         if (target == current) {
179                 if (copy_to_user((void __user *) uaddr, kbuf, len))
180                         return -EFAULT;
181         } else {
182                 int len2 = access_process_vm(target, uaddr, kbuf, len,
183                                 FOLL_FORCE | FOLL_WRITE);
184                 if (len2 != len)
185                         return -EFAULT;
186         }
187         return 0;
188 }
189
190 static int regwindow64_get(struct task_struct *target,
191                            const struct pt_regs *regs,
192                            struct reg_window *wbuf)
193 {
194         unsigned long rw_addr = regs->u_regs[UREG_I6];
195
196         if (!test_thread_64bit_stack(rw_addr)) {
197                 struct reg_window32 win32;
198                 int i;
199
200                 if (get_from_target(target, rw_addr, &win32, sizeof(win32)))
201                         return -EFAULT;
202                 for (i = 0; i < 8; i++)
203                         wbuf->locals[i] = win32.locals[i];
204                 for (i = 0; i < 8; i++)
205                         wbuf->ins[i] = win32.ins[i];
206         } else {
207                 rw_addr += STACK_BIAS;
208                 if (get_from_target(target, rw_addr, wbuf, sizeof(*wbuf)))
209                         return -EFAULT;
210         }
211
212         return 0;
213 }
214
215 static int regwindow64_set(struct task_struct *target,
216                            const struct pt_regs *regs,
217                            struct reg_window *wbuf)
218 {
219         unsigned long rw_addr = regs->u_regs[UREG_I6];
220
221         if (!test_thread_64bit_stack(rw_addr)) {
222                 struct reg_window32 win32;
223                 int i;
224
225                 for (i = 0; i < 8; i++)
226                         win32.locals[i] = wbuf->locals[i];
227                 for (i = 0; i < 8; i++)
228                         win32.ins[i] = wbuf->ins[i];
229
230                 if (set_to_target(target, rw_addr, &win32, sizeof(win32)))
231                         return -EFAULT;
232         } else {
233                 rw_addr += STACK_BIAS;
234                 if (set_to_target(target, rw_addr, wbuf, sizeof(*wbuf)))
235                         return -EFAULT;
236         }
237
238         return 0;
239 }
240
241 enum sparc_regset {
242         REGSET_GENERAL,
243         REGSET_FP,
244 };
245
246 static int genregs64_get(struct task_struct *target,
247                          const struct user_regset *regset,
248                          struct membuf to)
249 {
250         const struct pt_regs *regs = task_pt_regs(target);
251         struct reg_window window;
252
253         if (target == current)
254                 flushw_user();
255
256         membuf_write(&to, regs->u_regs, 16 * sizeof(u64));
257         if (!to.left)
258                 return 0;
259         if (regwindow64_get(target, regs, &window))
260                 return -EFAULT;
261         membuf_write(&to, &window, 16 * sizeof(u64));
262         /* TSTATE, TPC, TNPC */
263         membuf_write(&to, &regs->tstate, 3 * sizeof(u64));
264         return membuf_store(&to, (u64)regs->y);
265 }
266
267 static int genregs64_set(struct task_struct *target,
268                          const struct user_regset *regset,
269                          unsigned int pos, unsigned int count,
270                          const void *kbuf, const void __user *ubuf)
271 {
272         struct pt_regs *regs = task_pt_regs(target);
273         int ret;
274
275         if (target == current)
276                 flushw_user();
277
278         ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
279                                  regs->u_regs,
280                                  0, 16 * sizeof(u64));
281         if (!ret && count && pos < (32 * sizeof(u64))) {
282                 struct reg_window window;
283
284                 if (regwindow64_get(target, regs, &window))
285                         return -EFAULT;
286
287                 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
288                                          &window,
289                                          16 * sizeof(u64),
290                                          32 * sizeof(u64));
291
292                 if (!ret &&
293                     regwindow64_set(target, regs, &window))
294                         return -EFAULT;
295         }
296
297         if (!ret && count > 0) {
298                 unsigned long tstate;
299
300                 /* TSTATE */
301                 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
302                                          &tstate,
303                                          32 * sizeof(u64),
304                                          33 * sizeof(u64));
305                 if (!ret) {
306                         /* Only the condition codes and the "in syscall"
307                          * state can be modified in the %tstate register.
308                          */
309                         tstate &= (TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
310                         regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
311                         regs->tstate |= tstate;
312                 }
313         }
314
315         if (!ret) {
316                 /* TPC, TNPC */
317                 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
318                                          &regs->tpc,
319                                          33 * sizeof(u64),
320                                          35 * sizeof(u64));
321         }
322
323         if (!ret) {
324                 unsigned long y = regs->y;
325
326                 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
327                                          &y,
328                                          35 * sizeof(u64),
329                                          36 * sizeof(u64));
330                 if (!ret)
331                         regs->y = y;
332         }
333
334         if (!ret)
335                 ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
336                                                 36 * sizeof(u64), -1);
337
338         return ret;
339 }
340
341 static int fpregs64_get(struct task_struct *target,
342                         const struct user_regset *regset,
343                         struct membuf to)
344 {
345         struct thread_info *t = task_thread_info(target);
346         unsigned long fprs;
347
348         if (target == current)
349                 save_and_clear_fpu();
350
351         fprs = t->fpsaved[0];
352
353         if (fprs & FPRS_DL)
354                 membuf_write(&to, t->fpregs, 16 * sizeof(u64));
355         else
356                 membuf_zero(&to, 16 * sizeof(u64));
357
358         if (fprs & FPRS_DU)
359                 membuf_write(&to, t->fpregs + 16, 16 * sizeof(u64));
360         else
361                 membuf_zero(&to, 16 * sizeof(u64));
362         if (fprs & FPRS_FEF) {
363                 membuf_store(&to, t->xfsr[0]);
364                 membuf_store(&to, t->gsr[0]);
365         } else {
366                 membuf_zero(&to, 2 * sizeof(u64));
367         }
368         return membuf_store(&to, fprs);
369 }
370
371 static int fpregs64_set(struct task_struct *target,
372                         const struct user_regset *regset,
373                         unsigned int pos, unsigned int count,
374                         const void *kbuf, const void __user *ubuf)
375 {
376         unsigned long *fpregs = task_thread_info(target)->fpregs;
377         unsigned long fprs;
378         int ret;
379
380         if (target == current)
381                 save_and_clear_fpu();
382
383         ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
384                                  fpregs,
385                                  0, 32 * sizeof(u64));
386         if (!ret)
387                 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
388                                          task_thread_info(target)->xfsr,
389                                          32 * sizeof(u64),
390                                          33 * sizeof(u64));
391         if (!ret)
392                 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
393                                          task_thread_info(target)->gsr,
394                                          33 * sizeof(u64),
395                                          34 * sizeof(u64));
396
397         fprs = task_thread_info(target)->fpsaved[0];
398         if (!ret && count > 0) {
399                 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
400                                          &fprs,
401                                          34 * sizeof(u64),
402                                          35 * sizeof(u64));
403         }
404
405         fprs |= (FPRS_FEF | FPRS_DL | FPRS_DU);
406         task_thread_info(target)->fpsaved[0] = fprs;
407
408         if (!ret)
409                 ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
410                                                 35 * sizeof(u64), -1);
411         return ret;
412 }
413
414 static const struct user_regset sparc64_regsets[] = {
415         /* Format is:
416          *      G0 --> G7
417          *      O0 --> O7
418          *      L0 --> L7
419          *      I0 --> I7
420          *      TSTATE, TPC, TNPC, Y
421          */
422         [REGSET_GENERAL] = {
423                 .core_note_type = NT_PRSTATUS,
424                 .n = 36,
425                 .size = sizeof(u64), .align = sizeof(u64),
426                 .regset_get = genregs64_get, .set = genregs64_set
427         },
428         /* Format is:
429          *      F0 --> F63
430          *      FSR
431          *      GSR
432          *      FPRS
433          */
434         [REGSET_FP] = {
435                 .core_note_type = NT_PRFPREG,
436                 .n = 35,
437                 .size = sizeof(u64), .align = sizeof(u64),
438                 .regset_get = fpregs64_get, .set = fpregs64_set
439         },
440 };
441
442 static int getregs64_get(struct task_struct *target,
443                          const struct user_regset *regset,
444                          struct membuf to)
445 {
446         const struct pt_regs *regs = task_pt_regs(target);
447
448         if (target == current)
449                 flushw_user();
450
451         membuf_write(&to, regs->u_regs + 1, 15 * sizeof(u64));
452         membuf_store(&to, (u64)0);
453         membuf_write(&to, &regs->tstate, 3 * sizeof(u64));
454         return membuf_store(&to, (u64)regs->y);
455 }
456
457 static int setregs64_set(struct task_struct *target,
458                          const struct user_regset *regset,
459                          unsigned int pos, unsigned int count,
460                          const void *kbuf, const void __user *ubuf)
461 {
462         struct pt_regs *regs = task_pt_regs(target);
463         unsigned long y = regs->y;
464         unsigned long tstate;
465         int ret;
466
467         if (target == current)
468                 flushw_user();
469
470         ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
471                                  regs->u_regs + 1,
472                                  0 * sizeof(u64),
473                                  15 * sizeof(u64));
474         if (ret)
475                 return ret;
476         ret =user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
477                                  15 * sizeof(u64), 16 * sizeof(u64));
478         if (ret)
479                 return ret;
480         /* TSTATE */
481         ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
482                                  &tstate,
483                                  16 * sizeof(u64),
484                                  17 * sizeof(u64));
485         if (ret)
486                 return ret;
487         /* Only the condition codes and the "in syscall"
488          * state can be modified in the %tstate register.
489          */
490         tstate &= (TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
491         regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
492         regs->tstate |= tstate;
493
494         /* TPC, TNPC */
495         ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
496                                  &regs->tpc,
497                                  17 * sizeof(u64),
498                                  19 * sizeof(u64));
499         if (ret)
500                 return ret;
501         /* Y */
502         ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
503                                  &y,
504                                  19 * sizeof(u64),
505                                  20 * sizeof(u64));
506         if (!ret)
507                 regs->y = y;
508         return ret;
509 }
510
511 static const struct user_regset ptrace64_regsets[] = {
512         /* Format is:
513          *      G1 --> G7
514          *      O0 --> O7
515          *      0
516          *      TSTATE, TPC, TNPC, Y
517          */
518         [REGSET_GENERAL] = {
519                 .n = 20, .size = sizeof(u64),
520                 .regset_get = getregs64_get, .set = setregs64_set,
521         },
522 };
523
524 static const struct user_regset_view ptrace64_view = {
525         .regsets = ptrace64_regsets, .n = ARRAY_SIZE(ptrace64_regsets)
526 };
527
528 static const struct user_regset_view user_sparc64_view = {
529         .name = "sparc64", .e_machine = EM_SPARCV9,
530         .regsets = sparc64_regsets, .n = ARRAY_SIZE(sparc64_regsets)
531 };
532
533 #ifdef CONFIG_COMPAT
534 static int genregs32_get(struct task_struct *target,
535                          const struct user_regset *regset,
536                          struct membuf to)
537 {
538         const struct pt_regs *regs = task_pt_regs(target);
539         u32 uregs[16];
540         int i;
541
542         if (target == current)
543                 flushw_user();
544
545         for (i = 0; i < 16; i++)
546                 membuf_store(&to, (u32)regs->u_regs[i]);
547         if (!to.left)
548                 return 0;
549         if (get_from_target(target, regs->u_regs[UREG_I6],
550                             uregs, sizeof(uregs)))
551                 return -EFAULT;
552         membuf_write(&to, uregs, 16 * sizeof(u32));
553         membuf_store(&to, (u32)tstate_to_psr(regs->tstate));
554         membuf_store(&to, (u32)(regs->tpc));
555         membuf_store(&to, (u32)(regs->tnpc));
556         membuf_store(&to, (u32)(regs->y));
557         return membuf_zero(&to, 2 * sizeof(u32));
558 }
559
560 static int genregs32_set(struct task_struct *target,
561                          const struct user_regset *regset,
562                          unsigned int pos, unsigned int count,
563                          const void *kbuf, const void __user *ubuf)
564 {
565         struct pt_regs *regs = task_pt_regs(target);
566         compat_ulong_t __user *reg_window;
567         const compat_ulong_t *k = kbuf;
568         const compat_ulong_t __user *u = ubuf;
569         compat_ulong_t reg;
570
571         if (target == current)
572                 flushw_user();
573
574         pos /= sizeof(reg);
575         count /= sizeof(reg);
576
577         if (kbuf) {
578                 for (; count > 0 && pos < 16; count--)
579                         regs->u_regs[pos++] = *k++;
580
581                 reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
582                 reg_window -= 16;
583                 if (target == current) {
584                         for (; count > 0 && pos < 32; count--) {
585                                 if (put_user(*k++, &reg_window[pos++]))
586                                         return -EFAULT;
587                         }
588                 } else {
589                         for (; count > 0 && pos < 32; count--) {
590                                 if (access_process_vm(target,
591                                                       (unsigned long)
592                                                       &reg_window[pos],
593                                                       (void *) k,
594                                                       sizeof(*k),
595                                                       FOLL_FORCE | FOLL_WRITE)
596                                     != sizeof(*k))
597                                         return -EFAULT;
598                                 k++;
599                                 pos++;
600                         }
601                 }
602         } else {
603                 for (; count > 0 && pos < 16; count--) {
604                         if (get_user(reg, u++))
605                                 return -EFAULT;
606                         regs->u_regs[pos++] = reg;
607                 }
608
609                 reg_window = (compat_ulong_t __user *) regs->u_regs[UREG_I6];
610                 reg_window -= 16;
611                 if (target == current) {
612                         for (; count > 0 && pos < 32; count--) {
613                                 if (get_user(reg, u++) ||
614                                     put_user(reg, &reg_window[pos++]))
615                                         return -EFAULT;
616                         }
617                 } else {
618                         for (; count > 0 && pos < 32; count--) {
619                                 if (get_user(reg, u++))
620                                         return -EFAULT;
621                                 if (access_process_vm(target,
622                                                       (unsigned long)
623                                                       &reg_window[pos],
624                                                       &reg, sizeof(reg),
625                                                       FOLL_FORCE | FOLL_WRITE)
626                                     != sizeof(reg))
627                                         return -EFAULT;
628                                 pos++;
629                                 u++;
630                         }
631                 }
632         }
633         while (count > 0) {
634                 unsigned long tstate;
635
636                 if (kbuf)
637                         reg = *k++;
638                 else if (get_user(reg, u++))
639                         return -EFAULT;
640
641                 switch (pos) {
642                 case 32: /* PSR */
643                         tstate = regs->tstate;
644                         tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
645                         tstate |= psr_to_tstate_icc(reg);
646                         if (reg & PSR_SYSCALL)
647                                 tstate |= TSTATE_SYSCALL;
648                         regs->tstate = tstate;
649                         break;
650                 case 33: /* PC */
651                         regs->tpc = reg;
652                         break;
653                 case 34: /* NPC */
654                         regs->tnpc = reg;
655                         break;
656                 case 35: /* Y */
657                         regs->y = reg;
658                         break;
659                 case 36: /* WIM */
660                 case 37: /* TBR */
661                         break;
662                 default:
663                         goto finish;
664                 }
665
666                 pos++;
667                 count--;
668         }
669 finish:
670         pos *= sizeof(reg);
671         count *= sizeof(reg);
672
673         return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
674                                          38 * sizeof(reg), -1);
675 }
676
677 static int fpregs32_get(struct task_struct *target,
678                         const struct user_regset *regset,
679                         struct membuf to)
680 {
681         struct thread_info *t = task_thread_info(target);
682         bool enabled;
683
684         if (target == current)
685                 save_and_clear_fpu();
686
687         enabled = t->fpsaved[0] & FPRS_FEF;
688
689         membuf_write(&to, t->fpregs, 32 * sizeof(u32));
690         membuf_zero(&to, sizeof(u32));
691         if (enabled)
692                 membuf_store(&to, (u32)t->xfsr[0]);
693         else
694                 membuf_zero(&to, sizeof(u32));
695         membuf_store(&to, (u32)((enabled << 8) | (8 << 16)));
696         return membuf_zero(&to, 64 * sizeof(u32));
697 }
698
699 static int fpregs32_set(struct task_struct *target,
700                         const struct user_regset *regset,
701                         unsigned int pos, unsigned int count,
702                         const void *kbuf, const void __user *ubuf)
703 {
704         unsigned long *fpregs = task_thread_info(target)->fpregs;
705         unsigned long fprs;
706         int ret;
707
708         if (target == current)
709                 save_and_clear_fpu();
710
711         fprs = task_thread_info(target)->fpsaved[0];
712
713         ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
714                                  fpregs,
715                                  0, 32 * sizeof(u32));
716         if (!ret)
717                 user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
718                                           32 * sizeof(u32),
719                                           33 * sizeof(u32));
720         if (!ret && count > 0) {
721                 compat_ulong_t fsr;
722                 unsigned long val;
723
724                 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
725                                          &fsr,
726                                          33 * sizeof(u32),
727                                          34 * sizeof(u32));
728                 if (!ret) {
729                         val = task_thread_info(target)->xfsr[0];
730                         val &= 0xffffffff00000000UL;
731                         val |= fsr;
732                         task_thread_info(target)->xfsr[0] = val;
733                 }
734         }
735
736         fprs |= (FPRS_FEF | FPRS_DL);
737         task_thread_info(target)->fpsaved[0] = fprs;
738
739         if (!ret)
740                 ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
741                                                 34 * sizeof(u32), -1);
742         return ret;
743 }
744
745 static const struct user_regset sparc32_regsets[] = {
746         /* Format is:
747          *      G0 --> G7
748          *      O0 --> O7
749          *      L0 --> L7
750          *      I0 --> I7
751          *      PSR, PC, nPC, Y, WIM, TBR
752          */
753         [REGSET_GENERAL] = {
754                 .core_note_type = NT_PRSTATUS,
755                 .n = 38,
756                 .size = sizeof(u32), .align = sizeof(u32),
757                 .regset_get = genregs32_get, .set = genregs32_set
758         },
759         /* Format is:
760          *      F0 --> F31
761          *      empty 32-bit word
762          *      FSR (32--bit word)
763          *      FPU QUEUE COUNT (8-bit char)
764          *      FPU QUEUE ENTRYSIZE (8-bit char)
765          *      FPU ENABLED (8-bit char)
766          *      empty 8-bit char
767          *      FPU QUEUE (64 32-bit ints)
768          */
769         [REGSET_FP] = {
770                 .core_note_type = NT_PRFPREG,
771                 .n = 99,
772                 .size = sizeof(u32), .align = sizeof(u32),
773                 .regset_get = fpregs32_get, .set = fpregs32_set
774         },
775 };
776
777 static int getregs_get(struct task_struct *target,
778                          const struct user_regset *regset,
779                          struct membuf to)
780 {
781         const struct pt_regs *regs = task_pt_regs(target);
782         int i;
783
784         if (target == current)
785                 flushw_user();
786
787         membuf_store(&to, (u32)tstate_to_psr(regs->tstate));
788         membuf_store(&to, (u32)(regs->tpc));
789         membuf_store(&to, (u32)(regs->tnpc));
790         membuf_store(&to, (u32)(regs->y));
791         for (i = 1; i < 16; i++)
792                 membuf_store(&to, (u32)regs->u_regs[i]);
793         return to.left;
794 }
795
796 static int setregs_set(struct task_struct *target,
797                          const struct user_regset *regset,
798                          unsigned int pos, unsigned int count,
799                          const void *kbuf, const void __user *ubuf)
800 {
801         struct pt_regs *regs = task_pt_regs(target);
802         unsigned long tstate;
803         u32 uregs[19];
804         int i, ret;
805
806         if (target == current)
807                 flushw_user();
808
809         ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
810                                  uregs,
811                                  0, 19 * sizeof(u32));
812         if (ret)
813                 return ret;
814
815         tstate = regs->tstate;
816         tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
817         tstate |= psr_to_tstate_icc(uregs[0]);
818         if (uregs[0] & PSR_SYSCALL)
819                 tstate |= TSTATE_SYSCALL;
820         regs->tstate = tstate;
821         regs->tpc = uregs[1];
822         regs->tnpc = uregs[2];
823         regs->y = uregs[3];
824
825         for (i = 1; i < 15; i++)
826                 regs->u_regs[i] = uregs[3 + i];
827         return 0;
828 }
829
830 static int getfpregs_get(struct task_struct *target,
831                         const struct user_regset *regset,
832                         struct membuf to)
833 {
834         struct thread_info *t = task_thread_info(target);
835
836         if (target == current)
837                 save_and_clear_fpu();
838
839         membuf_write(&to, t->fpregs, 32 * sizeof(u32));
840         if (t->fpsaved[0] & FPRS_FEF)
841                 membuf_store(&to, (u32)t->xfsr[0]);
842         else
843                 membuf_zero(&to, sizeof(u32));
844         return membuf_zero(&to, 35 * sizeof(u32));
845 }
846
847 static int setfpregs_set(struct task_struct *target,
848                         const struct user_regset *regset,
849                         unsigned int pos, unsigned int count,
850                         const void *kbuf, const void __user *ubuf)
851 {
852         unsigned long *fpregs = task_thread_info(target)->fpregs;
853         unsigned long fprs;
854         int ret;
855
856         if (target == current)
857                 save_and_clear_fpu();
858
859         fprs = task_thread_info(target)->fpsaved[0];
860
861         ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
862                                  fpregs,
863                                  0, 32 * sizeof(u32));
864         if (!ret) {
865                 compat_ulong_t fsr;
866                 unsigned long val;
867
868                 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
869                                          &fsr,
870                                          32 * sizeof(u32),
871                                          33 * sizeof(u32));
872                 if (!ret) {
873                         val = task_thread_info(target)->xfsr[0];
874                         val &= 0xffffffff00000000UL;
875                         val |= fsr;
876                         task_thread_info(target)->xfsr[0] = val;
877                 }
878         }
879
880         fprs |= (FPRS_FEF | FPRS_DL);
881         task_thread_info(target)->fpsaved[0] = fprs;
882         return ret;
883 }
884
885 static const struct user_regset ptrace32_regsets[] = {
886         [REGSET_GENERAL] = {
887                 .n = 19, .size = sizeof(u32),
888                 .regset_get = getregs_get, .set = setregs_set,
889         },
890         [REGSET_FP] = {
891                 .n = 68, .size = sizeof(u32),
892                 .regset_get = getfpregs_get, .set = setfpregs_set,
893         },
894 };
895
896 static const struct user_regset_view ptrace32_view = {
897         .regsets = ptrace32_regsets, .n = ARRAY_SIZE(ptrace32_regsets)
898 };
899
900 static const struct user_regset_view user_sparc32_view = {
901         .name = "sparc", .e_machine = EM_SPARC,
902         .regsets = sparc32_regsets, .n = ARRAY_SIZE(sparc32_regsets)
903 };
904 #endif /* CONFIG_COMPAT */
905
906 const struct user_regset_view *task_user_regset_view(struct task_struct *task)
907 {
908 #ifdef CONFIG_COMPAT
909         if (test_tsk_thread_flag(task, TIF_32BIT))
910                 return &user_sparc32_view;
911 #endif
912         return &user_sparc64_view;
913 }
914
915 #ifdef CONFIG_COMPAT
916 struct compat_fps {
917         unsigned int regs[32];
918         unsigned int fsr;
919         unsigned int flags;
920         unsigned int extra;
921         unsigned int fpqd;
922         struct compat_fq {
923                 unsigned int insnaddr;
924                 unsigned int insn;
925         } fpq[16];
926 };
927
928 long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
929                         compat_ulong_t caddr, compat_ulong_t cdata)
930 {
931         compat_ulong_t caddr2 = task_pt_regs(current)->u_regs[UREG_I4];
932         struct pt_regs32 __user *pregs;
933         struct compat_fps __user *fps;
934         unsigned long addr2 = caddr2;
935         unsigned long addr = caddr;
936         unsigned long data = cdata;
937         int ret;
938
939         pregs = (struct pt_regs32 __user *) addr;
940         fps = (struct compat_fps __user *) addr;
941
942         switch (request) {
943         case PTRACE_PEEKUSR:
944                 ret = (addr != 0) ? -EIO : 0;
945                 break;
946
947         case PTRACE_GETREGS:
948                 ret = copy_regset_to_user(child, &ptrace32_view,
949                                           REGSET_GENERAL, 0,
950                                           19 * sizeof(u32),
951                                           pregs);
952                 break;
953
954         case PTRACE_SETREGS:
955                 ret = copy_regset_from_user(child, &ptrace32_view,
956                                           REGSET_GENERAL, 0,
957                                           19 * sizeof(u32),
958                                           pregs);
959                 break;
960
961         case PTRACE_GETFPREGS:
962                 ret = copy_regset_to_user(child, &ptrace32_view,
963                                           REGSET_FP, 0,
964                                           68 * sizeof(u32),
965                                           fps);
966                 break;
967
968         case PTRACE_SETFPREGS:
969                 ret = copy_regset_from_user(child, &ptrace32_view,
970                                           REGSET_FP, 0,
971                                           33 * sizeof(u32),
972                                           fps);
973                 break;
974
975         case PTRACE_READTEXT:
976         case PTRACE_READDATA:
977                 ret = ptrace_readdata(child, addr,
978                                       (char __user *)addr2, data);
979                 if (ret == data)
980                         ret = 0;
981                 else if (ret >= 0)
982                         ret = -EIO;
983                 break;
984
985         case PTRACE_WRITETEXT:
986         case PTRACE_WRITEDATA:
987                 ret = ptrace_writedata(child, (char __user *) addr2,
988                                        addr, data);
989                 if (ret == data)
990                         ret = 0;
991                 else if (ret >= 0)
992                         ret = -EIO;
993                 break;
994
995         default:
996                 if (request == PTRACE_SPARC_DETACH)
997                         request = PTRACE_DETACH;
998                 ret = compat_ptrace_request(child, request, addr, data);
999                 break;
1000         }
1001
1002         return ret;
1003 }
1004 #endif /* CONFIG_COMPAT */
1005
1006 struct fps {
1007         unsigned int regs[64];
1008         unsigned long fsr;
1009 };
1010
1011 long arch_ptrace(struct task_struct *child, long request,
1012                  unsigned long addr, unsigned long data)
1013 {
1014         const struct user_regset_view *view = task_user_regset_view(current);
1015         unsigned long addr2 = task_pt_regs(current)->u_regs[UREG_I4];
1016         struct pt_regs __user *pregs;
1017         struct fps __user *fps;
1018         void __user *addr2p;
1019         int ret;
1020
1021         pregs = (struct pt_regs __user *) addr;
1022         fps = (struct fps __user *) addr;
1023         addr2p = (void __user *) addr2;
1024
1025         switch (request) {
1026         case PTRACE_PEEKUSR:
1027                 ret = (addr != 0) ? -EIO : 0;
1028                 break;
1029
1030         case PTRACE_GETREGS64:
1031                 ret = copy_regset_to_user(child, &ptrace64_view,
1032                                           REGSET_GENERAL, 0,
1033                                           19 * sizeof(u64),
1034                                           pregs);
1035                 break;
1036
1037         case PTRACE_SETREGS64:
1038                 ret = copy_regset_from_user(child, &ptrace64_view,
1039                                           REGSET_GENERAL, 0,
1040                                           19 * sizeof(u64),
1041                                           pregs);
1042                 break;
1043
1044         case PTRACE_GETFPREGS64:
1045                 ret = copy_regset_to_user(child, view, REGSET_FP,
1046                                           0 * sizeof(u64),
1047                                           33 * sizeof(u64),
1048                                           fps);
1049                 break;
1050
1051         case PTRACE_SETFPREGS64:
1052                 ret = copy_regset_from_user(child, view, REGSET_FP,
1053                                           0 * sizeof(u64),
1054                                           33 * sizeof(u64),
1055                                           fps);
1056                 break;
1057
1058         case PTRACE_READTEXT:
1059         case PTRACE_READDATA:
1060                 ret = ptrace_readdata(child, addr, addr2p, data);
1061                 if (ret == data)
1062                         ret = 0;
1063                 else if (ret >= 0)
1064                         ret = -EIO;
1065                 break;
1066
1067         case PTRACE_WRITETEXT:
1068         case PTRACE_WRITEDATA:
1069                 ret = ptrace_writedata(child, addr2p, addr, data);
1070                 if (ret == data)
1071                         ret = 0;
1072                 else if (ret >= 0)
1073                         ret = -EIO;
1074                 break;
1075
1076         default:
1077                 if (request == PTRACE_SPARC_DETACH)
1078                         request = PTRACE_DETACH;
1079                 ret = ptrace_request(child, request, addr, data);
1080                 break;
1081         }
1082
1083         return ret;
1084 }
1085
1086 asmlinkage int syscall_trace_enter(struct pt_regs *regs)
1087 {
1088         int ret = 0;
1089
1090         /* do the secure computing check first */
1091         secure_computing_strict(regs->u_regs[UREG_G1]);
1092
1093         if (test_thread_flag(TIF_NOHZ))
1094                 user_exit();
1095
1096         if (test_thread_flag(TIF_SYSCALL_TRACE))
1097                 ret = ptrace_report_syscall_entry(regs);
1098
1099         if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
1100                 trace_sys_enter(regs, regs->u_regs[UREG_G1]);
1101
1102         audit_syscall_entry(regs->u_regs[UREG_G1], regs->u_regs[UREG_I0],
1103                             regs->u_regs[UREG_I1], regs->u_regs[UREG_I2],
1104                             regs->u_regs[UREG_I3]);
1105
1106         return ret;
1107 }
1108
1109 asmlinkage void syscall_trace_leave(struct pt_regs *regs)
1110 {
1111         if (test_thread_flag(TIF_NOHZ))
1112                 user_exit();
1113
1114         audit_syscall_exit(regs);
1115
1116         if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
1117                 trace_sys_exit(regs, regs->u_regs[UREG_I0]);
1118
1119         if (test_thread_flag(TIF_SYSCALL_TRACE))
1120                 ptrace_report_syscall_exit(regs, 0);
1121
1122         if (test_thread_flag(TIF_NOHZ))
1123                 user_enter();
1124 }
1125
1126 /**
1127  * regs_query_register_offset() - query register offset from its name
1128  * @name:       the name of a register
1129  *
1130  * regs_query_register_offset() returns the offset of a register in struct
1131  * pt_regs from its name. If the name is invalid, this returns -EINVAL;
1132  */
1133 int regs_query_register_offset(const char *name)
1134 {
1135         const struct pt_regs_offset *roff;
1136
1137         for (roff = regoffset_table; roff->name != NULL; roff++)
1138                 if (!strcmp(roff->name, name))
1139                         return roff->offset;
1140         return -EINVAL;
1141 }
1142
1143 /**
1144  * regs_within_kernel_stack() - check the address in the stack
1145  * @regs:       pt_regs which contains kernel stack pointer.
1146  * @addr:       address which is checked.
1147  *
1148  * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
1149  * If @addr is within the kernel stack, it returns true. If not, returns false.
1150  */
1151 static inline int regs_within_kernel_stack(struct pt_regs *regs,
1152                                            unsigned long addr)
1153 {
1154         unsigned long ksp = kernel_stack_pointer(regs) + STACK_BIAS;
1155         return ((addr & ~(THREAD_SIZE - 1))  ==
1156                 (ksp & ~(THREAD_SIZE - 1)));
1157 }
1158
1159 /**
1160  * regs_get_kernel_stack_nth() - get Nth entry of the stack
1161  * @regs:       pt_regs which contains kernel stack pointer.
1162  * @n:          stack entry number.
1163  *
1164  * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
1165  * is specified by @regs. If the @n th entry is NOT in the kernel stack,
1166  * this returns 0.
1167  */
1168 unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
1169 {
1170         unsigned long ksp = kernel_stack_pointer(regs) + STACK_BIAS;
1171         unsigned long *addr = (unsigned long *)ksp;
1172         addr += n;
1173         if (regs_within_kernel_stack(regs, (unsigned long)addr))
1174                 return *addr;
1175         else
1176                 return 0;
1177 }