Commit 415bfae9 authored by Al Viro's avatar Al Viro

parisc: switch to generic fork/vfork/clone

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 92bbe6cd
...@@ -24,6 +24,7 @@ config PARISC ...@@ -24,6 +24,7 @@ config PARISC
select MODULES_USE_ELF_RELA select MODULES_USE_ELF_RELA
select GENERIC_KERNEL_THREAD select GENERIC_KERNEL_THREAD
select GENERIC_KERNEL_EXECVE select GENERIC_KERNEL_EXECVE
select CLONE_BACKWARDS
help help
The PA-RISC microprocessor is designed by Hewlett-Packard and used The PA-RISC microprocessor is designed by Hewlett-Packard and used
......
...@@ -164,6 +164,9 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ ...@@ -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_SYS_RT_SIGSUSPEND
#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
#define __ARCH_WANT_SYS_EXECVE #define __ARCH_WANT_SYS_EXECVE
#define __ARCH_WANT_SYS_FORK
#define __ARCH_WANT_SYS_VFORK
#define __ARCH_WANT_SYS_CLONE
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
......
...@@ -1688,18 +1688,20 @@ dtlb_fault: ...@@ -1688,18 +1688,20 @@ dtlb_fault:
LDREG PT_GR18(\regs),%r18 LDREG PT_GR18(\regs),%r18
.endm .endm
ENTRY(sys_fork_wrapper) .macro fork_like name
ENTRY(sys_\name\()_wrapper)
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
ldo TASK_REGS(%r1),%r1 ldo TASK_REGS(%r1),%r1
reg_save %r1 reg_save %r1
mfctl %cr27, %r28 mfctl %cr27, %r28
b sys_\name
STREG %r28, PT_CR27(%r1) STREG %r28, PT_CR27(%r1)
ENDPROC(sys_\name\()_wrapper)
.endm
LDREG PT_GR30(%r1),%r25 fork_like clone
copy %r1,%r24 fork_like fork
b sys_clone fork_like vfork
ldi SIGCHLD,%r26
ENDPROC(sys_fork_wrapper)
/* Set the return value for the child */ /* Set the return value for the child */
ENTRY(child_return) ENTRY(child_return)
...@@ -1716,30 +1718,6 @@ finish_child_return: ...@@ -1716,30 +1718,6 @@ finish_child_return:
copy %r0,%r28 copy %r0,%r28
ENDPROC(child_return) 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) ENTRY(sys_rt_sigreturn_wrapper)
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26
ldo TASK_REGS(%r26),%r26 /* get pt regs */ ldo TASK_REGS(%r26),%r26 /* get pt regs */
......
...@@ -202,46 +202,10 @@ int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r) ...@@ -202,46 +202,10 @@ int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r)
return 1; 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 int
copy_thread(unsigned long clone_flags, unsigned long usp, copy_thread(unsigned long clone_flags, unsigned long usp,
unsigned long arg, 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); struct pt_regs * cregs = &(p->thread.regs);
void *stack = task_stack_page(p); void *stack = task_stack_page(p);
...@@ -278,7 +242,14 @@ copy_thread(unsigned long clone_flags, unsigned long usp, ...@@ -278,7 +242,14 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
cregs->gr[25] = arg; cregs->gr[25] = arg;
} else { } else {
/* user thread */ /* user thread */
/* 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->gr[30] = usp;
}
cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE; cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE;
if (personality(p->personality) == PER_HPUX) { if (personality(p->personality) == PER_HPUX) {
#ifdef CONFIG_HPUX #ifdef CONFIG_HPUX
...@@ -291,7 +262,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp, ...@@ -291,7 +262,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
} }
/* Setup thread TLS area from the 4th parameter in clone */ /* Setup thread TLS area from the 4th parameter in clone */
if (clone_flags & CLONE_SETTLS) if (clone_flags & CLONE_SETTLS)
cregs->cr27 = pregs->gr[23]; cregs->cr27 = cregs->gr[23];
} }
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment