From 557e1995a92d318206910d8b5c62075fe02b37e0 Mon Sep 17 00:00:00 2001
From: Al Viro <viro@zeniv.linux.org.uk>
Date: Wed, 10 Oct 2012 13:17:31 -0400
Subject: h8300: generic kernel_thread()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 arch/h8300/Kconfig                 |  1 +
 arch/h8300/include/asm/processor.h |  2 --
 arch/h8300/include/asm/ptrace.h    |  2 ++
 arch/h8300/kernel/entry.S          | 10 ++++++++++
 arch/h8300/kernel/h8300_ksyms.c    |  1 -
 arch/h8300/kernel/process.c        | 41 ++++++++------------------------------
 6 files changed, 21 insertions(+), 36 deletions(-)

(limited to 'arch/h8300')

diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index 98fabd10e95f..4cef8a91c2a0 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -8,6 +8,7 @@ config H8300
 	select GENERIC_IRQ_SHOW
 	select GENERIC_CPU_DEVICES
 	select MODULES_USE_ELF_RELA
+	select GENERIC_KERNEL_THREAD
 
 config SYMBOL_PREFIX
 	string
diff --git a/arch/h8300/include/asm/processor.h b/arch/h8300/include/asm/processor.h
index 4c9f6f87b617..4b0ca49bb463 100644
--- a/arch/h8300/include/asm/processor.h
+++ b/arch/h8300/include/asm/processor.h
@@ -107,8 +107,6 @@ static inline void release_thread(struct task_struct *dead_task)
 {
 }
 
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
 /*
  * Free current thread data structures etc..
  */
diff --git a/arch/h8300/include/asm/ptrace.h b/arch/h8300/include/asm/ptrace.h
index d09c440bdba7..00502a61bf0a 100644
--- a/arch/h8300/include/asm/ptrace.h
+++ b/arch/h8300/include/asm/ptrace.h
@@ -60,6 +60,8 @@ struct pt_regs {
 #define user_mode(regs) (!((regs)->ccr & PS_S))
 #define instruction_pointer(regs) ((regs)->pc)
 #define profile_pc(regs) instruction_pointer(regs)
+#define current_pt_regs() ((struct pt_regs *) \
+	(THREAD_SIZE + (unsigned long)current_thread_info()) - 1)
 #endif /* __KERNEL__ */
 #endif /* __ASSEMBLY__ */
 #endif /* _H8300_PTRACE_H */
diff --git a/arch/h8300/kernel/entry.S b/arch/h8300/kernel/entry.S
index ca7431690300..2cdb49a56099 100644
--- a/arch/h8300/kernel/entry.S
+++ b/arch/h8300/kernel/entry.S
@@ -158,6 +158,7 @@ INTERRUPTS = 128
 .globl SYMBOL_NAME(system_call)
 .globl SYMBOL_NAME(ret_from_exception)
 .globl SYMBOL_NAME(ret_from_fork)
+.globl SYMBOL_NAME(ret_from_kernel_thread)
 .globl SYMBOL_NAME(ret_from_interrupt)
 .globl SYMBOL_NAME(interrupt_redirect_table)
 .globl SYMBOL_NAME(sw_ksp),SYMBOL_NAME(sw_usp)
@@ -330,6 +331,15 @@ SYMBOL_NAME_LABEL(ret_from_fork)
 	jsr	@SYMBOL_NAME(schedule_tail)
 	jmp	@SYMBOL_NAME(ret_from_exception)
 
+SYMBOL_NAME_LABEL(ret_from_kernel_thread)
+	mov.l	er2,er0
+	jsr	@SYMBOL_NAME(schedule_tail)
+	mov.l	@(LER4:16,sp),er0
+	mov.l	@(LER5:16,sp),er1
+	jsr	@er1
+	sub.l	@er0,@er0
+	jsr	@SYMBOL_NAME(sys_exit)
+
 SYMBOL_NAME_LABEL(resume)
 	/*
 	 * Beware - when entering resume, offset of tss is in d1,
diff --git a/arch/h8300/kernel/h8300_ksyms.c b/arch/h8300/kernel/h8300_ksyms.c
index 6866bd9c7fb4..53d7c0e4bd83 100644
--- a/arch/h8300/kernel/h8300_ksyms.c
+++ b/arch/h8300/kernel/h8300_ksyms.c
@@ -33,7 +33,6 @@ EXPORT_SYMBOL(strncmp);
 
 EXPORT_SYMBOL(ip_fast_csum);
 
-EXPORT_SYMBOL(kernel_thread);
 EXPORT_SYMBOL(enable_irq);
 EXPORT_SYMBOL(disable_irq);
 
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
index e8dc1393a13a..e3dfea71c15f 100644
--- a/arch/h8300/kernel/process.c
+++ b/arch/h8300/kernel/process.c
@@ -47,6 +47,7 @@ void (*pm_power_off)(void) = NULL;
 EXPORT_SYMBOL(pm_power_off);
 
 asmlinkage void ret_from_fork(void);
+asmlinkage void ret_from_kernel_thread(void);
 
 /*
  * The idle loop on an H8/300..
@@ -122,39 +123,6 @@ void show_regs(struct pt_regs * regs)
 		printk("\n");
 }
 
-/*
- * Create a kernel thread
- */
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
-	long retval;
-	long clone_arg;
-	mm_segment_t fs;
-
-	fs = get_fs();
-	set_fs (KERNEL_DS);
-	clone_arg = flags | CLONE_VM;
-	__asm__("mov.l sp,er3\n\t"
-		"sub.l er2,er2\n\t"
-		"mov.l %2,er1\n\t"
-		"mov.l %1,er0\n\t"
-		"trapa #0\n\t"
-		"cmp.l sp,er3\n\t"
-		"beq 1f\n\t"
-		"mov.l %4,er0\n\t"
-		"mov.l %3,er1\n\t"
-		"jsr @er1\n\t"
-		"mov.l %5,er0\n\t"
-		"trapa #0\n"
-		"1:\n\t"
-		"mov.l er0,%0"
-		:"=r"(retval)
-		:"i"(__NR_clone),"g"(clone_arg),"g"(fn),"g"(arg),"i"(__NR_exit)
-		:"er0","er1","er2","er3");
-	set_fs (fs);
-	return retval;
-}
-
 void flush_thread(void)
 {
 }
@@ -198,6 +166,13 @@ int copy_thread(unsigned long clone_flags,
 
 	childregs = (struct pt_regs *) (THREAD_SIZE + task_stack_page(p)) - 1;
 
+	if (unlikely(p->flags & PF_KTHREAD)) {
+		memset(childregs, 0, sizeof(struct pt_regs));
+		childregs->retpc = (unsigned long) ret_from_kernel_thread;
+		childregs->er4 = topstk; /* arg */
+		childregs->er5 = usp; /* fn */
+		p->thread.ksp = (unsigned long)childregs;
+	}
 	*childregs = *regs;
 	childregs->retpc = (unsigned long) ret_from_fork;
 	childregs->er0 = 0;
-- 
cgit v1.2.3


From 5fae1b664595adc621fb9294b7d19145918073de Mon Sep 17 00:00:00 2001
From: Al Viro <viro@zeniv.linux.org.uk>
Date: Wed, 10 Oct 2012 13:29:28 -0400
Subject: h8300: generic kernel_execve()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 arch/h8300/Kconfig            |  1 +
 arch/h8300/kernel/entry.S     |  3 +--
 arch/h8300/kernel/sys_h8300.c | 26 --------------------------
 3 files changed, 2 insertions(+), 28 deletions(-)

(limited to 'arch/h8300')

diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index 4cef8a91c2a0..04bef4d25b4a 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -9,6 +9,7 @@ config H8300
 	select GENERIC_CPU_DEVICES
 	select MODULES_USE_ELF_RELA
 	select GENERIC_KERNEL_THREAD
+	select GENERIC_KERNEL_EXECVE
 
 config SYMBOL_PREFIX
 	string
diff --git a/arch/h8300/kernel/entry.S b/arch/h8300/kernel/entry.S
index 2cdb49a56099..617a6878787f 100644
--- a/arch/h8300/kernel/entry.S
+++ b/arch/h8300/kernel/entry.S
@@ -337,8 +337,7 @@ SYMBOL_NAME_LABEL(ret_from_kernel_thread)
 	mov.l	@(LER4:16,sp),er0
 	mov.l	@(LER5:16,sp),er1
 	jsr	@er1
-	sub.l	@er0,@er0
-	jsr	@SYMBOL_NAME(sys_exit)
+	jmp	@SYMBOL_NAME(ret_from_exception)
 
 SYMBOL_NAME_LABEL(resume)
 	/*
diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c
index 4bdc7311784e..bf350cb7f597 100644
--- a/arch/h8300/kernel/sys_h8300.c
+++ b/arch/h8300/kernel/sys_h8300.c
@@ -46,29 +46,3 @@ asmlinkage void syscall_print(void *dummy,...)
                ((regs->pc)&0xffffff)-2,regs->orig_er0,regs->er1,regs->er2,regs->er3,regs->er0);
 }
 #endif
-
-/*
- * Do a system call from kernel instead of calling sys_execve so we
- * end up with proper pt_regs.
- */
-asmlinkage
-int kernel_execve(const char *filename,
-		  const char *const argv[],
-		  const char *const envp[])
-{
-	register long res __asm__("er0");
-	register const char *const *_c __asm__("er3") = envp;
-	register const char *const *_b __asm__("er2") = argv;
-	register const char * _a __asm__("er1") = filename;
-	__asm__ __volatile__ ("mov.l %1,er0\n\t"
-			"trapa	#0\n\t"
-			: "=r" (res)
-			: "g" (__NR_execve),
-			  "g" (_a),
-			  "g" (_b),
-			  "g" (_c)
-			: "cc", "memory");
-	return res;
-}
-
-
-- 
cgit v1.2.3


From 71915d21e59c153c1202e3198916817c2d18da32 Mon Sep 17 00:00:00 2001
From: Al Viro <viro@zeniv.linux.org.uk>
Date: Wed, 10 Oct 2012 13:31:13 -0400
Subject: h8300: generic sys_execve()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 arch/h8300/include/asm/unistd.h |  1 +
 arch/h8300/kernel/process.c     | 21 ---------------------
 2 files changed, 1 insertion(+), 21 deletions(-)

(limited to 'arch/h8300')

diff --git a/arch/h8300/include/asm/unistd.h b/arch/h8300/include/asm/unistd.h
index 5cd882801d79..07afcfaec995 100644
--- a/arch/h8300/include/asm/unistd.h
+++ b/arch/h8300/include/asm/unistd.h
@@ -356,6 +356,7 @@
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_SYS_EXECVE
 
 /*
  * "Conditional" syscalls
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
index e3dfea71c15f..2a45718cc5e8 100644
--- a/arch/h8300/kernel/process.c
+++ b/arch/h8300/kernel/process.c
@@ -183,27 +183,6 @@ int copy_thread(unsigned long clone_flags,
 	return 0;
 }
 
-/*
- * sys_execve() executes a new program.
- */
-asmlinkage int sys_execve(const char *name,
-			  const char *const *argv,
-			  const char *const *envp,
-			  int dummy, ...)
-{
-	int error;
-	struct filename *filename;
-	struct pt_regs *regs = (struct pt_regs *) ((unsigned char *)&dummy-4);
-
-	filename = getname(name);
-	error = PTR_ERR(filename);
-	if (IS_ERR(filename))
-		return error;
-	error = do_execve(filename->name, argv, envp, regs);
-	putname(filename);
-	return error;
-}
-
 unsigned long thread_saved_pc(struct task_struct *tsk)
 {
 	return ((struct pt_regs *)tsk->thread.esp0)->pc;
-- 
cgit v1.2.3


From 3416e8098aa4c0eea1b2e5c4efc68cf61a848864 Mon Sep 17 00:00:00 2001
From: Al Viro <viro@zeniv.linux.org.uk>
Date: Sat, 27 Oct 2012 00:07:24 -0400
Subject: h8300: switch to generic fork/vfork/clone

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 arch/h8300/include/asm/unistd.h |  3 +++
 arch/h8300/kernel/process.c     | 38 +++-----------------------------------
 arch/h8300/kernel/syscalls.S    |  9 ---------
 3 files changed, 6 insertions(+), 44 deletions(-)

(limited to 'arch/h8300')

diff --git a/arch/h8300/include/asm/unistd.h b/arch/h8300/include/asm/unistd.h
index 07afcfaec995..c2c2f5c7d6bf 100644
--- a/arch/h8300/include/asm/unistd.h
+++ b/arch/h8300/include/asm/unistd.h
@@ -357,6 +357,9 @@
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
 #define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_SYS_FORK
+#define __ARCH_WANT_SYS_VFORK
+#define __ARCH_WANT_SYS_CLONE
 
 /*
  * "Conditional" syscalls
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
index 2a45718cc5e8..b0fb4054aee5 100644
--- a/arch/h8300/kernel/process.c
+++ b/arch/h8300/kernel/process.c
@@ -127,40 +127,9 @@ void flush_thread(void)
 {
 }
 
-/*
- * "h8300_fork()".. By the time we get here, the
- * non-volatile registers have also been saved on the
- * stack. We do some ugly pointer stuff here.. (see
- * also copy_thread)
- */
-
-asmlinkage int h8300_fork(struct pt_regs *regs)
-{
-	return -EINVAL;
-}
-
-asmlinkage int h8300_vfork(struct pt_regs *regs)
-{
-	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL, NULL);
-}
-
-asmlinkage int h8300_clone(struct pt_regs *regs)
-{
-	unsigned long clone_flags;
-	unsigned long newsp;
-
-	/* syscall2 puts clone_flags in er1 and usp in er2 */
-	clone_flags = regs->er1;
-	newsp = regs->er2;
-	if (!newsp)
-		newsp  = rdusp();
-	return do_fork(clone_flags, newsp, regs, 0, NULL, NULL);
-
-}
-
 int copy_thread(unsigned long clone_flags,
                 unsigned long usp, unsigned long topstk,
-		 struct task_struct * p, struct pt_regs * regs)
+		 struct task_struct * p, struct pt_regs *unused)
 {
 	struct pt_regs * childregs;
 
@@ -173,11 +142,10 @@ int copy_thread(unsigned long clone_flags,
 		childregs->er5 = usp; /* fn */
 		p->thread.ksp = (unsigned long)childregs;
 	}
-	*childregs = *regs;
+	*childregs = *current_pt_regs();
 	childregs->retpc = (unsigned long) ret_from_fork;
 	childregs->er0 = 0;
-
-	p->thread.usp = usp;
+	p->thread.usp = usp ?: rdusp();
 	p->thread.ksp = (unsigned long)childregs;
 
 	return 0;
diff --git a/arch/h8300/kernel/syscalls.S b/arch/h8300/kernel/syscalls.S
index 9d77e715a2ed..b74dd0ade58d 100644
--- a/arch/h8300/kernel/syscalls.S
+++ b/arch/h8300/kernel/syscalls.S
@@ -340,21 +340,12 @@ SYMBOL_NAME_LABEL(sys_call_table)
 	bra	SYMBOL_NAME(syscall_trampoline):8
 	.endm
 
-SYMBOL_NAME_LABEL(sys_clone)	
-	call_sp	h8300_clone
-	
 SYMBOL_NAME_LABEL(sys_sigreturn)
 	call_sp	do_sigreturn
 
 SYMBOL_NAME_LABEL(sys_rt_sigreturn)
 	call_sp	do_rt_sigreturn
 
-SYMBOL_NAME_LABEL(sys_fork)
-	call_sp	h8300_fork
-
-SYMBOL_NAME_LABEL(sys_vfork)
-	call_sp	h8300_vfork
-
 SYMBOL_NAME_LABEL(syscall_trampoline)
 	mov.l	sp,er0
 	jmp	@er6
-- 
cgit v1.2.3


From afa86fc426ff7e7f5477f15da9c405d08d5cf790 Mon Sep 17 00:00:00 2001
From: Al Viro <viro@zeniv.linux.org.uk>
Date: Mon, 22 Oct 2012 22:51:14 -0400
Subject: flagday: don't pass regs to copy_thread()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 arch/h8300/kernel/process.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'arch/h8300')

diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
index b0fb4054aee5..b609f63f1590 100644
--- a/arch/h8300/kernel/process.c
+++ b/arch/h8300/kernel/process.c
@@ -129,7 +129,7 @@ void flush_thread(void)
 
 int copy_thread(unsigned long clone_flags,
                 unsigned long usp, unsigned long topstk,
-		 struct task_struct * p, struct pt_regs *unused)
+		 struct task_struct * p)
 {
 	struct pt_regs * childregs;
 
-- 
cgit v1.2.3


From 4f4202fe5ae9a43e59303f20d700571f695d7b1b Mon Sep 17 00:00:00 2001
From: Al Viro <viro@zeniv.linux.org.uk>
Date: Mon, 5 Nov 2012 12:59:15 -0500
Subject: unify default ptrace_signal_deliver

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 arch/h8300/include/asm/signal.h | 2 --
 1 file changed, 2 deletions(-)

(limited to 'arch/h8300')

diff --git a/arch/h8300/include/asm/signal.h b/arch/h8300/include/asm/signal.h
index fd8b66e40dca..c43c0a7d2c2e 100644
--- a/arch/h8300/include/asm/signal.h
+++ b/arch/h8300/include/asm/signal.h
@@ -154,8 +154,6 @@ typedef struct sigaltstack {
 #include <asm/sigcontext.h>
 #undef __HAVE_ARCH_SIG_BITOPS
 
-#define ptrace_signal_deliver(regs, cookie) do { } while (0)
-
 #endif /* __KERNEL__ */
 
 #endif /* _H8300_SIGNAL_H */
-- 
cgit v1.2.3


From 22062a96300dabfef93368a28c34bdf35c9b8308 Mon Sep 17 00:00:00 2001
From: Al Viro <viro@zeniv.linux.org.uk>
Date: Mon, 5 Nov 2012 13:00:27 -0500
Subject: new helper: signal_pt_regs()

Always equal to task_pt_regs(current); defined only when we are in
signal delivery.  It may be different from current_pt_regs() - e.g.
architectures like m68k may have pt_regs location on exception
different from that on a syscall and signals (just as ptrace handling)
may happen on exceptions as well as on syscalls.

When they are equal, it's often better to have signal_pt_regs
defined (in asm/ptrace.h) as current_pt_regs - that tends to be
optimized better than default would be.  However, optimisation is
the only reason why we might want an arch-specific definition;
if current_pt_regs() and task_pt_regs(current) have different
values, the latter one is right.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 arch/h8300/include/asm/ptrace.h | 1 +
 1 file changed, 1 insertion(+)

(limited to 'arch/h8300')

diff --git a/arch/h8300/include/asm/ptrace.h b/arch/h8300/include/asm/ptrace.h
index 00502a61bf0a..7468589a128b 100644
--- a/arch/h8300/include/asm/ptrace.h
+++ b/arch/h8300/include/asm/ptrace.h
@@ -62,6 +62,7 @@ struct pt_regs {
 #define profile_pc(regs) instruction_pointer(regs)
 #define current_pt_regs() ((struct pt_regs *) \
 	(THREAD_SIZE + (unsigned long)current_thread_info()) - 1)
+#define signal_pt_regs() ((struct pt_regs *)current->thread.esp0)
 #endif /* __KERNEL__ */
 #endif /* __ASSEMBLY__ */
 #endif /* _H8300_PTRACE_H */
-- 
cgit v1.2.3