aboutsummaryrefslogtreecommitdiff
path: root/arch/s390/kernel
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-09-10 18:03:41 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-09-30 23:03:03 -0400
commit37fe5d41f6403b0ea84c1586548bf1b03f834af0 (patch)
tree37e404af54f246a686dba85099187415591cde9d /arch/s390/kernel
parent65f22a906e154e8086ed561904d09c3586de85f4 (diff)
s390: fold kernel_thread_helper() into ret_from_fork()
... and don't bother with syscall return path in case of kernel threads. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r--arch/s390/kernel/entry.S18
-rw-r--r--arch/s390/kernel/entry64.S16
-rw-r--r--arch/s390/kernel/process.c10
3 files changed, 28 insertions, 16 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 6286985a103..24de1cd3754 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -331,14 +331,26 @@ ENTRY(ret_from_fork)
l %r12,__LC_THREAD_INFO
l %r13,__LC_SVC_NEW_PSW+4
tm __PT_PSW+1(%r11),0x01 # forking a kernel thread ?
- jo 0f
- st %r15,__PT_R15(%r11) # store stack pointer for new kthread
-0: l %r1,BASED(.Lschedule_tail)
+ je 1f
+ l %r1,BASED(.Lschedule_tail)
basr %r14,%r1 # call schedule_tail
TRACE_IRQS_ON
ssm __LC_SVC_NEW_PSW # reenable interrupts
j sysc_tracenogo
+1: # it's a kernel thread
+ st %r15,__PT_R15(%r11) # store stack pointer for new kthread
+ l %r1,BASED(.Lschedule_tail)
+ basr %r14,%r1 # call schedule_tail
+ TRACE_IRQS_ON
+ ssm __LC_SVC_NEW_PSW # reenable interrupts
+ lm %r9,%r11,__PT_R9(%r11) # load gprs
+ENTRY(kernel_thread_starter)
+ la %r2,0(%r10)
+ basr %r14,%r9
+ la %r2,0
+ br %r11 # do_exit
+
#
# kernel_execve function needs to deal with pt_regs that is not
# at the usual place
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 1f776f2edda..39c84e65f74 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -352,12 +352,22 @@ ENTRY(ret_from_fork)
la %r11,STACK_FRAME_OVERHEAD(%r15)
lg %r12,__LC_THREAD_INFO
tm __PT_PSW+1(%r11),0x01 # forking a kernel thread ?
- jo 0f
- stg %r15,__PT_R15(%r11) # store stack pointer for new kthread
-0: brasl %r14,schedule_tail
+ je 1f
+ brasl %r14,schedule_tail
TRACE_IRQS_ON
ssm __LC_SVC_NEW_PSW # reenable interrupts
j sysc_tracenogo
+1: # it's a kernel thread
+ stg %r15,__PT_R15(%r11) # store stack pointer for new kthread
+ brasl %r14,schedule_tail
+ TRACE_IRQS_ON
+ ssm __LC_SVC_NEW_PSW # reenable interrupts
+ lmg %r9,%r11,__PT_R9(%r11) # load gprs
+ENTRY(kernel_thread_starter)
+ la %r2,0(%r10)
+ basr %r14,%r9
+ la %r2,0
+ br %r11 # do_exit
#
# kernel_execve function needs to deal with pt_regs that is not
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index e540251e1dd..2868a364ff9 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -98,16 +98,6 @@ void cpu_idle(void)
extern void __kprobes kernel_thread_starter(void);
-asm(
- ".section .kprobes.text, \"ax\"\n"
- ".global kernel_thread_starter\n"
- "kernel_thread_starter:\n"
- " la 2,0(10)\n"
- " basr 14,9\n"
- " la 2,0\n"
- " br 11\n"
- ".previous\n");
-
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
struct pt_regs regs;