1 /* ptrace.c: Sparc process tracing support.
3 * Copyright (C) 1996, 2008 David S. Miller (davem@davemloft.net)
4 * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
6 * Based upon code written by Ross Biro, Linus Torvalds, Bob Manson,
9 * Added Linux support -miguel (weird, eh?, the original code was meant
13 #include <linux/kernel.h>
14 #include <linux/sched.h>
15 #include <linux/sched/task_stack.h>
17 #include <linux/errno.h>
18 #include <linux/export.h>
19 #include <linux/ptrace.h>
20 #include <linux/user.h>
21 #include <linux/smp.h>
22 #include <linux/security.h>
23 #include <linux/seccomp.h>
24 #include <linux/audit.h>
25 #include <linux/signal.h>
26 #include <linux/regset.h>
27 #include <linux/tracehook.h>
28 #include <trace/syscall.h>
29 #include <linux/compat.h>
30 #include <linux/elf.h>
31 #include <linux/context_tracking.h>
34 #include <asm/pgtable.h>
35 #include <linux/uaccess.h>
36 #include <asm/psrcompat.h>
37 #include <asm/visasm.h>
38 #include <asm/spitfire.h>
40 #include <asm/cpudata.h>
41 #include <asm/cacheflush.h>
43 #define CREATE_TRACE_POINTS
44 #include <trace/events/syscalls.h>
48 /* #define ALLOW_INIT_TRACING */
50 struct pt_regs_offset
{
55 #define REG_OFFSET_NAME(n, r) \
56 {.name = n, .offset = (PT_V9_##r)}
57 #define REG_OFFSET_END {.name = NULL, .offset = 0}
59 static const struct pt_regs_offset regoffset_table
[] = {
60 REG_OFFSET_NAME("g0", G0
),
61 REG_OFFSET_NAME("g1", G1
),
62 REG_OFFSET_NAME("g2", G2
),
63 REG_OFFSET_NAME("g3", G3
),
64 REG_OFFSET_NAME("g4", G4
),
65 REG_OFFSET_NAME("g5", G5
),
66 REG_OFFSET_NAME("g6", G6
),
67 REG_OFFSET_NAME("g7", G7
),
69 REG_OFFSET_NAME("i0", I0
),
70 REG_OFFSET_NAME("i1", I1
),
71 REG_OFFSET_NAME("i2", I2
),
72 REG_OFFSET_NAME("i3", I3
),
73 REG_OFFSET_NAME("i4", I4
),
74 REG_OFFSET_NAME("i5", I5
),
75 REG_OFFSET_NAME("i6", I6
),
76 REG_OFFSET_NAME("i7", I7
),
78 REG_OFFSET_NAME("tstate", TSTATE
),
79 REG_OFFSET_NAME("pc", TPC
),
80 REG_OFFSET_NAME("npc", TNPC
),
81 REG_OFFSET_NAME("y", Y
),
82 REG_OFFSET_NAME("lr", I7
),
88 * Called by kernel/ptrace.c when detaching..
90 * Make sure single step bits etc are not set.
92 void ptrace_disable(struct task_struct
*child
)
97 /* To get the necessary page struct, access_process_vm() first calls
98 * get_user_pages(). This has done a flush_dcache_page() on the
99 * accessed page. Then our caller (copy_{to,from}_user_page()) did
100 * to memcpy to read/write the data from that page.
102 * Now, the only thing we have to do is:
103 * 1) flush the D-cache if it's possible than an illegal alias
105 * 2) flush the I-cache if this is pre-cheetah and we did a write
107 void flush_ptrace_access(struct vm_area_struct
*vma
, struct page
*page
,
108 unsigned long uaddr
, void *kaddr
,
109 unsigned long len
, int write
)
111 BUG_ON(len
> PAGE_SIZE
);
113 if (tlb_type
== hypervisor
)
118 #ifdef DCACHE_ALIASING_POSSIBLE
119 /* If bit 13 of the kernel address we used to access the
120 * user page is the same as the virtual address that page
121 * is mapped to in the user's address space, we can skip the
124 if ((uaddr
^ (unsigned long) kaddr
) & (1UL << 13)) {
125 unsigned long start
= __pa(kaddr
);
126 unsigned long end
= start
+ len
;
127 unsigned long dcache_line_size
;
129 dcache_line_size
= local_cpu_data().dcache_line_size
;
131 if (tlb_type
== spitfire
) {
132 for (; start
< end
; start
+= dcache_line_size
)
133 spitfire_put_dcache_tag(start
& 0x3fe0, 0x0);
135 start
&= ~(dcache_line_size
- 1);
136 for (; start
< end
; start
+= dcache_line_size
)
137 __asm__
__volatile__(
138 "stxa %%g0, [%0] %1\n\t"
142 "i" (ASI_DCACHE_INVALIDATE
));
146 if (write
&& tlb_type
== spitfire
) {
147 unsigned long start
= (unsigned long) kaddr
;
148 unsigned long end
= start
+ len
;
149 unsigned long icache_line_size
;
151 icache_line_size
= local_cpu_data().icache_line_size
;
153 for (; start
< end
; start
+= icache_line_size
)
159 EXPORT_SYMBOL_GPL(flush_ptrace_access
);
161 static int get_from_target(struct task_struct
*target
, unsigned long uaddr
,
164 if (target
== current
) {
165 if (copy_from_user(kbuf
, (void __user
*) uaddr
, len
))
168 int len2
= access_process_vm(target
, uaddr
, kbuf
, len
,
176 static int set_to_target(struct task_struct
*target
, unsigned long uaddr
,
179 if (target
== current
) {
180 if (copy_to_user((void __user
*) uaddr
, kbuf
, len
))
183 int len2
= access_process_vm(target
, uaddr
, kbuf
, len
,
184 FOLL_FORCE
| FOLL_WRITE
);
191 static int regwindow64_get(struct task_struct
*target
,
192 const struct pt_regs
*regs
,
193 struct reg_window
*wbuf
)
195 unsigned long rw_addr
= regs
->u_regs
[UREG_I6
];
197 if (!test_thread_64bit_stack(rw_addr
)) {
198 struct reg_window32 win32
;
201 if (get_from_target(target
, rw_addr
, &win32
, sizeof(win32
)))
203 for (i
= 0; i
< 8; i
++)
204 wbuf
->locals
[i
] = win32
.locals
[i
];
205 for (i
= 0; i
< 8; i
++)
206 wbuf
->ins
[i
] = win32
.ins
[i
];
208 rw_addr
+= STACK_BIAS
;
209 if (get_from_target(target
, rw_addr
, wbuf
, sizeof(*wbuf
)))
216 static int regwindow64_set(struct task_struct
*target
,
217 const struct pt_regs
*regs
,
218 struct reg_window
*wbuf
)
220 unsigned long rw_addr
= regs
->u_regs
[UREG_I6
];
222 if (!test_thread_64bit_stack(rw_addr
)) {
223 struct reg_window32 win32
;
226 for (i
= 0; i
< 8; i
++)
227 win32
.locals
[i
] = wbuf
->locals
[i
];
228 for (i
= 0; i
< 8; i
++)
229 win32
.ins
[i
] = wbuf
->ins
[i
];
231 if (set_to_target(target
, rw_addr
, &win32
, sizeof(win32
)))
234 rw_addr
+= STACK_BIAS
;
235 if (set_to_target(target
, rw_addr
, wbuf
, sizeof(*wbuf
)))
247 static int genregs64_get(struct task_struct
*target
,
248 const struct user_regset
*regset
,
249 unsigned int pos
, unsigned int count
,
250 void *kbuf
, void __user
*ubuf
)
252 const struct pt_regs
*regs
= task_pt_regs(target
);
255 if (target
== current
)
258 ret
= user_regset_copyout(&pos
, &count
, &kbuf
, &ubuf
,
260 0, 16 * sizeof(u64
));
261 if (!ret
&& count
&& pos
< (32 * sizeof(u64
))) {
262 struct reg_window window
;
264 if (regwindow64_get(target
, regs
, &window
))
266 ret
= user_regset_copyout(&pos
, &count
, &kbuf
, &ubuf
,
273 /* TSTATE, TPC, TNPC */
274 ret
= user_regset_copyout(&pos
, &count
, &kbuf
, &ubuf
,
281 unsigned long y
= regs
->y
;
283 ret
= user_regset_copyout(&pos
, &count
, &kbuf
, &ubuf
,
290 ret
= user_regset_copyout_zero(&pos
, &count
, &kbuf
, &ubuf
,
291 36 * sizeof(u64
), -1);
297 static int genregs64_set(struct task_struct
*target
,
298 const struct user_regset
*regset
,
299 unsigned int pos
, unsigned int count
,
300 const void *kbuf
, const void __user
*ubuf
)
302 struct pt_regs
*regs
= task_pt_regs(target
);
305 if (target
== current
)
308 ret
= user_regset_copyin(&pos
, &count
, &kbuf
, &ubuf
,
310 0, 16 * sizeof(u64
));
311 if (!ret
&& count
&& pos
< (32 * sizeof(u64
))) {
312 struct reg_window window
;
314 if (regwindow64_get(target
, regs
, &window
))
317 ret
= user_regset_copyin(&pos
, &count
, &kbuf
, &ubuf
,
323 regwindow64_set(target
, regs
, &window
))
327 if (!ret
&& count
> 0) {
328 unsigned long tstate
;
331 ret
= user_regset_copyin(&pos
, &count
, &kbuf
, &ubuf
,
336 /* Only the condition codes and the "in syscall"
337 * state can be modified in the %tstate register.
339 tstate
&= (TSTATE_ICC
| TSTATE_XCC
| TSTATE_SYSCALL
);
340 regs
->tstate
&= ~(TSTATE_ICC
| TSTATE_XCC
| TSTATE_SYSCALL
);
341 regs
->tstate
|= tstate
;
347 ret
= user_regset_copyin(&pos
, &count
, &kbuf
, &ubuf
,
354 unsigned long y
= regs
->y
;
356 ret
= user_regset_copyin(&pos
, &count
, &kbuf
, &ubuf
,
365 ret
= user_regset_copyin_ignore(&pos
, &count
, &kbuf
, &ubuf
,
366 36 * sizeof(u64
), -1);
371 static int fpregs64_get(struct task_struct
*target
,
372 const struct user_regset
*regset
,
373 unsigned int pos
, unsigned int count
,
374 void *kbuf
, void __user
*ubuf
)
376 const unsigned long *fpregs
= task_thread_info(target
)->fpregs
;
377 unsigned long fprs
, fsr
, gsr
;
380 if (target
== current
)
381 save_and_clear_fpu();
383 fprs
= task_thread_info(target
)->fpsaved
[0];
386 ret
= user_regset_copyout(&pos
, &count
, &kbuf
, &ubuf
,
388 0, 16 * sizeof(u64
));
390 ret
= user_regset_copyout_zero(&pos
, &count
, &kbuf
, &ubuf
,
396 ret
= user_regset_copyout(&pos
, &count
,
402 ret
= user_regset_copyout_zero(&pos
, &count
,
408 if (fprs
& FPRS_FEF
) {
409 fsr
= task_thread_info(target
)->xfsr
[0];
410 gsr
= task_thread_info(target
)->gsr
[0];
416 ret
= user_regset_copyout(&pos
, &count
, &kbuf
, &ubuf
,
421 ret
= user_regset_copyout(&pos
, &count
, &kbuf
, &ubuf
,
426 ret
= user_regset_copyout(&pos
, &count
, &kbuf
, &ubuf
,
432 ret
= user_regset_copyout_zero(&pos
, &count
, &kbuf
, &ubuf
,
433 35 * sizeof(u64
), -1);
438 static int fpregs64_set(struct task_struct
*target
,
439 const struct user_regset
*regset
,
440 unsigned int pos
, unsigned int count
,
441 const void *kbuf
, const void __user
*ubuf
)
443 unsigned long *fpregs
= task_thread_info(target
)->fpregs
;
447 if (target
== current
)
448 save_and_clear_fpu();
450 ret
= user_regset_copyin(&pos
, &count
, &kbuf
, &ubuf
,
452 0, 32 * sizeof(u64
));
454 ret
= user_regset_copyin(&pos
, &count
, &kbuf
, &ubuf
,
455 task_thread_info(target
)->xfsr
,
459 ret
= user_regset_copyin(&pos
, &count
, &kbuf
, &ubuf
,
460 task_thread_info(target
)->gsr
,
464 fprs
= task_thread_info(target
)->fpsaved
[0];
465 if (!ret
&& count
> 0) {
466 ret
= user_regset_copyin(&pos
, &count
, &kbuf
, &ubuf
,
472 fprs
|= (FPRS_FEF
| FPRS_DL
| FPRS_DU
);
473 task_thread_info(target
)->fpsaved
[0] = fprs
;
476 ret
= user_regset_copyin_ignore(&pos
, &count
, &kbuf
, &ubuf
,
477 35 * sizeof(u64
), -1);
481 static const struct user_regset sparc64_regsets
[] = {
487 * TSTATE, TPC, TNPC, Y
490 .core_note_type
= NT_PRSTATUS
,
492 .size
= sizeof(u64
), .align
= sizeof(u64
),
493 .get
= genregs64_get
, .set
= genregs64_set
502 .core_note_type
= NT_PRFPREG
,
504 .size
= sizeof(u64
), .align
= sizeof(u64
),
505 .get
= fpregs64_get
, .set
= fpregs64_set
509 static const struct user_regset_view user_sparc64_view
= {
510 .name
= "sparc64", .e_machine
= EM_SPARCV9
,
511 .regsets
= sparc64_regsets
, .n
= ARRAY_SIZE(sparc64_regsets
)
515 static int genregs32_get(struct task_struct
*target
,
516 const struct user_regset
*regset
,
517 unsigned int pos
, unsigned int count
,
518 void *kbuf
, void __user
*ubuf
)
520 const struct pt_regs
*regs
= task_pt_regs(target
);
521 compat_ulong_t __user
*reg_window
;
522 compat_ulong_t
*k
= kbuf
;
523 compat_ulong_t __user
*u
= ubuf
;
526 if (target
== current
)
530 count
/= sizeof(reg
);
533 for (; count
> 0 && pos
< 16; count
--)
534 *k
++ = regs
->u_regs
[pos
++];
536 reg_window
= (compat_ulong_t __user
*) regs
->u_regs
[UREG_I6
];
538 if (target
== current
) {
539 for (; count
> 0 && pos
< 32; count
--) {
540 if (get_user(*k
++, ®_window
[pos
++]))
544 for (; count
> 0 && pos
< 32; count
--) {
545 if (access_process_vm(target
,
557 for (; count
> 0 && pos
< 16; count
--) {
558 if (put_user((compat_ulong_t
) regs
->u_regs
[pos
++], u
++))
562 reg_window
= (compat_ulong_t __user
*) regs
->u_regs
[UREG_I6
];
564 if (target
== current
) {
565 for (; count
> 0 && pos
< 32; count
--) {
566 if (get_user(reg
, ®_window
[pos
++]) ||
571 for (; count
> 0 && pos
< 32; count
--) {
572 if (access_process_vm(target
,
579 if (access_process_vm(target
,
582 FOLL_FORCE
| FOLL_WRITE
)
593 reg
= tstate_to_psr(regs
->tstate
);
614 else if (put_user(reg
, u
++))
621 count
*= sizeof(reg
);
623 return user_regset_copyout_zero(&pos
, &count
, &kbuf
, &ubuf
,
624 38 * sizeof(reg
), -1);
627 static int genregs32_set(struct task_struct
*target
,
628 const struct user_regset
*regset
,
629 unsigned int pos
, unsigned int count
,
630 const void *kbuf
, const void __user
*ubuf
)
632 struct pt_regs
*regs
= task_pt_regs(target
);
633 compat_ulong_t __user
*reg_window
;
634 const compat_ulong_t
*k
= kbuf
;
635 const compat_ulong_t __user
*u
= ubuf
;
638 if (target
== current
)
642 count
/= sizeof(reg
);
645 for (; count
> 0 && pos
< 16; count
--)
646 regs
->u_regs
[pos
++] = *k
++;
648 reg_window
= (compat_ulong_t __user
*) regs
->u_regs
[UREG_I6
];
650 if (target
== current
) {
651 for (; count
> 0 && pos
< 32; count
--) {
652 if (put_user(*k
++, ®_window
[pos
++]))
656 for (; count
> 0 && pos
< 32; count
--) {
657 if (access_process_vm(target
,
662 FOLL_FORCE
| FOLL_WRITE
)
670 for (; count
> 0 && pos
< 16; count
--) {
671 if (get_user(reg
, u
++))
673 regs
->u_regs
[pos
++] = reg
;
676 reg_window
= (compat_ulong_t __user
*) regs
->u_regs
[UREG_I6
];
678 if (target
== current
) {
679 for (; count
> 0 && pos
< 32; count
--) {
680 if (get_user(reg
, u
++) ||
681 put_user(reg
, ®_window
[pos
++]))
685 for (; count
> 0 && pos
< 32; count
--) {
686 if (access_process_vm(target
,
693 if (access_process_vm(target
,
697 FOLL_FORCE
| FOLL_WRITE
)
706 unsigned long tstate
;
710 else if (get_user(reg
, u
++))
715 tstate
= regs
->tstate
;
716 tstate
&= ~(TSTATE_ICC
| TSTATE_XCC
| TSTATE_SYSCALL
);
717 tstate
|= psr_to_tstate_icc(reg
);
718 if (reg
& PSR_SYSCALL
)
719 tstate
|= TSTATE_SYSCALL
;
720 regs
->tstate
= tstate
;
743 count
*= sizeof(reg
);
745 return user_regset_copyin_ignore(&pos
, &count
, &kbuf
, &ubuf
,
746 38 * sizeof(reg
), -1);
749 static int fpregs32_get(struct task_struct
*target
,
750 const struct user_regset
*regset
,
751 unsigned int pos
, unsigned int count
,
752 void *kbuf
, void __user
*ubuf
)
754 const unsigned long *fpregs
= task_thread_info(target
)->fpregs
;
755 compat_ulong_t enabled
;
760 if (target
== current
)
761 save_and_clear_fpu();
763 fprs
= task_thread_info(target
)->fpsaved
[0];
764 if (fprs
& FPRS_FEF
) {
765 fsr
= task_thread_info(target
)->xfsr
[0];
772 ret
= user_regset_copyout(&pos
, &count
, &kbuf
, &ubuf
,
774 0, 32 * sizeof(u32
));
777 ret
= user_regset_copyout_zero(&pos
, &count
, &kbuf
, &ubuf
,
781 ret
= user_regset_copyout(&pos
, &count
, &kbuf
, &ubuf
,
789 val
= (enabled
<< 8) | (8 << 16);
790 ret
= user_regset_copyout(&pos
, &count
, &kbuf
, &ubuf
,
797 ret
= user_regset_copyout_zero(&pos
, &count
, &kbuf
, &ubuf
,
798 35 * sizeof(u32
), -1);
803 static int fpregs32_set(struct task_struct
*target
,
804 const struct user_regset
*regset
,
805 unsigned int pos
, unsigned int count
,
806 const void *kbuf
, const void __user
*ubuf
)
808 unsigned long *fpregs
= task_thread_info(target
)->fpregs
;
812 if (target
== current
)
813 save_and_clear_fpu();
815 fprs
= task_thread_info(target
)->fpsaved
[0];
817 ret
= user_regset_copyin(&pos
, &count
, &kbuf
, &ubuf
,
819 0, 32 * sizeof(u32
));
821 user_regset_copyin_ignore(&pos
, &count
, &kbuf
, &ubuf
,
824 if (!ret
&& count
> 0) {
828 ret
= user_regset_copyin(&pos
, &count
, &kbuf
, &ubuf
,
833 val
= task_thread_info(target
)->xfsr
[0];
834 val
&= 0xffffffff00000000UL
;
836 task_thread_info(target
)->xfsr
[0] = val
;
840 fprs
|= (FPRS_FEF
| FPRS_DL
);
841 task_thread_info(target
)->fpsaved
[0] = fprs
;
844 ret
= user_regset_copyin_ignore(&pos
, &count
, &kbuf
, &ubuf
,
845 34 * sizeof(u32
), -1);
849 static const struct user_regset sparc32_regsets
[] = {
855 * PSR, PC, nPC, Y, WIM, TBR
858 .core_note_type
= NT_PRSTATUS
,
860 .size
= sizeof(u32
), .align
= sizeof(u32
),
861 .get
= genregs32_get
, .set
= genregs32_set
867 * FPU QUEUE COUNT (8-bit char)
868 * FPU QUEUE ENTRYSIZE (8-bit char)
869 * FPU ENABLED (8-bit char)
871 * FPU QUEUE (64 32-bit ints)
874 .core_note_type
= NT_PRFPREG
,
876 .size
= sizeof(u32
), .align
= sizeof(u32
),
877 .get
= fpregs32_get
, .set
= fpregs32_set
881 static const struct user_regset_view user_sparc32_view
= {
882 .name
= "sparc", .e_machine
= EM_SPARC
,
883 .regsets
= sparc32_regsets
, .n
= ARRAY_SIZE(sparc32_regsets
)
885 #endif /* CONFIG_COMPAT */
887 const struct user_regset_view
*task_user_regset_view(struct task_struct
*task
)
890 if (test_tsk_thread_flag(task
, TIF_32BIT
))
891 return &user_sparc32_view
;
893 return &user_sparc64_view
;
898 unsigned int regs
[32];
904 unsigned int insnaddr
;
909 long compat_arch_ptrace(struct task_struct
*child
, compat_long_t request
,
910 compat_ulong_t caddr
, compat_ulong_t cdata
)
912 const struct user_regset_view
*view
= task_user_regset_view(current
);
913 compat_ulong_t caddr2
= task_pt_regs(current
)->u_regs
[UREG_I4
];
914 struct pt_regs32 __user
*pregs
;
915 struct compat_fps __user
*fps
;
916 unsigned long addr2
= caddr2
;
917 unsigned long addr
= caddr
;
918 unsigned long data
= cdata
;
921 pregs
= (struct pt_regs32 __user
*) addr
;
922 fps
= (struct compat_fps __user
*) addr
;
926 ret
= (addr
!= 0) ? -EIO
: 0;
930 ret
= copy_regset_to_user(child
, view
, REGSET_GENERAL
,
935 ret
= copy_regset_to_user(child
, view
, REGSET_GENERAL
,
942 ret
= copy_regset_from_user(child
, view
, REGSET_GENERAL
,
947 ret
= copy_regset_from_user(child
, view
, REGSET_GENERAL
,
953 case PTRACE_GETFPREGS
:
954 ret
= copy_regset_to_user(child
, view
, REGSET_FP
,
959 ret
= copy_regset_to_user(child
, view
, REGSET_FP
,
964 if (__put_user(0, &fps
->flags
) ||
965 __put_user(0, &fps
->extra
) ||
966 __put_user(0, &fps
->fpqd
) ||
967 clear_user(&fps
->fpq
[0], 32 * sizeof(unsigned int)))
972 case PTRACE_SETFPREGS
:
973 ret
= copy_regset_from_user(child
, view
, REGSET_FP
,
978 ret
= copy_regset_from_user(child
, view
, REGSET_FP
,
984 case PTRACE_READTEXT
:
985 case PTRACE_READDATA
:
986 ret
= ptrace_readdata(child
, addr
,
987 (char __user
*)addr2
, data
);
994 case PTRACE_WRITETEXT
:
995 case PTRACE_WRITEDATA
:
996 ret
= ptrace_writedata(child
, (char __user
*) addr2
,
1005 if (request
== PTRACE_SPARC_DETACH
)
1006 request
= PTRACE_DETACH
;
1007 ret
= compat_ptrace_request(child
, request
, addr
, data
);
1013 #endif /* CONFIG_COMPAT */
1016 unsigned int regs
[64];
1020 long arch_ptrace(struct task_struct
*child
, long request
,
1021 unsigned long addr
, unsigned long data
)
1023 const struct user_regset_view
*view
= task_user_regset_view(current
);
1024 unsigned long addr2
= task_pt_regs(current
)->u_regs
[UREG_I4
];
1025 struct pt_regs __user
*pregs
;
1026 struct fps __user
*fps
;
1027 void __user
*addr2p
;
1030 pregs
= (struct pt_regs __user
*) addr
;
1031 fps
= (struct fps __user
*) addr
;
1032 addr2p
= (void __user
*) addr2
;
1035 case PTRACE_PEEKUSR
:
1036 ret
= (addr
!= 0) ? -EIO
: 0;
1039 case PTRACE_GETREGS64
:
1040 ret
= copy_regset_to_user(child
, view
, REGSET_GENERAL
,
1045 /* XXX doesn't handle 'y' register correctly XXX */
1046 ret
= copy_regset_to_user(child
, view
, REGSET_GENERAL
,
1053 case PTRACE_SETREGS64
:
1054 ret
= copy_regset_from_user(child
, view
, REGSET_GENERAL
,
1059 /* XXX doesn't handle 'y' register correctly XXX */
1060 ret
= copy_regset_from_user(child
, view
, REGSET_GENERAL
,
1067 case PTRACE_GETFPREGS64
:
1068 ret
= copy_regset_to_user(child
, view
, REGSET_FP
,
1074 case PTRACE_SETFPREGS64
:
1075 ret
= copy_regset_from_user(child
, view
, REGSET_FP
,
1081 case PTRACE_READTEXT
:
1082 case PTRACE_READDATA
:
1083 ret
= ptrace_readdata(child
, addr
, addr2p
, data
);
1090 case PTRACE_WRITETEXT
:
1091 case PTRACE_WRITEDATA
:
1092 ret
= ptrace_writedata(child
, addr2p
, addr
, data
);
1100 if (request
== PTRACE_SPARC_DETACH
)
1101 request
= PTRACE_DETACH
;
1102 ret
= ptrace_request(child
, request
, addr
, data
);
1109 asmlinkage
int syscall_trace_enter(struct pt_regs
*regs
)
1113 /* do the secure computing check first */
1114 secure_computing_strict(regs
->u_regs
[UREG_G1
]);
1116 if (test_thread_flag(TIF_NOHZ
))
1119 if (test_thread_flag(TIF_SYSCALL_TRACE
))
1120 ret
= tracehook_report_syscall_entry(regs
);
1122 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT
)))
1123 trace_sys_enter(regs
, regs
->u_regs
[UREG_G1
]);
1125 audit_syscall_entry(regs
->u_regs
[UREG_G1
], regs
->u_regs
[UREG_I0
],
1126 regs
->u_regs
[UREG_I1
], regs
->u_regs
[UREG_I2
],
1127 regs
->u_regs
[UREG_I3
]);
1132 asmlinkage
void syscall_trace_leave(struct pt_regs
*regs
)
1134 if (test_thread_flag(TIF_NOHZ
))
1137 audit_syscall_exit(regs
);
1139 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT
)))
1140 trace_sys_exit(regs
, regs
->u_regs
[UREG_I0
]);
1142 if (test_thread_flag(TIF_SYSCALL_TRACE
))
1143 tracehook_report_syscall_exit(regs
, 0);
1145 if (test_thread_flag(TIF_NOHZ
))
1150 * regs_query_register_offset() - query register offset from its name
1151 * @name: the name of a register
1153 * regs_query_register_offset() returns the offset of a register in struct
1154 * pt_regs from its name. If the name is invalid, this returns -EINVAL;
1156 int regs_query_register_offset(const char *name
)
1158 const struct pt_regs_offset
*roff
;
1160 for (roff
= regoffset_table
; roff
->name
!= NULL
; roff
++)
1161 if (!strcmp(roff
->name
, name
))
1162 return roff
->offset
;
1167 * regs_within_kernel_stack() - check the address in the stack
1168 * @regs: pt_regs which contains kernel stack pointer.
1169 * @addr: address which is checked.
1171 * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
1172 * If @addr is within the kernel stack, it returns true. If not, returns false.
1174 static inline int regs_within_kernel_stack(struct pt_regs
*regs
,
1177 unsigned long ksp
= kernel_stack_pointer(regs
) + STACK_BIAS
;
1178 return ((addr
& ~(THREAD_SIZE
- 1)) ==
1179 (ksp
& ~(THREAD_SIZE
- 1)));
1183 * regs_get_kernel_stack_nth() - get Nth entry of the stack
1184 * @regs: pt_regs which contains kernel stack pointer.
1185 * @n: stack entry number.
1187 * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
1188 * is specified by @regs. If the @n th entry is NOT in the kernel stack,
1191 unsigned long regs_get_kernel_stack_nth(struct pt_regs
*regs
, unsigned int n
)
1193 unsigned long ksp
= kernel_stack_pointer(regs
) + STACK_BIAS
;
1194 unsigned long *addr
= (unsigned long *)ksp
;
1196 if (regs_within_kernel_stack(regs
, (unsigned long)addr
))