diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-10-26 23:59:16 (GMT) |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-11-29 03:36:46 (GMT) |
commit | 415bfae9e9dbc2232f1797a3ac78a22049a75e06 (patch) | |
tree | d5cd2e445270a1ffc6f1f5a860d458cbf321066b | |
parent | 92bbe6cdfdeeaf9ac2a240b1829bab219e7e91d0 (diff) | |
download | linux-415bfae9e9dbc2232f1797a3ac78a22049a75e06.tar.xz |
parisc: switch to generic fork/vfork/clone
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | arch/parisc/Kconfig | 1 | ||||
-rw-r--r-- | arch/parisc/include/asm/unistd.h | 3 | ||||
-rw-r--r-- | arch/parisc/kernel/entry.S | 38 | ||||
-rw-r--r-- | arch/parisc/kernel/process.c | 49 |
4 files changed, 22 insertions, 69 deletions
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 0aec70c..e688a2b 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -24,6 +24,7 @@ config PARISC select MODULES_USE_ELF_RELA select GENERIC_KERNEL_THREAD select GENERIC_KERNEL_EXECVE + select CLONE_BACKWARDS help The PA-RISC microprocessor is designed by Hewlett-Packard and used diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h index 55512e2..1efef41 100644 --- a/arch/parisc/include/asm/unistd.h +++ b/arch/parisc/include/asm/unistd.h @@ -164,6 +164,9 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ #define __ARCH_WANT_SYS_RT_SIGSUSPEND #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND #define __ARCH_WANT_SYS_EXECVE +#define __ARCH_WANT_SYS_FORK +#define __ARCH_WANT_SYS_VFORK +#define __ARCH_WANT_SYS_CLONE #endif /* __ASSEMBLY__ */ 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; |