FRV: Fix the new-style kernel_thread() stuff

The kernel_thread() changes for FRV don't work, and FRV fails to boot,
starting with:

	commit 02ce496f152df87be081a64796498942c433a2fd
	Author: Al Viro <>
	Date:   Tue Sep 18 22:18:51 2012 -0400
	Subject: frv: split ret_from_fork, simplify kernel_thread() a lot

The problem is that the userspace registers are completely cleared when a
kernel thread is created and all subsequent user threads are then copied from
that.  Unfortunately, however, the TBR and PSR registers are restored from the
pt_regs and the values they should be set to are clobbered by the memset.

Instead, copy across the old user registers as normal, and then merely alter
GR8 and GR9 in it if we're going to execute a kernel thread.

Signed-off-by: David Howells <>
diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c
index e1e3aa1..7e33215 100644
--- a/arch/frv/kernel/process.c
+++ b/arch/frv/kernel/process.c
@@ -181,6 +181,9 @@
 	childregs = (struct pt_regs *)
 		(task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE);
+	/* set up the userspace frame (the only place that the USP is stored) */
+	*childregs = *__kernel_frame0_ptr;
 	p->set_child_tid = p->clear_child_tid = NULL;
 	p->thread.frame	 = childregs;
@@ -191,10 +194,8 @@
 	p->thread.frame0 = childregs;
 	if (unlikely(!regs)) {
-		memset(childregs, 0, sizeof(struct pt_regs));
 		childregs->gr9 = usp; /* function */
 		childregs->gr8 = arg;
-		childregs->psr = PSR_S;
 		p->thread.pc = (unsigned long) ret_from_kernel_thread;
 		return 0;