diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-10-03 23:28:08 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-10-14 19:36:30 -0400 |
commit | a44e060fc523c379341e35a981c09c3953cf4ba4 (patch) | |
tree | f32db182b2f746acd95cd7dbb8794352a8f98eb4 /arch/parisc/kernel | |
parent | ddffeb8c4d0331609ef2581d84de4d763607bd37 (diff) |
parisc: switch to generic kernel_thread()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/parisc/kernel')
-rw-r--r-- | arch/parisc/kernel/entry.S | 53 | ||||
-rw-r--r-- | arch/parisc/kernel/process.c | 53 |
2 files changed, 17 insertions, 89 deletions
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 18670a078849..18d05e7373b5 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S | |||
@@ -708,59 +708,9 @@ ENTRY(end_fault_vector) | |||
708 | .import do_cpu_irq_mask,code | 708 | .import do_cpu_irq_mask,code |
709 | 709 | ||
710 | /* | 710 | /* |
711 | * r26 = function to be called | ||
712 | * r25 = argument to pass in | ||
713 | * r24 = flags for do_fork() | ||
714 | * | ||
715 | * Kernel threads don't ever return, so they don't need | ||
716 | * a true register context. We just save away the arguments | ||
717 | * for copy_thread/ret_ to properly set up the child. | ||
718 | */ | ||
719 | |||
720 | #define CLONE_VM 0x100 /* Must agree with <linux/sched.h> */ | ||
721 | #define CLONE_UNTRACED 0x00800000 | ||
722 | |||
723 | .import do_fork | ||
724 | ENTRY(__kernel_thread) | ||
725 | STREG %r2, -RP_OFFSET(%r30) | ||
726 | |||
727 | copy %r30, %r1 | ||
728 | ldo PT_SZ_ALGN(%r30),%r30 | ||
729 | #ifdef CONFIG_64BIT | ||
730 | /* Yo, function pointers in wide mode are little structs... -PB */ | ||
731 | ldd 24(%r26), %r2 | ||
732 | STREG %r2, PT_GR27(%r1) /* Store childs %dp */ | ||
733 | ldd 16(%r26), %r26 | ||
734 | |||
735 | STREG %r22, PT_GR22(%r1) /* save r22 (arg5) */ | ||
736 | copy %r0, %r22 /* user_tid */ | ||
737 | #endif | ||
738 | STREG %r26, PT_GR26(%r1) /* Store function & argument for child */ | ||
739 | STREG %r25, PT_GR25(%r1) | ||
740 | ldil L%CLONE_UNTRACED, %r26 | ||
741 | ldo CLONE_VM(%r26), %r26 /* Force CLONE_VM since only init_mm */ | ||
742 | or %r26, %r24, %r26 /* will have kernel mappings. */ | ||
743 | ldi 1, %r25 /* stack_start, signals kernel thread */ | ||
744 | stw %r0, -52(%r30) /* user_tid */ | ||
745 | #ifdef CONFIG_64BIT | ||
746 | ldo -16(%r30),%r29 /* Reference param save area */ | ||
747 | #endif | ||
748 | BL do_fork, %r2 | ||
749 | copy %r1, %r24 /* pt_regs */ | ||
750 | |||
751 | /* Parent Returns here */ | ||
752 | |||
753 | LDREG -PT_SZ_ALGN-RP_OFFSET(%r30), %r2 | ||
754 | ldo -PT_SZ_ALGN(%r30), %r30 | ||
755 | bv %r0(%r2) | ||
756 | nop | ||
757 | ENDPROC(__kernel_thread) | ||
758 | |||
759 | /* | ||
760 | * Child Returns here | 711 | * Child Returns here |
761 | * | 712 | * |
762 | * copy_thread moved args from temp save area set up above | 713 | * copy_thread moved args into task save area. |
763 | * into task save area. | ||
764 | */ | 714 | */ |
765 | 715 | ||
766 | ENTRY(ret_from_kernel_thread) | 716 | ENTRY(ret_from_kernel_thread) |
@@ -773,7 +723,6 @@ ENTRY(ret_from_kernel_thread) | |||
773 | LDREG TASK_PT_GR25(%r1), %r26 | 723 | LDREG TASK_PT_GR25(%r1), %r26 |
774 | #ifdef CONFIG_64BIT | 724 | #ifdef CONFIG_64BIT |
775 | LDREG TASK_PT_GR27(%r1), %r27 | 725 | LDREG TASK_PT_GR27(%r1), %r27 |
776 | LDREG TASK_PT_GR22(%r1), %r22 | ||
777 | #endif | 726 | #endif |
778 | LDREG TASK_PT_GR26(%r1), %r1 | 727 | LDREG TASK_PT_GR26(%r1), %r1 |
779 | ble 0(%sr7, %r1) | 728 | ble 0(%sr7, %r1) |
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index cbc37216bf90..b7b4126774e0 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; | |||
165 | EXPORT_SYMBOL(pm_power_off); | 165 | EXPORT_SYMBOL(pm_power_off); |
166 | 166 | ||
167 | /* | 167 | /* |
168 | * Create a kernel thread | ||
169 | */ | ||
170 | |||
171 | extern pid_t __kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); | ||
172 | pid_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 | } | ||
182 | EXPORT_SYMBOL(kernel_thread); | ||
183 | |||
184 | /* | ||
185 | * Free current thread data structures etc.. | 168 | * Free current thread data structures etc.. |
186 | */ | 169 | */ |
187 | void exit_thread(void) | 170 | void exit_thread(void) |
@@ -256,8 +239,8 @@ sys_vfork(struct pt_regs *regs) | |||
256 | 239 | ||
257 | int | 240 | int |
258 | copy_thread(unsigned long clone_flags, unsigned long usp, | 241 | copy_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)); |