diff options
Diffstat (limited to 'arch/mips/kernel/syscall.c')
-rw-r--r-- | arch/mips/kernel/syscall.c | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 21e3e13a4b44..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> |
@@ -26,6 +27,7 @@ | |||
26 | #include <linux/msg.h> | 27 | #include <linux/msg.h> |
27 | #include <linux/shm.h> | 28 | #include <linux/shm.h> |
28 | #include <linux/compiler.h> | 29 | #include <linux/compiler.h> |
30 | #include <linux/module.h> | ||
29 | 31 | ||
30 | #include <asm/branch.h> | 32 | #include <asm/branch.h> |
31 | #include <asm/cachectl.h> | 33 | #include <asm/cachectl.h> |
@@ -56,6 +58,8 @@ out: | |||
56 | 58 | ||
57 | unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */ | 59 | unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */ |
58 | 60 | ||
61 | EXPORT_SYMBOL(shm_align_mask); | ||
62 | |||
59 | #define COLOUR_ALIGN(addr,pgoff) \ | 63 | #define COLOUR_ALIGN(addr,pgoff) \ |
60 | ((((addr) + shm_align_mask) & ~shm_align_mask) + \ | 64 | ((((addr) + shm_align_mask) & ~shm_align_mask) + \ |
61 | (((pgoff) << PAGE_SHIFT) & shm_align_mask)) | 65 | (((pgoff) << PAGE_SHIFT) & shm_align_mask)) |
@@ -173,14 +177,28 @@ _sys_clone(nabi_no_regargs struct pt_regs regs) | |||
173 | { | 177 | { |
174 | unsigned long clone_flags; | 178 | unsigned long clone_flags; |
175 | unsigned long newsp; | 179 | unsigned long newsp; |
176 | int *parent_tidptr, *child_tidptr; | 180 | int __user *parent_tidptr, *child_tidptr; |
177 | 181 | ||
178 | clone_flags = regs.regs[4]; | 182 | clone_flags = regs.regs[4]; |
179 | newsp = regs.regs[5]; | 183 | newsp = regs.regs[5]; |
180 | if (!newsp) | 184 | if (!newsp) |
181 | newsp = regs.regs[29]; | 185 | newsp = regs.regs[29]; |
182 | parent_tidptr = (int *) regs.regs[6]; | 186 | parent_tidptr = (int __user *) regs.regs[6]; |
183 | 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 | ||
184 | return do_fork(clone_flags, newsp, ®s, 0, | 202 | return do_fork(clone_flags, newsp, ®s, 0, |
185 | parent_tidptr, child_tidptr); | 203 | parent_tidptr, child_tidptr); |
186 | } | 204 | } |
@@ -242,6 +260,16 @@ asmlinkage int sys_olduname(struct oldold_utsname * name) | |||
242 | return error; | 260 | return error; |
243 | } | 261 | } |
244 | 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 | |||
245 | 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) |
246 | { | 274 | { |
247 | int tmp, len; | 275 | int tmp, len; |