From a44e060fc523c379341e35a981c09c3953cf4ba4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 3 Oct 2012 23:28:08 -0400 Subject: parisc: switch to generic kernel_thread() Signed-off-by: Al Viro --- arch/parisc/kernel/entry.S | 53 +------------------------------------------- arch/parisc/kernel/process.c | 53 +++++++++++++------------------------------- 2 files changed, 17 insertions(+), 89 deletions(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 18670a0..18d05e7 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -708,59 +708,9 @@ ENTRY(end_fault_vector) .import do_cpu_irq_mask,code /* - * r26 = function to be called - * r25 = argument to pass in - * r24 = flags for do_fork() - * - * Kernel threads don't ever return, so they don't need - * a true register context. We just save away the arguments - * for copy_thread/ret_ to properly set up the child. - */ - -#define CLONE_VM 0x100 /* Must agree with */ -#define CLONE_UNTRACED 0x00800000 - - .import do_fork -ENTRY(__kernel_thread) - STREG %r2, -RP_OFFSET(%r30) - - copy %r30, %r1 - ldo PT_SZ_ALGN(%r30),%r30 -#ifdef CONFIG_64BIT - /* Yo, function pointers in wide mode are little structs... -PB */ - ldd 24(%r26), %r2 - STREG %r2, PT_GR27(%r1) /* Store childs %dp */ - ldd 16(%r26), %r26 - - STREG %r22, PT_GR22(%r1) /* save r22 (arg5) */ - copy %r0, %r22 /* user_tid */ -#endif - STREG %r26, PT_GR26(%r1) /* Store function & argument for child */ - STREG %r25, PT_GR25(%r1) - ldil L%CLONE_UNTRACED, %r26 - ldo CLONE_VM(%r26), %r26 /* Force CLONE_VM since only init_mm */ - or %r26, %r24, %r26 /* will have kernel mappings. */ - ldi 1, %r25 /* stack_start, signals kernel thread */ - stw %r0, -52(%r30) /* user_tid */ -#ifdef CONFIG_64BIT - ldo -16(%r30),%r29 /* Reference param save area */ -#endif - BL do_fork, %r2 - copy %r1, %r24 /* pt_regs */ - - /* Parent Returns here */ - - LDREG -PT_SZ_ALGN-RP_OFFSET(%r30), %r2 - ldo -PT_SZ_ALGN(%r30), %r30 - bv %r0(%r2) - nop -ENDPROC(__kernel_thread) - - /* * Child Returns here * - * copy_thread moved args from temp save area set up above - * into task save area. + * copy_thread moved args into task save area. */ ENTRY(ret_from_kernel_thread) @@ -773,7 +723,6 @@ ENTRY(ret_from_kernel_thread) LDREG TASK_PT_GR25(%r1), %r26 #ifdef CONFIG_64BIT LDREG TASK_PT_GR27(%r1), %r27 - LDREG TASK_PT_GR22(%r1), %r22 #endif LDREG TASK_PT_GR26(%r1), %r1 ble 0(%sr7, %r1) diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index cbc3721..b7b4126 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; EXPORT_SYMBOL(pm_power_off); /* - * Create a kernel thread - */ - -extern pid_t __kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); -pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) -{ - - /* - * FIXME: Once we are sure we don't need any debug here, - * kernel_thread can become a #define. - */ - - return __kernel_thread(fn, arg, flags); -} -EXPORT_SYMBOL(kernel_thread); - -/* * Free current thread data structures etc.. */ void exit_thread(void) @@ -256,8 +239,8 @@ sys_vfork(struct pt_regs *regs) int copy_thread(unsigned long clone_flags, unsigned long usp, - unsigned long unused, /* in ia64 this is "user_stack_size" */ - struct task_struct * p, struct pt_regs * pregs) + unsigned long arg, + struct task_struct *p, struct pt_regs *pregs) { struct pt_regs * cregs = &(p->thread.regs); void *stack = task_stack_page(p); @@ -271,21 +254,8 @@ copy_thread(unsigned long clone_flags, unsigned long usp, extern void * const hpux_child_return; #endif - *cregs = *pregs; - - /* Set the return value for the child. Note that this is not - actually restored by the syscall exit path, but we put it - here for consistency in case of signals. */ - cregs->gr[28] = 0; /* child */ - - /* - * We need to differentiate between a user fork and a - * kernel fork. We can't use user_mode, because the - * the syscall path doesn't save iaoq. Right now - * We rely on the fact that kernel_thread passes - * in zero for usp. - */ - if (usp == 1) { + if (unlikely((p->flags & PF_KTHREAD) && usp != 0)) { + memset(cregs, 0, sizeof(struct pt_regs)); /* kernel thread */ cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN; /* Must exit via ret_from_kernel_thread in order @@ -297,10 +267,12 @@ copy_thread(unsigned long clone_flags, unsigned long usp, * ret_from_kernel_thread. */ #ifdef CONFIG_64BIT - cregs->gr[27] = pregs->gr[27]; + cregs->gr[27] = ((unsigned long *)usp)[3]; + cregs->gr[26] = ((unsigned long *)usp)[2]; +#else + cregs->gr[26] = usp; #endif - cregs->gr[26] = pregs->gr[26]; - cregs->gr[25] = pregs->gr[25]; + cregs->gr[25] = arg; } else { /* user thread */ /* @@ -308,6 +280,13 @@ copy_thread(unsigned long clone_flags, unsigned long usp, * for setting gr[21]. */ + *cregs = *pregs; + + /* Set the return value for the child. Note that this is not + actually restored by the syscall exit path, but we put it + here for consistency in case of signals. */ + cregs->gr[28] = 0; /* child */ + /* Use same stack depth as parent */ cregs->ksp = (unsigned long)stack + (pregs->gr[21] & (THREAD_SIZE - 1)); -- cgit v1.1 From 4e5ed85ab5f1c9973588d7226c2894016059d9f6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 3 Oct 2012 23:44:44 -0400 Subject: parisc: switch to generic kernel_execve() Signed-off-by: Al Viro --- arch/parisc/kernel/entry.S | 28 ++++++---------------------- arch/parisc/kernel/process.c | 10 ---------- 2 files changed, 6 insertions(+), 32 deletions(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 18d05e7..a26917d 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -741,28 +741,12 @@ ENTRY(ret_from_kernel_thread) ldi 0, %r26 ENDPROC(ret_from_kernel_thread) - .import sys_execve, code -ENTRY(__execve) - copy %r2, %r15 - copy %r30, %r16 - ldo PT_SZ_ALGN(%r30), %r30 - STREG %r26, PT_GR26(%r16) - STREG %r25, PT_GR25(%r16) - STREG %r24, PT_GR24(%r16) -#ifdef CONFIG_64BIT - ldo -16(%r30),%r29 /* Reference param save area */ -#endif - BL sys_execve, %r2 - copy %r16, %r26 - - cmpib,=,n 0,%r28,intr_return /* forward */ - - /* yes, this will trap and die. */ - copy %r15, %r2 - copy %r16, %r30 - bv %r0(%r2) - nop -ENDPROC(__execve) +ENTRY(ret_from_kernel_execve) + mfctl %cr30, %r1 + ldo THREAD_SZ_ALGN(%r1), %r30 + b intr_return /* forward */ + copy %r26,%r16 /* pt_regs into r16 */ +ENDPROC(ret_from_kernel_execve) /* diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index b7b4126..f3f6408 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -337,16 +337,6 @@ out: return error; } -extern int __execve(const char *filename, - const char *const argv[], - const char *const envp[], struct task_struct *task); -int kernel_execve(const char *filename, - const char *const argv[], - const char *const envp[]) -{ - return __execve(filename, argv, envp, current); -} - unsigned long get_wchan(struct task_struct *p) { -- cgit v1.1 From 7f1f311ac7b7b9c779fd207a20369f7fa3a61ba6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 4 Oct 2012 08:34:57 -0400 Subject: parisc: switch to generic sys_execve() Signed-off-by: Al Viro --- arch/parisc/kernel/entry.S | 46 -------------------------------------- arch/parisc/kernel/process.c | 23 ------------------- arch/parisc/kernel/sys_parisc32.c | 22 ------------------ arch/parisc/kernel/syscall_table.S | 2 +- 4 files changed, 1 insertion(+), 92 deletions(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index a26917d..7d22e97 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -1804,52 +1804,6 @@ ENTRY(sys_vfork_wrapper) ENDPROC(sys_vfork_wrapper) - .macro execve_wrapper execve - LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 - ldo TASK_REGS(%r1),%r1 /* get pt regs */ - - /* - * Do we need to save/restore r3-r18 here? - * I don't think so. why would new thread need old - * threads registers? - */ - - /* %arg0 - %arg3 are already saved for us. */ - - STREG %r2,-RP_OFFSET(%r30) - ldo FRAME_SIZE(%r30),%r30 -#ifdef CONFIG_64BIT - ldo -16(%r30),%r29 /* Reference param save area */ -#endif - BL \execve,%r2 - copy %r1,%arg0 - - ldo -FRAME_SIZE(%r30),%r30 - LDREG -RP_OFFSET(%r30),%r2 - - /* If exec succeeded we need to load the args */ - - ldo -1024(%r0),%r1 - cmpb,>>= %r28,%r1,error_\execve - copy %r2,%r19 - -error_\execve: - bv %r0(%r19) - nop - .endm - - .import sys_execve -ENTRY(sys_execve_wrapper) - execve_wrapper sys_execve -ENDPROC(sys_execve_wrapper) - -#ifdef CONFIG_64BIT - .import sys32_execve -ENTRY(sys32_execve_wrapper) - execve_wrapper sys32_execve -ENDPROC(sys32_execve_wrapper) -#endif - ENTRY(sys_rt_sigreturn_wrapper) LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26 ldo TASK_REGS(%r26),%r26 /* get pt regs */ diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index f3f6408..44e8534 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -314,29 +314,6 @@ unsigned long thread_saved_pc(struct task_struct *t) return t->thread.regs.kpc; } -/* - * sys_execve() executes a new program. - */ - -asmlinkage int sys_execve(struct pt_regs *regs) -{ - int error; - struct filename *filename; - - filename = getname((const char __user *) regs->gr[26]); - error = PTR_ERR(filename); - if (IS_ERR(filename)) - goto out; - error = do_execve(filename->name, - (const char __user *const __user *) regs->gr[25], - (const char __user *const __user *) regs->gr[24], - regs); - putname(filename); -out: - - return error; -} - unsigned long get_wchan(struct task_struct *p) { diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c index bf5b93a..9cfdaa1 100644 --- a/arch/parisc/kernel/sys_parisc32.c +++ b/arch/parisc/kernel/sys_parisc32.c @@ -53,28 +53,6 @@ #define DBG(x) #endif -/* - * sys32_execve() executes a new program. - */ - -asmlinkage int sys32_execve(struct pt_regs *regs) -{ - int error; - struct filename *filename; - - DBG(("sys32_execve(%p) r26 = 0x%lx\n", regs, regs->gr[26])); - filename = getname((const char __user *) regs->gr[26]); - error = PTR_ERR(filename); - if (IS_ERR(filename)) - goto out; - error = compat_do_execve(filename->name, compat_ptr(regs->gr[25]), - compat_ptr(regs->gr[24]), regs); - putname(filename); -out: - - return error; -} - asmlinkage long sys32_unimplemented(int r26, int r25, int r24, int r23, int r22, int r21, int r20) { diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 3735abd..cb2da96 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -66,7 +66,7 @@ ENTRY_SAME(creat) ENTRY_SAME(link) ENTRY_SAME(unlink) /* 10 */ - ENTRY_DIFF(execve_wrapper) + ENTRY_COMP(execve) ENTRY_SAME(chdir) /* See comments in kernel/time.c!!! Maybe we don't need this? */ ENTRY_COMP(time) -- cgit v1.1 From ff0ab8af9c3f36e7b6f716c3b9e8811a4202eec6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 5 Oct 2012 18:55:57 -0400 Subject: parisc: optimizations in copy_thread() and friends * in user thread case the registers had been copied as part of task_struct already; no need to do it in copy_thread(). * no need to store kernel stack pointer into regs->r21; we know its offset anyway. * no need to clobber r3 in sys_fork_wrapper and friends - r28 will do just as well and *it* will be overwritten anyway. * no need to mess with storing the return address for child - it should just use syscall_exit. * no need to bother with separate stack frame for sys_clone() - just branch there and be done with that. * no need to bother with wrapper_exit - we need it only on the child_return, so let's just do it there. * use the same ksp for kernel threads and userland ones, while we are at it, and let ret_from_kernel_execve() go through the normal syscall_exit. More straightforward is better here... [fixes from jejb folded] Signed-off-by: Al Viro --- arch/parisc/kernel/entry.S | 86 ++++++++++---------------------------------- arch/parisc/kernel/process.c | 28 +++++---------- 2 files changed, 27 insertions(+), 87 deletions(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 7d22e97..47fb6dd 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -719,7 +719,7 @@ ENTRY(ret_from_kernel_thread) BL schedule_tail, %r2 nop - LDREG TI_TASK-THREAD_SZ_ALGN(%r30), %r1 + LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1 LDREG TASK_PT_GR25(%r1), %r26 #ifdef CONFIG_64BIT LDREG TASK_PT_GR27(%r1), %r27 @@ -743,9 +743,8 @@ ENDPROC(ret_from_kernel_thread) ENTRY(ret_from_kernel_execve) mfctl %cr30, %r1 - ldo THREAD_SZ_ALGN(%r1), %r30 - b intr_return /* forward */ - copy %r26,%r16 /* pt_regs into r16 */ + b syscall_exit /* forward */ + ldo THREAD_SZ_ALGN+FRAME_SIZE(%r1), %r30 ENDPROC(ret_from_kernel_execve) @@ -1709,39 +1708,13 @@ ENTRY(sys_fork_wrapper) LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1 ldo TASK_REGS(%r1),%r1 reg_save %r1 - mfctl %cr27, %r3 - STREG %r3, PT_CR27(%r1) - - STREG %r2,-RP_OFFSET(%r30) - ldo FRAME_SIZE(%r30),%r30 -#ifdef CONFIG_64BIT - ldo -16(%r30),%r29 /* Reference param save area */ -#endif - - /* These are call-clobbered registers and therefore - also syscall-clobbered (we hope). */ - STREG %r2,PT_GR19(%r1) /* save for child */ - STREG %r30,PT_GR21(%r1) + mfctl %cr27, %r28 + STREG %r28, PT_CR27(%r1) LDREG PT_GR30(%r1),%r25 copy %r1,%r24 - BL sys_clone,%r2 + b sys_clone ldi SIGCHLD,%r26 - - LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2 -wrapper_exit: - ldo -FRAME_SIZE(%r30),%r30 /* get the stackframe */ - LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 - ldo TASK_REGS(%r1),%r1 /* get pt regs */ - - LDREG PT_CR27(%r1), %r3 - mtctl %r3, %cr27 - reg_restore %r1 - - /* strace expects syscall # to be preserved in r20 */ - ldi __NR_fork,%r20 - bv %r0(%r2) - STREG %r20,PT_GR20(%r1) ENDPROC(sys_fork_wrapper) /* Set the return value for the child */ @@ -1749,9 +1722,13 @@ ENTRY(child_return) BL schedule_tail, %r2 nop - LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE-FRAME_SIZE(%r30), %r1 - LDREG TASK_PT_GR19(%r1),%r2 - b wrapper_exit + LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1 + ldo TASK_REGS(%r1),%r1 /* get pt regs */ + + LDREG PT_CR27(%r1), %r3 + mtctl %r3, %cr27 + reg_restore %r1 + b syscall_exit copy %r0,%r28 ENDPROC(child_return) @@ -1760,23 +1737,10 @@ ENTRY(sys_clone_wrapper) LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 ldo TASK_REGS(%r1),%r1 /* get pt regs */ reg_save %r1 - mfctl %cr27, %r3 - STREG %r3, PT_CR27(%r1) - - STREG %r2,-RP_OFFSET(%r30) - ldo FRAME_SIZE(%r30),%r30 -#ifdef CONFIG_64BIT - ldo -16(%r30),%r29 /* Reference param save area */ -#endif - - /* WARNING - Clobbers r19 and r21, userspace must save these! */ - STREG %r2,PT_GR19(%r1) /* save for child */ - STREG %r30,PT_GR21(%r1) - BL sys_clone,%r2 + mfctl %cr27, %r28 + STREG %r28, PT_CR27(%r1) + b sys_clone copy %r1,%r24 - - b wrapper_exit - LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2 ENDPROC(sys_clone_wrapper) @@ -1784,23 +1748,11 @@ ENTRY(sys_vfork_wrapper) LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 ldo TASK_REGS(%r1),%r1 /* get pt regs */ reg_save %r1 - mfctl %cr27, %r3 - STREG %r3, PT_CR27(%r1) - - STREG %r2,-RP_OFFSET(%r30) - ldo FRAME_SIZE(%r30),%r30 -#ifdef CONFIG_64BIT - ldo -16(%r30),%r29 /* Reference param save area */ -#endif + mfctl %cr27, %r28 + STREG %r28, PT_CR27(%r1) - STREG %r2,PT_GR19(%r1) /* save for child */ - STREG %r30,PT_GR21(%r1) - - BL sys_vfork,%r2 + b sys_vfork copy %r1,%r26 - - b wrapper_exit - LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2 ENDPROC(sys_vfork_wrapper) diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 44e8534..38db36f 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -52,6 +52,7 @@ #include #include +#include #include #include #include @@ -253,14 +254,16 @@ copy_thread(unsigned long clone_flags, unsigned long usp, #ifdef CONFIG_HPUX extern void * const hpux_child_return; #endif - - if (unlikely((p->flags & PF_KTHREAD) && usp != 0)) { + if (unlikely(p->flags & PF_KTHREAD)) { memset(cregs, 0, sizeof(struct pt_regs)); + if (!usp) /* idle thread */ + return 0; + /* kernel thread */ - cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN; /* Must exit via ret_from_kernel_thread in order * to call schedule_tail() */ + cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE; cregs->kpc = (unsigned long) &ret_from_kernel_thread; /* * Copy function and argument to be called from @@ -275,22 +278,8 @@ copy_thread(unsigned long clone_flags, unsigned long usp, cregs->gr[25] = arg; } else { /* user thread */ - /* - * Note that the fork wrappers are responsible - * for setting gr[21]. - */ - - *cregs = *pregs; - - /* Set the return value for the child. Note that this is not - actually restored by the syscall exit path, but we put it - here for consistency in case of signals. */ - cregs->gr[28] = 0; /* child */ - - /* Use same stack depth as parent */ - cregs->ksp = (unsigned long)stack - + (pregs->gr[21] & (THREAD_SIZE - 1)); cregs->gr[30] = usp; + cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE; if (personality(p->personality) == PER_HPUX) { #ifdef CONFIG_HPUX cregs->kpc = (unsigned long) &hpux_child_return; @@ -302,8 +291,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp, } /* Setup thread TLS area from the 4th parameter in clone */ if (clone_flags & CLONE_SETTLS) - cregs->cr27 = pregs->gr[23]; - + cregs->cr27 = pregs->gr[23]; } return 0; -- cgit v1.1 From 363806ddd232b67fdb2bd7ec8c98527e481c25c4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 11 Oct 2012 17:22:16 -0400 Subject: parisc: switch to saner kernel_execve() semantics ACKed-by: James Bottomley Signed-off-by: Al Viro --- arch/parisc/kernel/entry.S | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 47fb6dd..c9a9abd 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -727,26 +727,10 @@ ENTRY(ret_from_kernel_thread) LDREG TASK_PT_GR26(%r1), %r1 ble 0(%sr7, %r1) copy %r31, %r2 - -#ifdef CONFIG_64BIT - ldo -16(%r30),%r29 /* Reference param save area */ - loadgp /* Thread could have been in a module */ -#endif -#ifndef CONFIG_64BIT - b sys_exit -#else - load32 sys_exit, %r1 - bv %r0(%r1) -#endif - ldi 0, %r26 + b finish_child_return + nop ENDPROC(ret_from_kernel_thread) -ENTRY(ret_from_kernel_execve) - mfctl %cr30, %r1 - b syscall_exit /* forward */ - ldo THREAD_SZ_ALGN+FRAME_SIZE(%r1), %r30 -ENDPROC(ret_from_kernel_execve) - /* * struct task_struct *_switch_to(struct task_struct *prev, @@ -1721,7 +1705,7 @@ ENDPROC(sys_fork_wrapper) ENTRY(child_return) BL schedule_tail, %r2 nop - +finish_child_return: LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1 ldo TASK_REGS(%r1),%r1 /* get pt regs */ -- cgit v1.1 From 415bfae9e9dbc2232f1797a3ac78a22049a75e06 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 26 Oct 2012 19:59:16 -0400 Subject: parisc: switch to generic fork/vfork/clone Signed-off-by: Al Viro --- arch/parisc/kernel/entry.S | 38 ++++++++-------------------------- arch/parisc/kernel/process.c | 49 +++++++++----------------------------------- 2 files changed, 18 insertions(+), 69 deletions(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index c9a9abd..bfb4424 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -1688,18 +1688,20 @@ dtlb_fault: LDREG PT_GR18(\regs),%r18 .endm -ENTRY(sys_fork_wrapper) + .macro fork_like name +ENTRY(sys_\name\()_wrapper) LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1 ldo TASK_REGS(%r1),%r1 reg_save %r1 mfctl %cr27, %r28 + b sys_\name STREG %r28, PT_CR27(%r1) +ENDPROC(sys_\name\()_wrapper) + .endm - LDREG PT_GR30(%r1),%r25 - copy %r1,%r24 - b sys_clone - ldi SIGCHLD,%r26 -ENDPROC(sys_fork_wrapper) +fork_like clone +fork_like fork +fork_like vfork /* Set the return value for the child */ ENTRY(child_return) @@ -1716,30 +1718,6 @@ finish_child_return: copy %r0,%r28 ENDPROC(child_return) - -ENTRY(sys_clone_wrapper) - LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 - ldo TASK_REGS(%r1),%r1 /* get pt regs */ - reg_save %r1 - mfctl %cr27, %r28 - STREG %r28, PT_CR27(%r1) - b sys_clone - copy %r1,%r24 -ENDPROC(sys_clone_wrapper) - - -ENTRY(sys_vfork_wrapper) - LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 - ldo TASK_REGS(%r1),%r1 /* get pt regs */ - reg_save %r1 - mfctl %cr27, %r28 - STREG %r28, PT_CR27(%r1) - - b sys_vfork - copy %r1,%r26 -ENDPROC(sys_vfork_wrapper) - - ENTRY(sys_rt_sigreturn_wrapper) LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26 ldo TASK_REGS(%r26),%r26 /* get pt regs */ diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 38db36f..9753ecf 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -202,46 +202,10 @@ int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r) return 1; } -/* Note that "fork()" is implemented in terms of clone, with - parameters (SIGCHLD, regs->gr[30], regs). */ -int -sys_clone(unsigned long clone_flags, unsigned long usp, - struct pt_regs *regs) -{ - /* Arugments from userspace are: - r26 = Clone flags. - r25 = Child stack. - r24 = parent_tidptr. - r23 = Is the TLS storage descriptor - r22 = child_tidptr - - However, these last 3 args are only examined - if the proper flags are set. */ - int __user *parent_tidptr = (int __user *)regs->gr[24]; - int __user *child_tidptr = (int __user *)regs->gr[22]; - - /* usp must be word aligned. This also prevents users from - * passing in the value 1 (which is the signal for a special - * return for a kernel thread) */ - usp = ALIGN(usp, 4); - - /* A zero value for usp means use the current stack */ - if (usp == 0) - usp = regs->gr[30]; - - return do_fork(clone_flags, usp, regs, 0, parent_tidptr, child_tidptr); -} - -int -sys_vfork(struct pt_regs *regs) -{ - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gr[30], regs, 0, NULL, NULL); -} - int copy_thread(unsigned long clone_flags, unsigned long usp, unsigned long arg, - struct task_struct *p, struct pt_regs *pregs) + struct task_struct *p, struct pt_regs *unused) { struct pt_regs * cregs = &(p->thread.regs); void *stack = task_stack_page(p); @@ -278,7 +242,14 @@ copy_thread(unsigned long clone_flags, unsigned long usp, cregs->gr[25] = arg; } else { /* user thread */ - cregs->gr[30] = usp; + /* usp must be word aligned. This also prevents users from + * passing in the value 1 (which is the signal for a special + * return for a kernel thread) */ + if (usp) { + usp = ALIGN(usp, 4); + if (likely(usp)) + cregs->gr[30] = usp; + } cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE; if (personality(p->personality) == PER_HPUX) { #ifdef CONFIG_HPUX @@ -291,7 +262,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp, } /* Setup thread TLS area from the 4th parameter in clone */ if (clone_flags & CLONE_SETTLS) - cregs->cr27 = pregs->gr[23]; + cregs->cr27 = cregs->gr[23]; } return 0; -- cgit v1.1 From afa86fc426ff7e7f5477f15da9c405d08d5cf790 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 22 Oct 2012 22:51:14 -0400 Subject: flagday: don't pass regs to copy_thread() Signed-off-by: Al Viro --- arch/parisc/kernel/process.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 9753ecf..d135072 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -204,10 +204,9 @@ int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r) int copy_thread(unsigned long clone_flags, unsigned long usp, - unsigned long arg, - struct task_struct *p, struct pt_regs *unused) + unsigned long arg, struct task_struct *p) { - struct pt_regs * cregs = &(p->thread.regs); + struct pt_regs *cregs = &(p->thread.regs); void *stack = task_stack_page(p); /* We have to use void * instead of a function pointer, because -- cgit v1.1