arm: switch to generic fork/vfork/clone
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
1d4b4b2994
commit
38a61b6b4a
6 changed files with 13 additions and 55 deletions
|
@ -55,6 +55,7 @@ config ARM
|
||||||
select SYS_SUPPORTS_APM_EMULATION
|
select SYS_SUPPORTS_APM_EMULATION
|
||||||
select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND
|
select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND
|
||||||
select MODULES_USE_ELF_REL
|
select MODULES_USE_ELF_REL
|
||||||
|
select CLONE_BACKWARDS
|
||||||
help
|
help
|
||||||
The ARM series is a line of low-power-consumption RISC chip designs
|
The ARM series is a line of low-power-consumption RISC chip designs
|
||||||
licensed by ARM Ltd and targeted at embedded applications and
|
licensed by ARM Ltd and targeted at embedded applications and
|
||||||
|
|
|
@ -42,6 +42,9 @@
|
||||||
#define __ARCH_WANT_SYS_SOCKETCALL
|
#define __ARCH_WANT_SYS_SOCKETCALL
|
||||||
#endif
|
#endif
|
||||||
#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
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "Conditional" syscalls
|
* "Conditional" syscalls
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
*/
|
*/
|
||||||
/* 0 */ CALL(sys_restart_syscall)
|
/* 0 */ CALL(sys_restart_syscall)
|
||||||
CALL(sys_exit)
|
CALL(sys_exit)
|
||||||
CALL(sys_fork_wrapper)
|
CALL(sys_fork)
|
||||||
CALL(sys_read)
|
CALL(sys_read)
|
||||||
CALL(sys_write)
|
CALL(sys_write)
|
||||||
/* 5 */ CALL(sys_open)
|
/* 5 */ CALL(sys_open)
|
||||||
|
@ -129,7 +129,7 @@
|
||||||
CALL(OBSOLETE(ABI(sys_ipc, sys_oabi_ipc)))
|
CALL(OBSOLETE(ABI(sys_ipc, sys_oabi_ipc)))
|
||||||
CALL(sys_fsync)
|
CALL(sys_fsync)
|
||||||
CALL(sys_sigreturn_wrapper)
|
CALL(sys_sigreturn_wrapper)
|
||||||
/* 120 */ CALL(sys_clone_wrapper)
|
/* 120 */ CALL(sys_clone)
|
||||||
CALL(sys_setdomainname)
|
CALL(sys_setdomainname)
|
||||||
CALL(sys_newuname)
|
CALL(sys_newuname)
|
||||||
CALL(sys_ni_syscall) /* modify_ldt */
|
CALL(sys_ni_syscall) /* modify_ldt */
|
||||||
|
@ -199,7 +199,7 @@
|
||||||
CALL(sys_sendfile)
|
CALL(sys_sendfile)
|
||||||
CALL(sys_ni_syscall) /* getpmsg */
|
CALL(sys_ni_syscall) /* getpmsg */
|
||||||
CALL(sys_ni_syscall) /* putpmsg */
|
CALL(sys_ni_syscall) /* putpmsg */
|
||||||
/* 190 */ CALL(sys_vfork_wrapper)
|
/* 190 */ CALL(sys_vfork)
|
||||||
CALL(sys_getrlimit)
|
CALL(sys_getrlimit)
|
||||||
CALL(sys_mmap2)
|
CALL(sys_mmap2)
|
||||||
CALL(ABI(sys_truncate64, sys_oabi_truncate64))
|
CALL(ABI(sys_truncate64, sys_oabi_truncate64))
|
||||||
|
|
|
@ -510,22 +510,6 @@ sys_syscall:
|
||||||
b sys_ni_syscall
|
b sys_ni_syscall
|
||||||
ENDPROC(sys_syscall)
|
ENDPROC(sys_syscall)
|
||||||
|
|
||||||
sys_fork_wrapper:
|
|
||||||
add r0, sp, #S_OFF
|
|
||||||
b sys_fork
|
|
||||||
ENDPROC(sys_fork_wrapper)
|
|
||||||
|
|
||||||
sys_vfork_wrapper:
|
|
||||||
add r0, sp, #S_OFF
|
|
||||||
b sys_vfork
|
|
||||||
ENDPROC(sys_vfork_wrapper)
|
|
||||||
|
|
||||||
sys_clone_wrapper:
|
|
||||||
add ip, sp, #S_OFF
|
|
||||||
str ip, [sp, #4]
|
|
||||||
b sys_clone
|
|
||||||
ENDPROC(sys_clone_wrapper)
|
|
||||||
|
|
||||||
sys_sigreturn_wrapper:
|
sys_sigreturn_wrapper:
|
||||||
add r0, sp, #S_OFF
|
add r0, sp, #S_OFF
|
||||||
mov why, #0 @ prevent syscall restart handling
|
mov why, #0 @ prevent syscall restart handling
|
||||||
|
|
|
@ -376,17 +376,18 @@ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
|
||||||
|
|
||||||
int
|
int
|
||||||
copy_thread(unsigned long clone_flags, unsigned long stack_start,
|
copy_thread(unsigned long clone_flags, unsigned long stack_start,
|
||||||
unsigned long stk_sz, struct task_struct *p, struct pt_regs *regs)
|
unsigned long stk_sz, struct task_struct *p, struct pt_regs *unused)
|
||||||
{
|
{
|
||||||
struct thread_info *thread = task_thread_info(p);
|
struct thread_info *thread = task_thread_info(p);
|
||||||
struct pt_regs *childregs = task_pt_regs(p);
|
struct pt_regs *childregs = task_pt_regs(p);
|
||||||
|
|
||||||
memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
|
memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
|
||||||
|
|
||||||
if (likely(regs)) {
|
if (likely(!(p->flags & PF_KTHREAD))) {
|
||||||
*childregs = *regs;
|
*childregs = *current_pt_regs();
|
||||||
childregs->ARM_r0 = 0;
|
childregs->ARM_r0 = 0;
|
||||||
childregs->ARM_sp = stack_start;
|
if (stack_start)
|
||||||
|
childregs->ARM_sp = stack_start;
|
||||||
} else {
|
} else {
|
||||||
memset(childregs, 0, sizeof(struct pt_regs));
|
memset(childregs, 0, sizeof(struct pt_regs));
|
||||||
thread->cpu_context.r4 = stk_sz;
|
thread->cpu_context.r4 = stk_sz;
|
||||||
|
@ -399,7 +400,7 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start,
|
||||||
clear_ptrace_hw_breakpoint(p);
|
clear_ptrace_hw_breakpoint(p);
|
||||||
|
|
||||||
if (clone_flags & CLONE_SETTLS)
|
if (clone_flags & CLONE_SETTLS)
|
||||||
thread->tp_value = regs->ARM_r3;
|
thread->tp_value = childregs->ARM_r3;
|
||||||
|
|
||||||
thread_notify(THREAD_NOTIFY_COPY, thread);
|
thread_notify(THREAD_NOTIFY_COPY, thread);
|
||||||
|
|
||||||
|
|
|
@ -28,37 +28,6 @@
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
|
||||||
/* Fork a new task - this creates a new program thread.
|
|
||||||
* This is called indirectly via a small wrapper
|
|
||||||
*/
|
|
||||||
asmlinkage int sys_fork(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_MMU
|
|
||||||
return do_fork(SIGCHLD, regs->ARM_sp, regs, 0, NULL, NULL);
|
|
||||||
#else
|
|
||||||
/* can not support in nommu mode */
|
|
||||||
return(-EINVAL);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clone a task - this clones the calling program thread.
|
|
||||||
* This is called indirectly via a small wrapper
|
|
||||||
*/
|
|
||||||
asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
|
|
||||||
int __user *parent_tidptr, int tls_val,
|
|
||||||
int __user *child_tidptr, struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
if (!newsp)
|
|
||||||
newsp = regs->ARM_sp;
|
|
||||||
|
|
||||||
return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage int sys_vfork(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->ARM_sp, regs, 0, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since loff_t is a 64 bit type we avoid a lot of ABI hassle
|
* Since loff_t is a 64 bit type we avoid a lot of ABI hassle
|
||||||
* with a different argument ordering.
|
* with a different argument ordering.
|
||||||
|
|
Loading…
Add table
Reference in a new issue