1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2005-2017 Andes Technology Corporation
4 #include <linux/ptrace.h>
5 #include <linux/regset.h>
6 #include <linux/tracehook.h>
8 #include <linux/sched/task_stack.h>
14 static int gpr_get(struct task_struct
*target
,
15 const struct user_regset
*regset
,
16 unsigned int pos
, unsigned int count
,
17 void *kbuf
, void __user
* ubuf
)
19 struct user_pt_regs
*uregs
= &task_pt_regs(target
)->user_regs
;
20 return user_regset_copyout(&pos
, &count
, &kbuf
, &ubuf
, uregs
, 0, -1);
23 static int gpr_set(struct task_struct
*target
, const struct user_regset
*regset
,
24 unsigned int pos
, unsigned int count
,
25 const void *kbuf
, const void __user
* ubuf
)
28 struct user_pt_regs newregs
= task_pt_regs(target
)->user_regs
;
30 err
= user_regset_copyin(&pos
, &count
, &kbuf
, &ubuf
, &newregs
, 0, -1);
34 task_pt_regs(target
)->user_regs
= newregs
;
38 static const struct user_regset nds32_regsets
[] = {
40 .core_note_type
= NT_PRSTATUS
,
41 .n
= sizeof(struct user_pt_regs
) / sizeof(u32
),
42 .size
= sizeof(elf_greg_t
),
43 .align
= sizeof(elf_greg_t
),
48 static const struct user_regset_view nds32_user_view
= {
50 .e_machine
= EM_NDS32
,
51 .regsets
= nds32_regsets
,
52 .n
= ARRAY_SIZE(nds32_regsets
)
55 const struct user_regset_view
*task_user_regset_view(struct task_struct
*task
)
57 return &nds32_user_view
;
60 void ptrace_disable(struct task_struct
*child
)
62 user_disable_single_step(child
);
67 * Provide ptrace defined service.
69 long arch_ptrace(struct task_struct
*child
, long request
, unsigned long addr
,
76 ret
= ptrace_request(child
, request
, addr
, data
);
83 void user_enable_single_step(struct task_struct
*child
)
86 regs
= task_pt_regs(child
);
87 regs
->ipsw
|= PSW_mskHSS
;
88 set_tsk_thread_flag(child
, TIF_SINGLESTEP
);
91 void user_disable_single_step(struct task_struct
*child
)
94 regs
= task_pt_regs(child
);
95 regs
->ipsw
&= ~PSW_mskHSS
;
96 clear_tsk_thread_flag(child
, TIF_SINGLESTEP
);
101 * syscall trace handler.
104 asmlinkage
int syscall_trace_enter(struct pt_regs
*regs
)
106 if (test_thread_flag(TIF_SYSCALL_TRACE
)) {
107 if (tracehook_report_syscall_entry(regs
))
108 forget_syscall(regs
);
110 return regs
->syscallno
;
113 asmlinkage
void syscall_trace_leave(struct pt_regs
*regs
)
115 int step
= test_thread_flag(TIF_SINGLESTEP
);
116 if (step
|| test_thread_flag(TIF_SYSCALL_TRACE
))
117 tracehook_report_syscall_exit(regs
, step
);