diff options
Diffstat (limited to 'arch/arm64/include/asm/syscall.h')
| -rw-r--r-- | arch/arm64/include/asm/syscall.h | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h index ab8e14b96f68..5e4c7fc44f73 100644 --- a/arch/arm64/include/asm/syscall.h +++ b/arch/arm64/include/asm/syscall.h @@ -61,16 +61,51 @@ static inline void syscall_set_return_value(struct task_struct *task, regs->regs[0] = val; } -#define SYSCALL_MAX_ARGS 6 +static inline void syscall_set_nr(struct task_struct *task, + struct pt_regs *regs, + int nr) +{ + regs->syscallno = nr; + if (nr == -1) { + /* + * When the syscall number is set to -1, the syscall will be + * skipped. In this case the syscall return value has to be + * set explicitly, otherwise the first syscall argument is + * returned as the syscall return value. + */ + syscall_set_return_value(task, regs, -ENOSYS, 0); + } +} static inline void syscall_get_arguments(struct task_struct *task, struct pt_regs *regs, unsigned long *args) { args[0] = regs->orig_x0; - args++; + args[1] = regs->regs[1]; + args[2] = regs->regs[2]; + args[3] = regs->regs[3]; + args[4] = regs->regs[4]; + args[5] = regs->regs[5]; +} - memcpy(args, ®s->regs[1], 5 * sizeof(args[0])); +static inline void syscall_set_arguments(struct task_struct *task, + struct pt_regs *regs, + const unsigned long *args) +{ + regs->regs[0] = args[0]; + regs->regs[1] = args[1]; + regs->regs[2] = args[2]; + regs->regs[3] = args[3]; + regs->regs[4] = args[4]; + regs->regs[5] = args[5]; + + /* + * Also copy the first argument into orig_x0 + * so that syscall_get_arguments() would return it + * instead of the previous value. + */ + regs->orig_x0 = regs->regs[0]; } /* |
