diff options
Diffstat (limited to 'arch/mips/kernel/syscall.c')
-rw-r--r-- | arch/mips/kernel/syscall.c | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 8fde242596f9..ee98eeb65e85 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. | 7 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. |
8 | * Copyright (C) 2001 MIPS Technologies, Inc. | 8 | * Copyright (C) 2001 MIPS Technologies, Inc. |
9 | */ | 9 | */ |
10 | #include <linux/config.h> | ||
10 | #include <linux/a.out.h> | 11 | #include <linux/a.out.h> |
11 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
12 | #include <linux/linkage.h> | 13 | #include <linux/linkage.h> |
@@ -176,14 +177,28 @@ _sys_clone(nabi_no_regargs struct pt_regs regs) | |||
176 | { | 177 | { |
177 | unsigned long clone_flags; | 178 | unsigned long clone_flags; |
178 | unsigned long newsp; | 179 | unsigned long newsp; |
179 | int *parent_tidptr, *child_tidptr; | 180 | int __user *parent_tidptr, *child_tidptr; |
180 | 181 | ||
181 | clone_flags = regs.regs[4]; | 182 | clone_flags = regs.regs[4]; |
182 | newsp = regs.regs[5]; | 183 | newsp = regs.regs[5]; |
183 | if (!newsp) | 184 | if (!newsp) |
184 | newsp = regs.regs[29]; | 185 | newsp = regs.regs[29]; |
185 | parent_tidptr = (int *) regs.regs[6]; | 186 | parent_tidptr = (int __user *) regs.regs[6]; |
186 | child_tidptr = (int *) regs.regs[7]; | 187 | #ifdef CONFIG_32BIT |
188 | /* We need to fetch the fifth argument off the stack. */ | ||
189 | child_tidptr = NULL; | ||
190 | if (clone_flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) { | ||
191 | int __user *__user *usp = (int __user *__user *) regs.regs[29]; | ||
192 | if (regs.regs[2] == __NR_syscall) { | ||
193 | if (get_user (child_tidptr, &usp[5])) | ||
194 | return -EFAULT; | ||
195 | } | ||
196 | else if (get_user (child_tidptr, &usp[4])) | ||
197 | return -EFAULT; | ||
198 | } | ||
199 | #else | ||
200 | child_tidptr = (int __user *) regs.regs[8]; | ||
201 | #endif | ||
187 | return do_fork(clone_flags, newsp, ®s, 0, | 202 | return do_fork(clone_flags, newsp, ®s, 0, |
188 | parent_tidptr, child_tidptr); | 203 | parent_tidptr, child_tidptr); |
189 | } | 204 | } |
@@ -245,6 +260,16 @@ asmlinkage int sys_olduname(struct oldold_utsname * name) | |||
245 | return error; | 260 | return error; |
246 | } | 261 | } |
247 | 262 | ||
263 | void sys_set_thread_area(unsigned long addr) | ||
264 | { | ||
265 | struct thread_info *ti = current->thread_info; | ||
266 | |||
267 | ti->tp_value = addr; | ||
268 | |||
269 | /* If some future MIPS implementation has this register in hardware, | ||
270 | * we will need to update it here (and in context switches). */ | ||
271 | } | ||
272 | |||
248 | asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3) | 273 | asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3) |
249 | { | 274 | { |
250 | int tmp, len; | 275 | int tmp, len; |