summaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/entry.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/entry.S')
-rw-r--r--arch/s390/kernel/entry.S87
1 files changed, 32 insertions, 55 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index dddc3de3040..c8a2212014e 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -249,8 +249,6 @@ sysc_do_restart:
bnz BASED(sysc_tracesys)
basr %r14,%r8 # call sys_xxxx
st %r2,SP_R2(%r15) # store return value (change R2 on stack)
- # ATTENTION: check sys_execve_glue before
- # changing anything here !!
sysc_return:
tm SP_PSW+1(%r15),0x01 # returning to user ?
@@ -381,50 +379,37 @@ ret_from_fork:
b BASED(sysc_return)
#
-# clone, fork, vfork, exec and sigreturn need glue,
-# because they all expect pt_regs as parameter,
-# but are called with different parameter.
-# return-address is set up above
+# kernel_execve function needs to deal with pt_regs that is not
+# at the usual place
#
-sys_clone_glue:
- la %r2,SP_PTREGS(%r15) # load pt_regs
- l %r1,BASED(.Lclone)
- br %r1 # branch to sys_clone
-
-sys_fork_glue:
- la %r2,SP_PTREGS(%r15) # load pt_regs
- l %r1,BASED(.Lfork)
- br %r1 # branch to sys_fork
-
-sys_vfork_glue:
- la %r2,SP_PTREGS(%r15) # load pt_regs
- l %r1,BASED(.Lvfork)
- br %r1 # branch to sys_vfork
-
-sys_execve_glue:
- la %r2,SP_PTREGS(%r15) # load pt_regs
- l %r1,BASED(.Lexecve)
- lr %r12,%r14 # save return address
- basr %r14,%r1 # call sys_execve
- ltr %r2,%r2 # check if execve failed
- bnz 0(%r12) # it did fail -> store result in gpr2
- b 4(%r12) # SKIP ST 2,SP_R2(15) after BASR 14,8
- # in system_call/sysc_tracesys
-
-sys_sigreturn_glue:
- la %r2,SP_PTREGS(%r15) # load pt_regs as parameter
- l %r1,BASED(.Lsigreturn)
- br %r1 # branch to sys_sigreturn
-
-sys_rt_sigreturn_glue:
- la %r2,SP_PTREGS(%r15) # load pt_regs as parameter
- l %r1,BASED(.Lrt_sigreturn)
- br %r1 # branch to sys_sigreturn
-
-sys_sigaltstack_glue:
- la %r4,SP_PTREGS(%r15) # load pt_regs as parameter
- l %r1,BASED(.Lsigaltstack)
- br %r1 # branch to sys_sigreturn
+ .globl kernel_execve
+kernel_execve:
+ stm %r12,%r15,48(%r15)
+ lr %r14,%r15
+ l %r13,__LC_SVC_NEW_PSW+4
+ s %r15,BASED(.Lc_spsize)
+ st %r14,__SF_BACKCHAIN(%r15)
+ la %r12,SP_PTREGS(%r15)
+ xc 0(__PT_SIZE,%r12),0(%r12)
+ l %r1,BASED(.Ldo_execve)
+ lr %r5,%r12
+ basr %r14,%r1
+ ltr %r2,%r2
+ be BASED(0f)
+ a %r15,BASED(.Lc_spsize)
+ lm %r12,%r15,48(%r15)
+ br %r14
+ # execve succeeded.
+0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts
+ l %r15,__LC_KERNEL_STACK # load ksp
+ s %r15,BASED(.Lc_spsize) # make room for registers & psw
+ l %r9,__LC_THREAD_INFO
+ mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs
+ xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
+ stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
+ l %r1,BASED(.Lexecve_tail)
+ basr %r14,%r1
+ b BASED(sysc_return)
/*
* Program check handler routine
@@ -1031,19 +1016,11 @@ cleanup_io_leave_insn:
.Ldo_extint: .long do_extint
.Ldo_signal: .long do_signal
.Lhandle_per: .long do_single_step
+.Ldo_execve: .long do_execve
+.Lexecve_tail: .long execve_tail
.Ljump_table: .long pgm_check_table
.Lschedule: .long schedule
-.Lclone: .long sys_clone
-.Lexecve: .long sys_execve
-.Lfork: .long sys_fork
-.Lrt_sigreturn: .long sys_rt_sigreturn
-.Lrt_sigsuspend:
- .long sys_rt_sigsuspend
-.Lsigreturn: .long sys_sigreturn
-.Lsigsuspend: .long sys_sigsuspend
-.Lsigaltstack: .long sys_sigaltstack
.Ltrace: .long syscall_trace
-.Lvfork: .long sys_vfork
.Lschedtail: .long schedule_tail
.Lsysc_table: .long sys_call_table
#ifdef CONFIG_TRACE_IRQFLAGS