1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef __ASM_SH_SYSCALL_32_H 3 #define __ASM_SH_SYSCALL_32_H 4 5 #include <uapi/linux/audit.h> 6 #include <linux/kernel.h> 7 #include <linux/sched.h> 8 #include <linux/err.h> 9 #include <asm/ptrace.h> 10 11 /* The system call number is given by the user in R3 */ 12 static inline long syscall_get_nr(struct task_struct *task, 13 struct pt_regs *regs) 14 { 15 return (regs->tra >= 0) ? regs->regs[3] : -1L; 16 } 17 18 static inline void syscall_set_nr(struct task_struct *task, 19 struct pt_regs *regs, 20 int nr) 21 { 22 /* 23 * Unlike syscall_get_nr(), syscall_set_nr() can be called only when 24 * the target task is stopped for tracing on entering syscall, so 25 * there is no need to have the same check syscall_get_nr() has. 26 */ 27 regs->regs[3] = nr; 28 } 29 30 static inline void syscall_rollback(struct task_struct *task, 31 struct pt_regs *regs) 32 { 33 /* 34 * XXX: This needs some thought. On SH we don't 35 * save away the original r0 value anywhere. 36 */ 37 } 38 39 static inline long syscall_get_error(struct task_struct *task, 40 struct pt_regs *regs) 41 { 42 return IS_ERR_VALUE(regs->regs[0]) ? regs->regs[0] : 0; 43 } 44 45 static inline long syscall_get_return_value(struct task_struct *task, 46 struct pt_regs *regs) 47 { 48 return regs->regs[0]; 49 } 50 51 static inline void syscall_set_return_value(struct task_struct *task, 52 struct pt_regs *regs, 53 int error, long val) 54 { 55 regs->regs[0] = (long) error ?: val; 56 } 57 58 static inline void syscall_get_arguments(struct task_struct *task, 59 struct pt_regs *regs, 60 unsigned long *args) 61 { 62 63 /* Argument pattern is: R4, R5, R6, R7, R0, R1 */ 64 args[5] = regs->regs[1]; 65 args[4] = regs->regs[0]; 66 args[3] = regs->regs[7]; 67 args[2] = regs->regs[6]; 68 args[1] = regs->regs[5]; 69 args[0] = regs->regs[4]; 70 } 71 72 static inline void syscall_set_arguments(struct task_struct *task, 73 struct pt_regs *regs, 74 const unsigned long *args) 75 { 76 regs->regs[1] = args[5]; 77 regs->regs[0] = args[4]; 78 regs->regs[7] = args[3]; 79 regs->regs[6] = args[2]; 80 regs->regs[5] = args[1]; 81 regs->regs[4] = args[0]; 82 } 83 84 static inline int syscall_get_arch(struct task_struct *task) 85 { 86 int arch = AUDIT_ARCH_SH; 87 88 #ifdef CONFIG_CPU_LITTLE_ENDIAN 89 arch |= __AUDIT_ARCH_LE; 90 #endif 91 return arch; 92 } 93 #endif /* __ASM_SH_SYSCALL_32_H */ 94