summary refs log tree commit diff
path: root/arch/s390
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
parent65f22a906e154e8086ed561904d09c3586de85f4 (diff)
downloadlinux-37fe5d41f6403b0ea84c1586548bf1b03f834af0.tar.gz
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')
-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 6286985a1039..24de1cd3754b 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 1f776f2edda5..39c84e65f74f 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 e540251e1dd1..2868a364ff94 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;