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)
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 */
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);
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
}
/* 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;