Commit b2450cc1b7ce07d73545ece32db50197d649e230
Committed by
Kyle McMartin
1 parent
8b631342dd
[PARISC] Implement 5 argument clone.
* arch/parisc/kernel/process.c (sys_clone): Use 5 args, and process CLONE_PARENT_SETTID, CLONE_CHILD_SETTID, CLONE_CHILD_CLEARTID. (copy_thread): First cut at CLONE_SETTLS. Signed-off-by: Carlos O'Donell <carlos@parisc-linux.org> Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
Showing 1 changed file with 29 additions and 5 deletions Side-by-side Diff
arch/parisc/kernel/process.c
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | * Copyright (C) 2000-2003 Paul Bame <bame at parisc-linux.org> |
10 | 10 | * Copyright (C) 2000 Philipp Rumpf <prumpf with tux.org> |
11 | 11 | * Copyright (C) 2000 David Kennedy <dkennedy with linuxcare.com> |
12 | - * Copyright (C) 2000 Richard Hirst <rhirst with parisc-lixux.org> | |
12 | + * Copyright (C) 2000 Richard Hirst <rhirst with parisc-linux.org> | |
13 | 13 | * Copyright (C) 2000 Grant Grundler <grundler with parisc-linux.org> |
14 | 14 | * Copyright (C) 2001 Alan Modra <amodra at parisc-linux.org> |
15 | 15 | * Copyright (C) 2001-2002 Ryan Bradetich <rbrad at parisc-linux.org> |
... | ... | @@ -245,7 +245,17 @@ |
245 | 245 | sys_clone(unsigned long clone_flags, unsigned long usp, |
246 | 246 | struct pt_regs *regs) |
247 | 247 | { |
248 | - int __user *user_tid = (int __user *)regs->gr[26]; | |
248 | + /* Arugments from userspace are: | |
249 | + r26 = Clone flags. | |
250 | + r25 = Child stack. | |
251 | + r24 = parent_tidptr. | |
252 | + r23 = Is the TLS storage descriptor | |
253 | + r22 = child_tidptr | |
254 | + | |
255 | + However, these last 3 args are only examined | |
256 | + if the proper flags are set. */ | |
257 | + int __user *child_tidptr; | |
258 | + int __user *parent_tidptr; | |
249 | 259 | |
250 | 260 | /* usp must be word aligned. This also prevents users from |
251 | 261 | * passing in the value 1 (which is the signal for a special |
252 | 262 | |
... | ... | @@ -253,10 +263,20 @@ |
253 | 263 | usp = ALIGN(usp, 4); |
254 | 264 | |
255 | 265 | /* A zero value for usp means use the current stack */ |
256 | - if(usp == 0) | |
257 | - usp = regs->gr[30]; | |
266 | + if (usp == 0) | |
267 | + usp = regs->gr[30]; | |
258 | 268 | |
259 | - return do_fork(clone_flags, usp, regs, 0, user_tid, NULL); | |
269 | + if (clone_flags & CLONE_PARENT_SETTID) | |
270 | + parent_tidptr = (int __user *)regs->gr[24]; | |
271 | + else | |
272 | + parent_tidptr = NULL; | |
273 | + | |
274 | + if (clone_flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) | |
275 | + child_tidptr = (int __user *)regs->gr[22]; | |
276 | + else | |
277 | + child_tidptr = NULL; | |
278 | + | |
279 | + return do_fork(clone_flags, usp, regs, 0, parent_tidptr, child_tidptr); | |
260 | 280 | } |
261 | 281 | |
262 | 282 | int |
... | ... | @@ -332,6 +352,10 @@ |
332 | 352 | } else { |
333 | 353 | cregs->kpc = (unsigned long) &child_return; |
334 | 354 | } |
355 | + /* Setup thread TLS area from the 4th parameter in clone */ | |
356 | + if (clone_flags & CLONE_SETTLS) | |
357 | + cregs->cr27 = pregs->gr[23]; | |
358 | + | |
335 | 359 | } |
336 | 360 | |
337 | 361 | return 0; |