2 * Copyright 2010 Tilera Corporation. All Rights Reserved.
3 * Copyright 2015 Regents of the University of California
4 * Copyright 2017 SiFive
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation, version 2.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * Copied from arch/tile/kernel/ptrace.c
18 #include <asm/ptrace.h>
19 #include <asm/syscall.h>
20 #include <asm/thread_info.h>
21 #include <linux/ptrace.h>
22 #include <linux/elf.h>
23 #include <linux/regset.h>
24 #include <linux/sched.h>
25 #include <linux/sched/task_stack.h>
26 #include <linux/tracehook.h>
27 #include <trace/events/syscalls.h>
33 static int riscv_gpr_get(struct task_struct
*target
,
34 const struct user_regset
*regset
,
35 unsigned int pos
, unsigned int count
,
36 void *kbuf
, void __user
*ubuf
)
40 regs
= task_pt_regs(target
);
41 return user_regset_copyout(&pos
, &count
, &kbuf
, &ubuf
, regs
, 0, -1);
44 static int riscv_gpr_set(struct task_struct
*target
,
45 const struct user_regset
*regset
,
46 unsigned int pos
, unsigned int count
,
47 const void *kbuf
, const void __user
*ubuf
)
52 regs
= task_pt_regs(target
);
53 ret
= user_regset_copyin(&pos
, &count
, &kbuf
, &ubuf
, regs
, 0, -1);
58 static const struct user_regset riscv_user_regset
[] = {
60 .core_note_type
= NT_PRSTATUS
,
62 .size
= sizeof(elf_greg_t
),
63 .align
= sizeof(elf_greg_t
),
64 .get
= &riscv_gpr_get
,
65 .set
= &riscv_gpr_set
,
69 static const struct user_regset_view riscv_user_native_view
= {
71 .e_machine
= EM_RISCV
,
72 .regsets
= riscv_user_regset
,
73 .n
= ARRAY_SIZE(riscv_user_regset
),
76 const struct user_regset_view
*task_user_regset_view(struct task_struct
*task
)
78 return &riscv_user_native_view
;
81 void ptrace_disable(struct task_struct
*child
)
83 clear_tsk_thread_flag(child
, TIF_SYSCALL_TRACE
);
86 long arch_ptrace(struct task_struct
*child
, long request
,
87 unsigned long addr
, unsigned long data
)
93 ret
= ptrace_request(child
, request
, addr
, data
);
101 * Allows PTRACE_SYSCALL to work. These are called from entry.S in
102 * {handle,ret_from}_syscall.
104 void do_syscall_trace_enter(struct pt_regs
*regs
)
106 if (test_thread_flag(TIF_SYSCALL_TRACE
))
107 if (tracehook_report_syscall_entry(regs
))
108 syscall_set_nr(current
, regs
, -1);
110 #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
111 if (test_thread_flag(TIF_SYSCALL_TRACEPOINT
))
112 trace_sys_enter(regs
, syscall_get_nr(current
, regs
));
116 void do_syscall_trace_exit(struct pt_regs
*regs
)
118 if (test_thread_flag(TIF_SYSCALL_TRACE
))
119 tracehook_report_syscall_exit(regs
, 0);
121 #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
122 if (test_thread_flag(TIF_SYSCALL_TRACEPOINT
))
123 trace_sys_exit(regs
, regs_return_value(regs
));