diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2007-04-27 10:01:40 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2007-04-27 10:01:42 -0400 |
commit | 03ff9a235a0602724fc54916469b6e0939c62c9b (patch) | |
tree | 86ab2236897eb59542be2ccd667d6ca221153a44 /arch/s390/kernel/process.c | |
parent | ef99516c9646802c3d38c3eb83de302e05b3c1b5 (diff) |
[S390] System call cleanup.
Remove system call glue for sys_clone, sys_fork, sys_vfork, sys_execve,
sys_sigreturn, sys_rt_sigreturn and sys_sigaltstack. Call do_execve from
kernel_execve directly, move pt_regs to the right place and branch to
sysc_return to start the user space program. This removes the last
in-kernel system call.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/process.c')
-rw-r--r-- | arch/s390/kernel/process.c | 82 |
1 files changed, 48 insertions, 34 deletions
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 5acfac654f9d..11d9b0197626 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c | |||
@@ -280,24 +280,26 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp, | |||
280 | return 0; | 280 | return 0; |
281 | } | 281 | } |
282 | 282 | ||
283 | asmlinkage long sys_fork(struct pt_regs regs) | 283 | asmlinkage long sys_fork(void) |
284 | { | 284 | { |
285 | return do_fork(SIGCHLD, regs.gprs[15], ®s, 0, NULL, NULL); | 285 | struct pt_regs *regs = task_pt_regs(current); |
286 | return do_fork(SIGCHLD, regs->gprs[15], regs, 0, NULL, NULL); | ||
286 | } | 287 | } |
287 | 288 | ||
288 | asmlinkage long sys_clone(struct pt_regs regs) | 289 | asmlinkage long sys_clone(void) |
289 | { | 290 | { |
290 | unsigned long clone_flags; | 291 | struct pt_regs *regs = task_pt_regs(current); |
291 | unsigned long newsp; | 292 | unsigned long clone_flags; |
293 | unsigned long newsp; | ||
292 | int __user *parent_tidptr, *child_tidptr; | 294 | int __user *parent_tidptr, *child_tidptr; |
293 | 295 | ||
294 | clone_flags = regs.gprs[3]; | 296 | clone_flags = regs->gprs[3]; |
295 | newsp = regs.orig_gpr2; | 297 | newsp = regs->orig_gpr2; |
296 | parent_tidptr = (int __user *) regs.gprs[4]; | 298 | parent_tidptr = (int __user *) regs->gprs[4]; |
297 | child_tidptr = (int __user *) regs.gprs[5]; | 299 | child_tidptr = (int __user *) regs->gprs[5]; |
298 | if (!newsp) | 300 | if (!newsp) |
299 | newsp = regs.gprs[15]; | 301 | newsp = regs->gprs[15]; |
300 | return do_fork(clone_flags, newsp, ®s, 0, | 302 | return do_fork(clone_flags, newsp, regs, 0, |
301 | parent_tidptr, child_tidptr); | 303 | parent_tidptr, child_tidptr); |
302 | } | 304 | } |
303 | 305 | ||
@@ -311,40 +313,52 @@ asmlinkage long sys_clone(struct pt_regs regs) | |||
311 | * do not have enough call-clobbered registers to hold all | 313 | * do not have enough call-clobbered registers to hold all |
312 | * the information you need. | 314 | * the information you need. |
313 | */ | 315 | */ |
314 | asmlinkage long sys_vfork(struct pt_regs regs) | 316 | asmlinkage long sys_vfork(void) |
315 | { | 317 | { |
318 | struct pt_regs *regs = task_pt_regs(current); | ||
316 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, | 319 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, |
317 | regs.gprs[15], ®s, 0, NULL, NULL); | 320 | regs->gprs[15], regs, 0, NULL, NULL); |
321 | } | ||
322 | |||
323 | asmlinkage void execve_tail(void) | ||
324 | { | ||
325 | task_lock(current); | ||
326 | current->ptrace &= ~PT_DTRACE; | ||
327 | task_unlock(current); | ||
328 | current->thread.fp_regs.fpc = 0; | ||
329 | if (MACHINE_HAS_IEEE) | ||
330 | asm volatile("sfpc %0,%0" : : "d" (0)); | ||
318 | } | 331 | } |
319 | 332 | ||
320 | /* | 333 | /* |
321 | * sys_execve() executes a new program. | 334 | * sys_execve() executes a new program. |
322 | */ | 335 | */ |
323 | asmlinkage long sys_execve(struct pt_regs regs) | 336 | asmlinkage long sys_execve(void) |
324 | { | 337 | { |
325 | int error; | 338 | struct pt_regs *regs = task_pt_regs(current); |
326 | char * filename; | 339 | char *filename; |
327 | 340 | unsigned long result; | |
328 | filename = getname((char __user *) regs.orig_gpr2); | 341 | int rc; |
329 | error = PTR_ERR(filename); | 342 | |
330 | if (IS_ERR(filename)) | 343 | filename = getname((char __user *) regs->orig_gpr2); |
331 | goto out; | 344 | if (IS_ERR(filename)) { |
332 | error = do_execve(filename, (char __user * __user *) regs.gprs[3], | 345 | result = PTR_ERR(filename); |
333 | (char __user * __user *) regs.gprs[4], ®s); | 346 | goto out; |
334 | if (error == 0) { | ||
335 | task_lock(current); | ||
336 | current->ptrace &= ~PT_DTRACE; | ||
337 | task_unlock(current); | ||
338 | current->thread.fp_regs.fpc = 0; | ||
339 | if (MACHINE_HAS_IEEE) | ||
340 | asm volatile("sfpc %0,%0" : : "d" (0)); | ||
341 | } | 347 | } |
342 | putname(filename); | 348 | rc = do_execve(filename, (char __user * __user *) regs->gprs[3], |
349 | (char __user * __user *) regs->gprs[4], regs); | ||
350 | if (rc) { | ||
351 | result = rc; | ||
352 | goto out_putname; | ||
353 | } | ||
354 | execve_tail(); | ||
355 | result = regs->gprs[2]; | ||
356 | out_putname: | ||
357 | putname(filename); | ||
343 | out: | 358 | out: |
344 | return error; | 359 | return result; |
345 | } | 360 | } |
346 | 361 | ||
347 | |||
348 | /* | 362 | /* |
349 | * fill in the FPU structure for a core dump. | 363 | * fill in the FPU structure for a core dump. |
350 | */ | 364 | */ |