aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc/kernel/process.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-10-03 23:28:08 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-10-14 19:36:30 -0400
commita44e060fc523c379341e35a981c09c3953cf4ba4 (patch)
treef32db182b2f746acd95cd7dbb8794352a8f98eb4 /arch/parisc/kernel/process.c
parentddffeb8c4d0331609ef2581d84de4d763607bd37 (diff)
parisc: switch to generic kernel_thread()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/parisc/kernel/process.c')
-rw-r--r--arch/parisc/kernel/process.c53
1 files changed, 16 insertions, 37 deletions
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index cbc37216bf9..b7b4126774e 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -165,23 +165,6 @@ void (*pm_power_off)(void) = machine_power_off;
165EXPORT_SYMBOL(pm_power_off); 165EXPORT_SYMBOL(pm_power_off);
166 166
167/* 167/*
168 * Create a kernel thread
169 */
170
171extern pid_t __kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
172pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
173{
174
175 /*
176 * FIXME: Once we are sure we don't need any debug here,
177 * kernel_thread can become a #define.
178 */
179
180 return __kernel_thread(fn, arg, flags);
181}
182EXPORT_SYMBOL(kernel_thread);
183
184/*
185 * Free current thread data structures etc.. 168 * Free current thread data structures etc..
186 */ 169 */
187void exit_thread(void) 170void exit_thread(void)
@@ -256,8 +239,8 @@ sys_vfork(struct pt_regs *regs)
256 239
257int 240int
258copy_thread(unsigned long clone_flags, unsigned long usp, 241copy_thread(unsigned long clone_flags, unsigned long usp,
259 unsigned long unused, /* in ia64 this is "user_stack_size" */ 242 unsigned long arg,
260 struct task_struct * p, struct pt_regs * pregs) 243 struct task_struct *p, struct pt_regs *pregs)
261{ 244{
262 struct pt_regs * cregs = &(p->thread.regs); 245 struct pt_regs * cregs = &(p->thread.regs);
263 void *stack = task_stack_page(p); 246 void *stack = task_stack_page(p);
@@ -271,21 +254,8 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
271 extern void * const hpux_child_return; 254 extern void * const hpux_child_return;
272#endif 255#endif
273 256
274 *cregs = *pregs; 257 if (unlikely((p->flags & PF_KTHREAD) && usp != 0)) {
275 258 memset(cregs, 0, sizeof(struct pt_regs));
276 /* Set the return value for the child. Note that this is not
277 actually restored by the syscall exit path, but we put it
278 here for consistency in case of signals. */
279 cregs->gr[28] = 0; /* child */
280
281 /*
282 * We need to differentiate between a user fork and a
283 * kernel fork. We can't use user_mode, because the
284 * the syscall path doesn't save iaoq. Right now
285 * We rely on the fact that kernel_thread passes
286 * in zero for usp.
287 */
288 if (usp == 1) {
289 /* kernel thread */ 259 /* kernel thread */
290 cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN; 260 cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN;
291 /* Must exit via ret_from_kernel_thread in order 261 /* Must exit via ret_from_kernel_thread in order
@@ -297,10 +267,12 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
297 * ret_from_kernel_thread. 267 * ret_from_kernel_thread.
298 */ 268 */
299#ifdef CONFIG_64BIT 269#ifdef CONFIG_64BIT
300 cregs->gr[27] = pregs->gr[27]; 270 cregs->gr[27] = ((unsigned long *)usp)[3];
271 cregs->gr[26] = ((unsigned long *)usp)[2];
272#else
273 cregs->gr[26] = usp;
301#endif 274#endif
302 cregs->gr[26] = pregs->gr[26]; 275 cregs->gr[25] = arg;
303 cregs->gr[25] = pregs->gr[25];
304 } else { 276 } else {
305 /* user thread */ 277 /* user thread */
306 /* 278 /*
@@ -308,6 +280,13 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
308 * for setting gr[21]. 280 * for setting gr[21].
309 */ 281 */
310 282
283 *cregs = *pregs;
284
285 /* Set the return value for the child. Note that this is not
286 actually restored by the syscall exit path, but we put it
287 here for consistency in case of signals. */
288 cregs->gr[28] = 0; /* child */
289
311 /* Use same stack depth as parent */ 290 /* Use same stack depth as parent */
312 cregs->ksp = (unsigned long)stack 291 cregs->ksp = (unsigned long)stack
313 + (pregs->gr[21] & (THREAD_SIZE - 1)); 292 + (pregs->gr[21] & (THREAD_SIZE - 1));