diff options
Diffstat (limited to 'arch/nds32/include/asm/syscall.h')
| -rw-r--r-- | arch/nds32/include/asm/syscall.h | 62 |
1 files changed, 11 insertions, 51 deletions
diff --git a/arch/nds32/include/asm/syscall.h b/arch/nds32/include/asm/syscall.h index f7e5e86765fe..671ebd357496 100644 --- a/arch/nds32/include/asm/syscall.h +++ b/arch/nds32/include/asm/syscall.h | |||
| @@ -108,81 +108,41 @@ void syscall_set_return_value(struct task_struct *task, struct pt_regs *regs, | |||
| 108 | * syscall_get_arguments - extract system call parameter values | 108 | * syscall_get_arguments - extract system call parameter values |
| 109 | * @task: task of interest, must be blocked | 109 | * @task: task of interest, must be blocked |
| 110 | * @regs: task_pt_regs() of @task | 110 | * @regs: task_pt_regs() of @task |
| 111 | * @i: argument index [0,5] | ||
| 112 | * @n: number of arguments; n+i must be [1,6]. | ||
| 113 | * @args: array filled with argument values | 111 | * @args: array filled with argument values |
| 114 | * | 112 | * |
| 115 | * Fetches @n arguments to the system call starting with the @i'th argument | 113 | * Fetches 6 arguments to the system call (from 0 through 5). The first |
| 116 | * (from 0 through 5). Argument @i is stored in @args[0], and so on. | 114 | * argument is stored in @args[0], and so on. |
| 117 | * An arch inline version is probably optimal when @i and @n are constants. | ||
| 118 | * | 115 | * |
| 119 | * It's only valid to call this when @task is stopped for tracing on | 116 | * It's only valid to call this when @task is stopped for tracing on |
| 120 | * entry to a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. | 117 | * entry to a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. |
| 121 | * It's invalid to call this with @i + @n > 6; we only support system calls | ||
| 122 | * taking up to 6 arguments. | ||
| 123 | */ | 118 | */ |
| 124 | #define SYSCALL_MAX_ARGS 6 | 119 | #define SYSCALL_MAX_ARGS 6 |
| 125 | void syscall_get_arguments(struct task_struct *task, struct pt_regs *regs, | 120 | void syscall_get_arguments(struct task_struct *task, struct pt_regs *regs, |
| 126 | unsigned int i, unsigned int n, unsigned long *args) | 121 | unsigned long *args) |
| 127 | { | 122 | { |
| 128 | if (n == 0) | 123 | args[0] = regs->orig_r0; |
| 129 | return; | 124 | args++; |
| 130 | if (i + n > SYSCALL_MAX_ARGS) { | 125 | memcpy(args, ®s->uregs[0] + 1, 5 * sizeof(args[0])); |
| 131 | unsigned long *args_bad = args + SYSCALL_MAX_ARGS - i; | ||
| 132 | unsigned int n_bad = n + i - SYSCALL_MAX_ARGS; | ||
| 133 | pr_warning("%s called with max args %d, handling only %d\n", | ||
| 134 | __func__, i + n, SYSCALL_MAX_ARGS); | ||
| 135 | memset(args_bad, 0, n_bad * sizeof(args[0])); | ||
| 136 | memset(args_bad, 0, n_bad * sizeof(args[0])); | ||
| 137 | } | ||
| 138 | |||
| 139 | if (i == 0) { | ||
| 140 | args[0] = regs->orig_r0; | ||
| 141 | args++; | ||
| 142 | i++; | ||
| 143 | n--; | ||
| 144 | } | ||
| 145 | |||
| 146 | memcpy(args, ®s->uregs[0] + i, n * sizeof(args[0])); | ||
| 147 | } | 126 | } |
| 148 | 127 | ||
| 149 | /** | 128 | /** |
| 150 | * syscall_set_arguments - change system call parameter value | 129 | * syscall_set_arguments - change system call parameter value |
| 151 | * @task: task of interest, must be in system call entry tracing | 130 | * @task: task of interest, must be in system call entry tracing |
| 152 | * @regs: task_pt_regs() of @task | 131 | * @regs: task_pt_regs() of @task |
| 153 | * @i: argument index [0,5] | ||
| 154 | * @n: number of arguments; n+i must be [1,6]. | ||
| 155 | * @args: array of argument values to store | 132 | * @args: array of argument values to store |
| 156 | * | 133 | * |
| 157 | * Changes @n arguments to the system call starting with the @i'th argument. | 134 | * Changes 6 arguments to the system call. The first argument gets value |
| 158 | * Argument @i gets value @args[0], and so on. | 135 | * @args[0], and so on. |
| 159 | * An arch inline version is probably optimal when @i and @n are constants. | ||
| 160 | * | 136 | * |
| 161 | * It's only valid to call this when @task is stopped for tracing on | 137 | * It's only valid to call this when @task is stopped for tracing on |
| 162 | * entry to a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. | 138 | * entry to a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT. |
| 163 | * It's invalid to call this with @i + @n > 6; we only support system calls | ||
| 164 | * taking up to 6 arguments. | ||
| 165 | */ | 139 | */ |
| 166 | void syscall_set_arguments(struct task_struct *task, struct pt_regs *regs, | 140 | void syscall_set_arguments(struct task_struct *task, struct pt_regs *regs, |
| 167 | unsigned int i, unsigned int n, | ||
| 168 | const unsigned long *args) | 141 | const unsigned long *args) |
| 169 | { | 142 | { |
| 170 | if (n == 0) | 143 | regs->orig_r0 = args[0]; |
| 171 | return; | 144 | args++; |
| 172 | |||
| 173 | if (i + n > SYSCALL_MAX_ARGS) { | ||
| 174 | pr_warn("%s called with max args %d, handling only %d\n", | ||
| 175 | __func__, i + n, SYSCALL_MAX_ARGS); | ||
| 176 | n = SYSCALL_MAX_ARGS - i; | ||
| 177 | } | ||
| 178 | |||
| 179 | if (i == 0) { | ||
| 180 | regs->orig_r0 = args[0]; | ||
| 181 | args++; | ||
| 182 | i++; | ||
| 183 | n--; | ||
| 184 | } | ||
| 185 | 145 | ||
| 186 | memcpy(®s->uregs[0] + i, args, n * sizeof(args[0])); | 146 | memcpy(®s->uregs[0] + 1, args, 5 * sizeof(args[0])); |
| 187 | } | 147 | } |
| 188 | #endif /* _ASM_NDS32_SYSCALL_H */ | 148 | #endif /* _ASM_NDS32_SYSCALL_H */ |
