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 02ce496f15
Author: Al Viro <viro@zeniv.linux.org.uk>
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 <dhowells@redhat.com>
This commit is contained in:
parent
1ee6f5669a
commit
e7aa51b2e5
|
@ -181,6 +181,9 @@ int copy_thread(unsigned long clone_flags,
|
|||
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 @@ int copy_thread(unsigned long clone_flags,
|
|||
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;
|
||||
save_user_regs(p->thread.user);
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue
Block a user