diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-09-22 18:10:15 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-10-01 00:53:11 -0400 |
commit | 49ed3398b75c98c087537a7d5a1a23f86a8c8746 (patch) | |
tree | 29d8f77210dcec7dac19fc7355ae8e07fd35a444 /arch/frv/kernel | |
parent | 019f96a345b6e23d4e0bc2c136ec5f7500b95834 (diff) |
frv: switch to generic kernel_thread()
Diffstat (limited to 'arch/frv/kernel')
-rw-r--r-- | arch/frv/kernel/process.c | 41 |
1 files changed, 19 insertions, 22 deletions
diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c index 7ff4dbef056..014f855362b 100644 --- a/arch/frv/kernel/process.c +++ b/arch/frv/kernel/process.c | |||
@@ -170,7 +170,7 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, | |||
170 | * set up the kernel stack and exception frames for a new process | 170 | * set up the kernel stack and exception frames for a new process |
171 | */ | 171 | */ |
172 | int copy_thread(unsigned long clone_flags, | 172 | int copy_thread(unsigned long clone_flags, |
173 | unsigned long usp, unsigned long topstk, | 173 | unsigned long usp, unsigned long arg, |
174 | struct task_struct *p, struct pt_regs *regs) | 174 | struct task_struct *p, struct pt_regs *regs) |
175 | { | 175 | { |
176 | struct pt_regs *childregs; | 176 | struct pt_regs *childregs; |
@@ -178,17 +178,6 @@ int copy_thread(unsigned long clone_flags, | |||
178 | childregs = (struct pt_regs *) | 178 | childregs = (struct pt_regs *) |
179 | (task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE); | 179 | (task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE); |
180 | 180 | ||
181 | /* set up the userspace frame (the only place that the USP is stored) */ | ||
182 | *childregs = *regs; | ||
183 | |||
184 | childregs->sp = usp; | ||
185 | childregs->next_frame = NULL; | ||
186 | |||
187 | if (unlikely(!user_mode(regs))) | ||
188 | p->thread.pc = (unsigned long) ret_from_kernel_thread; | ||
189 | else | ||
190 | p->thread.pc = (unsigned long) ret_from_fork; | ||
191 | |||
192 | p->set_child_tid = p->clear_child_tid = NULL; | 181 | p->set_child_tid = p->clear_child_tid = NULL; |
193 | 182 | ||
194 | p->thread.frame = childregs; | 183 | p->thread.frame = childregs; |
@@ -198,6 +187,24 @@ int copy_thread(unsigned long clone_flags, | |||
198 | p->thread.lr = 0; | 187 | p->thread.lr = 0; |
199 | p->thread.frame0 = childregs; | 188 | p->thread.frame0 = childregs; |
200 | 189 | ||
190 | if (unlikely(!regs)) { | ||
191 | memset(childregs, 0, sizeof(struct pt_regs)); | ||
192 | childregs->gr9 = usp; /* function */ | ||
193 | childregs->gr8 = arg; | ||
194 | chilregs->psr = PSR_S; | ||
195 | p->thread.pc = (unsigned long) ret_from_kernel_thread; | ||
196 | save_user_regs(p->thread.user); | ||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | /* set up the userspace frame (the only place that the USP is stored) */ | ||
201 | *childregs = *regs; | ||
202 | |||
203 | childregs->sp = usp; | ||
204 | childregs->next_frame = NULL; | ||
205 | |||
206 | p->thread.pc = (unsigned long) ret_from_fork; | ||
207 | |||
201 | /* the new TLS pointer is passed in as arg #5 to sys_clone() */ | 208 | /* the new TLS pointer is passed in as arg #5 to sys_clone() */ |
202 | if (clone_flags & CLONE_SETTLS) | 209 | if (clone_flags & CLONE_SETTLS) |
203 | childregs->gr29 = childregs->gr12; | 210 | childregs->gr29 = childregs->gr12; |
@@ -320,13 +327,3 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs) | |||
320 | sizeof(current->thread.user->f)); | 327 | sizeof(current->thread.user->f)); |
321 | return 1; | 328 | return 1; |
322 | } | 329 | } |
323 | |||
324 | int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | ||
325 | { | ||
326 | struct pt_regs regs = { | ||
327 | .gr8 = (unsigned long)arg; | ||
328 | .gr9 = (unsigned long)fn; | ||
329 | .psr = PSR_S; | ||
330 | }; | ||
331 | return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); | ||
332 | } | ||