summaryrefslogtreecommitdiff
path: root/arch/mips/include/asm/syscall.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/include/asm/syscall.h')
-rw-r--r--arch/mips/include/asm/syscall.h43
1 files changed, 43 insertions, 0 deletions
diff --git a/arch/mips/include/asm/syscall.h b/arch/mips/include/asm/syscall.h
index 056aa1b713e2..d19e67e2aa6a 100644
--- a/arch/mips/include/asm/syscall.h
+++ b/arch/mips/include/asm/syscall.h
@@ -41,6 +41,21 @@ static inline long syscall_get_nr(struct task_struct *task,
return task_thread_info(task)->syscall;
}
+static inline void syscall_set_nr(struct task_struct *task,
+ struct pt_regs *regs,
+ int nr)
+{
+ /*
+ * New syscall number has to be assigned to regs[2] because
+ * it is loaded from there unconditionally after return from
+ * syscall_trace_enter() invocation.
+ *
+ * Consequently, if the syscall was indirect and nr != __NR_syscall,
+ * then after this assignment the syscall will cease to be indirect.
+ */
+ task_thread_info(task)->syscall = regs->regs[2] = nr;
+}
+
static inline void mips_syscall_update_nr(struct task_struct *task,
struct pt_regs *regs)
{
@@ -74,6 +89,23 @@ static inline void mips_get_syscall_arg(unsigned long *arg,
#endif
}
+static inline void mips_set_syscall_arg(unsigned long *arg,
+ struct task_struct *task, struct pt_regs *regs, unsigned int n)
+{
+#ifdef CONFIG_32BIT
+ switch (n) {
+ case 0: case 1: case 2: case 3:
+ regs->regs[4 + n] = *arg;
+ return;
+ case 4: case 5: case 6: case 7:
+ *arg = regs->args[n] = *arg;
+ return;
+ }
+#else
+ regs->regs[4 + n] = *arg;
+#endif
+}
+
static inline long syscall_get_error(struct task_struct *task,
struct pt_regs *regs)
{
@@ -120,6 +152,17 @@ static inline void syscall_get_arguments(struct task_struct *task,
mips_get_syscall_arg(args++, task, regs, i++);
}
+static inline void syscall_set_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned long *args)
+{
+ unsigned int i = 0;
+ unsigned int n = 6;
+
+ while (n--)
+ mips_set_syscall_arg(args++, task, regs, i++);
+}
+
extern const unsigned long sys_call_table[];
extern const unsigned long sys32_call_table[];
extern const unsigned long sysn32_call_table[];