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/entry.S | |
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/entry.S')
-rw-r--r-- | arch/s390/kernel/entry.S | 87 |
1 files changed, 32 insertions, 55 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index dddc3de30401..c8a2212014e0 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -249,8 +249,6 @@ sysc_do_restart: | |||
249 | bnz BASED(sysc_tracesys) | 249 | bnz BASED(sysc_tracesys) |
250 | basr %r14,%r8 # call sys_xxxx | 250 | basr %r14,%r8 # call sys_xxxx |
251 | st %r2,SP_R2(%r15) # store return value (change R2 on stack) | 251 | st %r2,SP_R2(%r15) # store return value (change R2 on stack) |
252 | # ATTENTION: check sys_execve_glue before | ||
253 | # changing anything here !! | ||
254 | 252 | ||
255 | sysc_return: | 253 | sysc_return: |
256 | tm SP_PSW+1(%r15),0x01 # returning to user ? | 254 | tm SP_PSW+1(%r15),0x01 # returning to user ? |
@@ -381,50 +379,37 @@ ret_from_fork: | |||
381 | b BASED(sysc_return) | 379 | b BASED(sysc_return) |
382 | 380 | ||
383 | # | 381 | # |
384 | # clone, fork, vfork, exec and sigreturn need glue, | 382 | # kernel_execve function needs to deal with pt_regs that is not |
385 | # because they all expect pt_regs as parameter, | 383 | # at the usual place |
386 | # but are called with different parameter. | ||
387 | # return-address is set up above | ||
388 | # | 384 | # |
389 | sys_clone_glue: | 385 | .globl kernel_execve |
390 | la %r2,SP_PTREGS(%r15) # load pt_regs | 386 | kernel_execve: |
391 | l %r1,BASED(.Lclone) | 387 | stm %r12,%r15,48(%r15) |
392 | br %r1 # branch to sys_clone | 388 | lr %r14,%r15 |
393 | 389 | l %r13,__LC_SVC_NEW_PSW+4 | |
394 | sys_fork_glue: | 390 | s %r15,BASED(.Lc_spsize) |
395 | la %r2,SP_PTREGS(%r15) # load pt_regs | 391 | st %r14,__SF_BACKCHAIN(%r15) |
396 | l %r1,BASED(.Lfork) | 392 | la %r12,SP_PTREGS(%r15) |
397 | br %r1 # branch to sys_fork | 393 | xc 0(__PT_SIZE,%r12),0(%r12) |
398 | 394 | l %r1,BASED(.Ldo_execve) | |
399 | sys_vfork_glue: | 395 | lr %r5,%r12 |
400 | la %r2,SP_PTREGS(%r15) # load pt_regs | 396 | basr %r14,%r1 |
401 | l %r1,BASED(.Lvfork) | 397 | ltr %r2,%r2 |
402 | br %r1 # branch to sys_vfork | 398 | be BASED(0f) |
403 | 399 | a %r15,BASED(.Lc_spsize) | |
404 | sys_execve_glue: | 400 | lm %r12,%r15,48(%r15) |
405 | la %r2,SP_PTREGS(%r15) # load pt_regs | 401 | br %r14 |
406 | l %r1,BASED(.Lexecve) | 402 | # execve succeeded. |
407 | lr %r12,%r14 # save return address | 403 | 0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts |
408 | basr %r14,%r1 # call sys_execve | 404 | l %r15,__LC_KERNEL_STACK # load ksp |
409 | ltr %r2,%r2 # check if execve failed | 405 | s %r15,BASED(.Lc_spsize) # make room for registers & psw |
410 | bnz 0(%r12) # it did fail -> store result in gpr2 | 406 | l %r9,__LC_THREAD_INFO |
411 | b 4(%r12) # SKIP ST 2,SP_R2(15) after BASR 14,8 | 407 | mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs |
412 | # in system_call/sysc_tracesys | 408 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) |
413 | 409 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | |
414 | sys_sigreturn_glue: | 410 | l %r1,BASED(.Lexecve_tail) |
415 | la %r2,SP_PTREGS(%r15) # load pt_regs as parameter | 411 | basr %r14,%r1 |
416 | l %r1,BASED(.Lsigreturn) | 412 | b BASED(sysc_return) |
417 | br %r1 # branch to sys_sigreturn | ||
418 | |||
419 | sys_rt_sigreturn_glue: | ||
420 | la %r2,SP_PTREGS(%r15) # load pt_regs as parameter | ||
421 | l %r1,BASED(.Lrt_sigreturn) | ||
422 | br %r1 # branch to sys_sigreturn | ||
423 | |||
424 | sys_sigaltstack_glue: | ||
425 | la %r4,SP_PTREGS(%r15) # load pt_regs as parameter | ||
426 | l %r1,BASED(.Lsigaltstack) | ||
427 | br %r1 # branch to sys_sigreturn | ||
428 | 413 | ||
429 | /* | 414 | /* |
430 | * Program check handler routine | 415 | * Program check handler routine |
@@ -1031,19 +1016,11 @@ cleanup_io_leave_insn: | |||
1031 | .Ldo_extint: .long do_extint | 1016 | .Ldo_extint: .long do_extint |
1032 | .Ldo_signal: .long do_signal | 1017 | .Ldo_signal: .long do_signal |
1033 | .Lhandle_per: .long do_single_step | 1018 | .Lhandle_per: .long do_single_step |
1019 | .Ldo_execve: .long do_execve | ||
1020 | .Lexecve_tail: .long execve_tail | ||
1034 | .Ljump_table: .long pgm_check_table | 1021 | .Ljump_table: .long pgm_check_table |
1035 | .Lschedule: .long schedule | 1022 | .Lschedule: .long schedule |
1036 | .Lclone: .long sys_clone | ||
1037 | .Lexecve: .long sys_execve | ||
1038 | .Lfork: .long sys_fork | ||
1039 | .Lrt_sigreturn: .long sys_rt_sigreturn | ||
1040 | .Lrt_sigsuspend: | ||
1041 | .long sys_rt_sigsuspend | ||
1042 | .Lsigreturn: .long sys_sigreturn | ||
1043 | .Lsigsuspend: .long sys_sigsuspend | ||
1044 | .Lsigaltstack: .long sys_sigaltstack | ||
1045 | .Ltrace: .long syscall_trace | 1023 | .Ltrace: .long syscall_trace |
1046 | .Lvfork: .long sys_vfork | ||
1047 | .Lschedtail: .long schedule_tail | 1024 | .Lschedtail: .long schedule_tail |
1048 | .Lsysc_table: .long sys_call_table | 1025 | .Lsysc_table: .long sys_call_table |
1049 | #ifdef CONFIG_TRACE_IRQFLAGS | 1026 | #ifdef CONFIG_TRACE_IRQFLAGS |