summaryrefslogtreecommitdiff
path: root/arch/arm64/include/asm/syscall.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64/include/asm/syscall.h')
-rw-r--r--arch/arm64/include/asm/syscall.h41
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, &regs->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];
}
/*