aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-12 15:22:13 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-12 15:22:13 -0500
commit9977d9b379cb77e0f67bd6f4563618106e58e11d (patch)
tree0191accfddf578edb52c69c933d64521e3dce297 /kernel/fork.c
parentcf4af01221579a4e895f43dbfc47598fbfc5a731 (diff)
parent541880d9a2c7871f6370071d55aa6662d329c51e (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull big execve/kernel_thread/fork unification series from Al Viro: "All architectures are converted to new model. Quite a bit of that stuff is actually shared with architecture trees; in such cases it's literally shared branch pulled by both, not a cherry-pick. A lot of ugliness and black magic is gone (-3KLoC total in this one): - kernel_thread()/kernel_execve()/sys_execve() redesign. We don't do syscalls from kernel anymore for either kernel_thread() or kernel_execve(): kernel_thread() is essentially clone(2) with callback run before we return to userland, the callbacks either never return or do successful do_execve() before returning. kernel_execve() is a wrapper for do_execve() - it doesn't need to do transition to user mode anymore. As a result kernel_thread() and kernel_execve() are arch-independent now - they live in kernel/fork.c and fs/exec.c resp. sys_execve() is also in fs/exec.c and it's completely architecture-independent. - daemonize() is gone, along with its parts in fs/*.c - struct pt_regs * is no longer passed to do_fork/copy_process/ copy_thread/do_execve/search_binary_handler/->load_binary/do_coredump. - sys_fork()/sys_vfork()/sys_clone() unified; some architectures still need wrappers (ones with callee-saved registers not saved in pt_regs on syscall entry), but the main part of those suckers is in kernel/fork.c now." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: (113 commits) do_coredump(): get rid of pt_regs argument print_fatal_signal(): get rid of pt_regs argument ptrace_signal(): get rid of unused arguments get rid of ptrace_signal_deliver() arguments new helper: signal_pt_regs() unify default ptrace_signal_deliver flagday: kill pt_regs argument of do_fork() death to idle_regs() don't pass regs to copy_process() flagday: don't pass regs to copy_thread() bfin: switch to generic vfork, get rid of pointless wrappers xtensa: switch to generic clone() openrisc: switch to use of generic fork and clone unicore32: switch to generic clone(2) score: switch to generic fork/vfork/clone c6x: sanitize copy_thread(), get rid of clone(2) wrapper, switch to generic clone() take sys_fork/sys_vfork/sys_clone prototypes to linux/syscalls.h mn10300: switch to generic fork/vfork/clone h8300: switch to generic fork/vfork/clone tile: switch to generic clone() ... Conflicts: arch/microblaze/include/asm/Kbuild
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c64
1 files changed, 48 insertions, 16 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 79de9f99a48d..3c31e874afad 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1129,7 +1129,6 @@ static void posix_cpu_timers_init(struct task_struct *tsk)
1129 */ 1129 */
1130static struct task_struct *copy_process(unsigned long clone_flags, 1130static struct task_struct *copy_process(unsigned long clone_flags,
1131 unsigned long stack_start, 1131 unsigned long stack_start,
1132 struct pt_regs *regs,
1133 unsigned long stack_size, 1132 unsigned long stack_size,
1134 int __user *child_tidptr, 1133 int __user *child_tidptr,
1135 struct pid *pid, 1134 struct pid *pid,
@@ -1321,7 +1320,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1321 retval = copy_io(clone_flags, p); 1320 retval = copy_io(clone_flags, p);
1322 if (retval) 1321 if (retval)
1323 goto bad_fork_cleanup_namespaces; 1322 goto bad_fork_cleanup_namespaces;
1324 retval = copy_thread(clone_flags, stack_start, stack_size, p, regs); 1323 retval = copy_thread(clone_flags, stack_start, stack_size, p);
1325 if (retval) 1324 if (retval)
1326 goto bad_fork_cleanup_io; 1325 goto bad_fork_cleanup_io;
1327 1326
@@ -1510,12 +1509,6 @@ fork_out:
1510 return ERR_PTR(retval); 1509 return ERR_PTR(retval);
1511} 1510}
1512 1511
1513noinline struct pt_regs * __cpuinit __attribute__((weak)) idle_regs(struct pt_regs *regs)
1514{
1515 memset(regs, 0, sizeof(struct pt_regs));
1516 return regs;
1517}
1518
1519static inline void init_idle_pids(struct pid_link *links) 1512static inline void init_idle_pids(struct pid_link *links)
1520{ 1513{
1521 enum pid_type type; 1514 enum pid_type type;
@@ -1529,10 +1522,7 @@ static inline void init_idle_pids(struct pid_link *links)
1529struct task_struct * __cpuinit fork_idle(int cpu) 1522struct task_struct * __cpuinit fork_idle(int cpu)
1530{ 1523{
1531 struct task_struct *task; 1524 struct task_struct *task;
1532 struct pt_regs regs; 1525 task = copy_process(CLONE_VM, 0, 0, NULL, &init_struct_pid, 0);
1533
1534 task = copy_process(CLONE_VM, 0, idle_regs(&regs), 0, NULL,
1535 &init_struct_pid, 0);
1536 if (!IS_ERR(task)) { 1526 if (!IS_ERR(task)) {
1537 init_idle_pids(task->pids); 1527 init_idle_pids(task->pids);
1538 init_idle(task, cpu); 1528 init_idle(task, cpu);
@@ -1549,7 +1539,6 @@ struct task_struct * __cpuinit fork_idle(int cpu)
1549 */ 1539 */
1550long do_fork(unsigned long clone_flags, 1540long do_fork(unsigned long clone_flags,
1551 unsigned long stack_start, 1541 unsigned long stack_start,
1552 struct pt_regs *regs,
1553 unsigned long stack_size, 1542 unsigned long stack_size,
1554 int __user *parent_tidptr, 1543 int __user *parent_tidptr,
1555 int __user *child_tidptr) 1544 int __user *child_tidptr)
@@ -1579,7 +1568,7 @@ long do_fork(unsigned long clone_flags,
1579 * requested, no event is reported; otherwise, report if the event 1568 * requested, no event is reported; otherwise, report if the event
1580 * for the type of forking is enabled. 1569 * for the type of forking is enabled.
1581 */ 1570 */
1582 if (!(clone_flags & CLONE_UNTRACED) && likely(user_mode(regs))) { 1571 if (!(clone_flags & CLONE_UNTRACED)) {
1583 if (clone_flags & CLONE_VFORK) 1572 if (clone_flags & CLONE_VFORK)
1584 trace = PTRACE_EVENT_VFORK; 1573 trace = PTRACE_EVENT_VFORK;
1585 else if ((clone_flags & CSIGNAL) != SIGCHLD) 1574 else if ((clone_flags & CSIGNAL) != SIGCHLD)
@@ -1591,7 +1580,7 @@ long do_fork(unsigned long clone_flags,
1591 trace = 0; 1580 trace = 0;
1592 } 1581 }
1593 1582
1594 p = copy_process(clone_flags, stack_start, regs, stack_size, 1583 p = copy_process(clone_flags, stack_start, stack_size,
1595 child_tidptr, NULL, trace); 1584 child_tidptr, NULL, trace);
1596 /* 1585 /*
1597 * Do this prior waking up the new thread - the thread pointer 1586 * Do this prior waking up the new thread - the thread pointer
@@ -1635,11 +1624,54 @@ long do_fork(unsigned long clone_flags,
1635 */ 1624 */
1636pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) 1625pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
1637{ 1626{
1638 return do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn, NULL, 1627 return do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn,
1639 (unsigned long)arg, NULL, NULL); 1628 (unsigned long)arg, NULL, NULL);
1640} 1629}
1641#endif 1630#endif
1642 1631
1632#ifdef __ARCH_WANT_SYS_FORK
1633SYSCALL_DEFINE0(fork)
1634{
1635#ifdef CONFIG_MMU
1636 return do_fork(SIGCHLD, 0, 0, NULL, NULL);
1637#else
1638 /* can not support in nommu mode */
1639 return(-EINVAL);
1640#endif
1641}
1642#endif
1643
1644#ifdef __ARCH_WANT_SYS_VFORK
1645SYSCALL_DEFINE0(vfork)
1646{
1647 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0,
1648 0, NULL, NULL);
1649}
1650#endif
1651
1652#ifdef __ARCH_WANT_SYS_CLONE
1653#ifdef CONFIG_CLONE_BACKWARDS
1654SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
1655 int __user *, parent_tidptr,
1656 int, tls_val,
1657 int __user *, child_tidptr)
1658#elif defined(CONFIG_CLONE_BACKWARDS2)
1659SYSCALL_DEFINE5(clone, unsigned long, newsp, unsigned long, clone_flags,
1660 int __user *, parent_tidptr,
1661 int __user *, child_tidptr,
1662 int, tls_val)
1663#else
1664SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
1665 int __user *, parent_tidptr,
1666 int __user *, child_tidptr,
1667 int, tls_val)
1668#endif
1669{
1670 return do_fork(clone_flags, newsp, 0,
1671 parent_tidptr, child_tidptr);
1672}
1673#endif
1674
1643#ifndef ARCH_MIN_MMSTRUCT_ALIGN 1675#ifndef ARCH_MIN_MMSTRUCT_ALIGN
1644#define ARCH_MIN_MMSTRUCT_ALIGN 0 1676#define ARCH_MIN_MMSTRUCT_ALIGN 0
1645#endif 1677#endif