Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sh: Provide the asm/syscall.h interface, needed by tracehook.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>

+126
+10
arch/sh/include/asm/syscall.h
··· 1 + #ifndef __ASM_SH_SYSCALL_H 2 + #define __ASM_SH_SYSCALL_H 3 + 4 + #ifdef CONFIG_SUPERH32 5 + # include "syscall_32.h" 6 + #else 7 + # include "syscall_64.h" 8 + #endif 9 + 10 + #endif /* __ASM_SH_SYSCALL_H */
+110
arch/sh/include/asm/syscall_32.h
··· 1 + #ifndef __ASM_SH_SYSCALL_32_H 2 + #define __ASM_SH_SYSCALL_32_H 3 + 4 + #include <linux/kernel.h> 5 + #include <linux/sched.h> 6 + #include <asm/ptrace.h> 7 + 8 + /* The system call number is given by the user in %g1 */ 9 + static inline long syscall_get_nr(struct task_struct *task, 10 + struct pt_regs *regs) 11 + { 12 + return (regs->tra >= 0) ? regs->regs[3] : -1L; 13 + } 14 + 15 + static inline void syscall_rollback(struct task_struct *task, 16 + struct pt_regs *regs) 17 + { 18 + /* 19 + * XXX: This needs some thought. On SH we don't 20 + * save away the original r0 value anywhere. 21 + */ 22 + } 23 + 24 + static inline bool syscall_has_error(struct pt_regs *regs) 25 + { 26 + return (regs->sr & 0x1) ? true : false; 27 + } 28 + static inline void syscall_set_error(struct pt_regs *regs) 29 + { 30 + regs->sr |= 0x1; 31 + } 32 + static inline void syscall_clear_error(struct pt_regs *regs) 33 + { 34 + regs->sr &= ~0x1; 35 + } 36 + 37 + static inline long syscall_get_error(struct task_struct *task, 38 + struct pt_regs *regs) 39 + { 40 + return syscall_has_error(regs) ? regs->regs[0] : 0; 41 + } 42 + 43 + static inline long syscall_get_return_value(struct task_struct *task, 44 + struct pt_regs *regs) 45 + { 46 + return regs->regs[0]; 47 + } 48 + 49 + static inline void syscall_set_return_value(struct task_struct *task, 50 + struct pt_regs *regs, 51 + int error, long val) 52 + { 53 + if (error) { 54 + syscall_set_error(regs); 55 + regs->regs[0] = -error; 56 + } else { 57 + syscall_clear_error(regs); 58 + regs->regs[0] = val; 59 + } 60 + } 61 + 62 + static inline void syscall_get_arguments(struct task_struct *task, 63 + struct pt_regs *regs, 64 + unsigned int i, unsigned int n, 65 + unsigned long *args) 66 + { 67 + /* 68 + * Do this simply for now. If we need to start supporting 69 + * fetching arguments from arbitrary indices, this will need some 70 + * extra logic. Presently there are no in-tree users that depend 71 + * on this behaviour. 72 + */ 73 + BUG_ON(i); 74 + 75 + /* Argument pattern is: R4, R5, R6, R7, R0, R1 */ 76 + switch (n) { 77 + case 6: args[5] = regs->regs[1]; 78 + case 5: args[4] = regs->regs[0]; 79 + case 4: args[3] = regs->regs[7]; 80 + case 3: args[2] = regs->regs[6]; 81 + case 2: args[1] = regs->regs[5]; 82 + case 1: args[0] = regs->regs[4]; 83 + break; 84 + default: 85 + BUG(); 86 + } 87 + } 88 + 89 + static inline void syscall_set_arguments(struct task_struct *task, 90 + struct pt_regs *regs, 91 + unsigned int i, unsigned int n, 92 + const unsigned long *args) 93 + { 94 + /* Same note as above applies */ 95 + BUG_ON(i); 96 + 97 + switch (n) { 98 + case 6: regs->regs[1] = args[5]; 99 + case 5: regs->regs[0] = args[4]; 100 + case 4: regs->regs[7] = args[3]; 101 + case 3: regs->regs[6] = args[2]; 102 + case 2: regs->regs[5] = args[1]; 103 + case 1: regs->regs[4] = args[0]; 104 + break; 105 + default: 106 + BUG(); 107 + } 108 + } 109 + 110 + #endif /* __ASM_SH_SYSCALL_32_H */
+6
arch/sh/include/asm/syscall_64.h
··· 1 + #ifndef __ASM_SH_SYSCALL_64_H 2 + #define __ASM_SH_SYSCALL_64_H 3 + 4 + #include <asm-generic/syscall.h> 5 + 6 + #endif /* __ASM_SH_SYSCALL_64_H */