diff options
Diffstat (limited to 'kernel/fork.c')
-rw-r--r-- | kernel/fork.c | 69 |
1 files changed, 53 insertions, 16 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 51ad0b0b7266..202a0ba63d3c 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -64,6 +64,7 @@ | |||
64 | #include <linux/magic.h> | 64 | #include <linux/magic.h> |
65 | #include <linux/perf_event.h> | 65 | #include <linux/perf_event.h> |
66 | #include <linux/posix-timers.h> | 66 | #include <linux/posix-timers.h> |
67 | #include <linux/user-return-notifier.h> | ||
67 | 68 | ||
68 | #include <asm/pgtable.h> | 69 | #include <asm/pgtable.h> |
69 | #include <asm/pgalloc.h> | 70 | #include <asm/pgalloc.h> |
@@ -91,7 +92,7 @@ int nr_processes(void) | |||
91 | int cpu; | 92 | int cpu; |
92 | int total = 0; | 93 | int total = 0; |
93 | 94 | ||
94 | for_each_online_cpu(cpu) | 95 | for_each_possible_cpu(cpu) |
95 | total += per_cpu(process_counts, cpu); | 96 | total += per_cpu(process_counts, cpu); |
96 | 97 | ||
97 | return total; | 98 | return total; |
@@ -249,6 +250,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) | |||
249 | goto out; | 250 | goto out; |
250 | 251 | ||
251 | setup_thread_stack(tsk, orig); | 252 | setup_thread_stack(tsk, orig); |
253 | clear_user_return_notifier(tsk); | ||
252 | stackend = end_of_stack(tsk); | 254 | stackend = end_of_stack(tsk); |
253 | *stackend = STACK_END_MAGIC; /* for overflow detection */ | 255 | *stackend = STACK_END_MAGIC; /* for overflow detection */ |
254 | 256 | ||
@@ -434,6 +436,14 @@ __setup("coredump_filter=", coredump_filter_setup); | |||
434 | 436 | ||
435 | #include <linux/init_task.h> | 437 | #include <linux/init_task.h> |
436 | 438 | ||
439 | static void mm_init_aio(struct mm_struct *mm) | ||
440 | { | ||
441 | #ifdef CONFIG_AIO | ||
442 | spin_lock_init(&mm->ioctx_lock); | ||
443 | INIT_HLIST_HEAD(&mm->ioctx_list); | ||
444 | #endif | ||
445 | } | ||
446 | |||
437 | static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) | 447 | static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) |
438 | { | 448 | { |
439 | atomic_set(&mm->mm_users, 1); | 449 | atomic_set(&mm->mm_users, 1); |
@@ -447,10 +457,9 @@ static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) | |||
447 | set_mm_counter(mm, file_rss, 0); | 457 | set_mm_counter(mm, file_rss, 0); |
448 | set_mm_counter(mm, anon_rss, 0); | 458 | set_mm_counter(mm, anon_rss, 0); |
449 | spin_lock_init(&mm->page_table_lock); | 459 | spin_lock_init(&mm->page_table_lock); |
450 | spin_lock_init(&mm->ioctx_lock); | ||
451 | INIT_HLIST_HEAD(&mm->ioctx_list); | ||
452 | mm->free_area_cache = TASK_UNMAPPED_BASE; | 460 | mm->free_area_cache = TASK_UNMAPPED_BASE; |
453 | mm->cached_hole_size = ~0UL; | 461 | mm->cached_hole_size = ~0UL; |
462 | mm_init_aio(mm); | ||
454 | mm_init_owner(mm, p); | 463 | mm_init_owner(mm, p); |
455 | 464 | ||
456 | if (likely(!mm_alloc_pgd(mm))) { | 465 | if (likely(!mm_alloc_pgd(mm))) { |
@@ -511,6 +520,8 @@ void mmput(struct mm_struct *mm) | |||
511 | spin_unlock(&mmlist_lock); | 520 | spin_unlock(&mmlist_lock); |
512 | } | 521 | } |
513 | put_swap_token(mm); | 522 | put_swap_token(mm); |
523 | if (mm->binfmt) | ||
524 | module_put(mm->binfmt->module); | ||
514 | mmdrop(mm); | 525 | mmdrop(mm); |
515 | } | 526 | } |
516 | } | 527 | } |
@@ -561,12 +572,18 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm) | |||
561 | 572 | ||
562 | /* Get rid of any futexes when releasing the mm */ | 573 | /* Get rid of any futexes when releasing the mm */ |
563 | #ifdef CONFIG_FUTEX | 574 | #ifdef CONFIG_FUTEX |
564 | if (unlikely(tsk->robust_list)) | 575 | if (unlikely(tsk->robust_list)) { |
565 | exit_robust_list(tsk); | 576 | exit_robust_list(tsk); |
577 | tsk->robust_list = NULL; | ||
578 | } | ||
566 | #ifdef CONFIG_COMPAT | 579 | #ifdef CONFIG_COMPAT |
567 | if (unlikely(tsk->compat_robust_list)) | 580 | if (unlikely(tsk->compat_robust_list)) { |
568 | compat_exit_robust_list(tsk); | 581 | compat_exit_robust_list(tsk); |
582 | tsk->compat_robust_list = NULL; | ||
583 | } | ||
569 | #endif | 584 | #endif |
585 | if (unlikely(!list_empty(&tsk->pi_state_list))) | ||
586 | exit_pi_state_list(tsk); | ||
570 | #endif | 587 | #endif |
571 | 588 | ||
572 | /* Get rid of any cached register state */ | 589 | /* Get rid of any cached register state */ |
@@ -636,9 +653,14 @@ struct mm_struct *dup_mm(struct task_struct *tsk) | |||
636 | mm->hiwater_rss = get_mm_rss(mm); | 653 | mm->hiwater_rss = get_mm_rss(mm); |
637 | mm->hiwater_vm = mm->total_vm; | 654 | mm->hiwater_vm = mm->total_vm; |
638 | 655 | ||
656 | if (mm->binfmt && !try_module_get(mm->binfmt->module)) | ||
657 | goto free_pt; | ||
658 | |||
639 | return mm; | 659 | return mm; |
640 | 660 | ||
641 | free_pt: | 661 | free_pt: |
662 | /* don't put binfmt in mmput, we haven't got module yet */ | ||
663 | mm->binfmt = NULL; | ||
642 | mmput(mm); | 664 | mmput(mm); |
643 | 665 | ||
644 | fail_nomem: | 666 | fail_nomem: |
@@ -864,6 +886,9 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | |||
864 | sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero; | 886 | sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero; |
865 | sig->gtime = cputime_zero; | 887 | sig->gtime = cputime_zero; |
866 | sig->cgtime = cputime_zero; | 888 | sig->cgtime = cputime_zero; |
889 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING | ||
890 | sig->prev_utime = sig->prev_stime = cputime_zero; | ||
891 | #endif | ||
867 | sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; | 892 | sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; |
868 | sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; | 893 | sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; |
869 | sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; | 894 | sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; |
@@ -914,9 +939,9 @@ SYSCALL_DEFINE1(set_tid_address, int __user *, tidptr) | |||
914 | 939 | ||
915 | static void rt_mutex_init_task(struct task_struct *p) | 940 | static void rt_mutex_init_task(struct task_struct *p) |
916 | { | 941 | { |
917 | spin_lock_init(&p->pi_lock); | 942 | raw_spin_lock_init(&p->pi_lock); |
918 | #ifdef CONFIG_RT_MUTEXES | 943 | #ifdef CONFIG_RT_MUTEXES |
919 | plist_head_init(&p->pi_waiters, &p->pi_lock); | 944 | plist_head_init_raw(&p->pi_waiters, &p->pi_lock); |
920 | p->pi_blocked_on = NULL; | 945 | p->pi_blocked_on = NULL; |
921 | #endif | 946 | #endif |
922 | } | 947 | } |
@@ -979,6 +1004,16 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
979 | if ((clone_flags & CLONE_SIGHAND) && !(clone_flags & CLONE_VM)) | 1004 | if ((clone_flags & CLONE_SIGHAND) && !(clone_flags & CLONE_VM)) |
980 | return ERR_PTR(-EINVAL); | 1005 | return ERR_PTR(-EINVAL); |
981 | 1006 | ||
1007 | /* | ||
1008 | * Siblings of global init remain as zombies on exit since they are | ||
1009 | * not reaped by their parent (swapper). To solve this and to avoid | ||
1010 | * multi-rooted process trees, prevent global and container-inits | ||
1011 | * from creating siblings. | ||
1012 | */ | ||
1013 | if ((clone_flags & CLONE_PARENT) && | ||
1014 | current->signal->flags & SIGNAL_UNKILLABLE) | ||
1015 | return ERR_PTR(-EINVAL); | ||
1016 | |||
982 | retval = security_task_create(clone_flags); | 1017 | retval = security_task_create(clone_flags); |
983 | if (retval) | 1018 | if (retval) |
984 | goto fork_out; | 1019 | goto fork_out; |
@@ -1020,9 +1055,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1020 | if (!try_module_get(task_thread_info(p)->exec_domain->module)) | 1055 | if (!try_module_get(task_thread_info(p)->exec_domain->module)) |
1021 | goto bad_fork_cleanup_count; | 1056 | goto bad_fork_cleanup_count; |
1022 | 1057 | ||
1023 | if (p->binfmt && !try_module_get(p->binfmt->module)) | ||
1024 | goto bad_fork_cleanup_put_domain; | ||
1025 | |||
1026 | p->did_exec = 0; | 1058 | p->did_exec = 0; |
1027 | delayacct_tsk_init(p); /* Must remain after dup_task_struct() */ | 1059 | delayacct_tsk_init(p); /* Must remain after dup_task_struct() */ |
1028 | copy_flags(clone_flags, p); | 1060 | copy_flags(clone_flags, p); |
@@ -1039,8 +1071,10 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1039 | p->gtime = cputime_zero; | 1071 | p->gtime = cputime_zero; |
1040 | p->utimescaled = cputime_zero; | 1072 | p->utimescaled = cputime_zero; |
1041 | p->stimescaled = cputime_zero; | 1073 | p->stimescaled = cputime_zero; |
1074 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING | ||
1042 | p->prev_utime = cputime_zero; | 1075 | p->prev_utime = cputime_zero; |
1043 | p->prev_stime = cputime_zero; | 1076 | p->prev_stime = cputime_zero; |
1077 | #endif | ||
1044 | 1078 | ||
1045 | p->default_timer_slack_ns = current->timer_slack_ns; | 1079 | p->default_timer_slack_ns = current->timer_slack_ns; |
1046 | 1080 | ||
@@ -1093,6 +1127,10 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1093 | #ifdef CONFIG_DEBUG_MUTEXES | 1127 | #ifdef CONFIG_DEBUG_MUTEXES |
1094 | p->blocked_on = NULL; /* not blocked yet */ | 1128 | p->blocked_on = NULL; /* not blocked yet */ |
1095 | #endif | 1129 | #endif |
1130 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR | ||
1131 | p->memcg_batch.do_batch = 0; | ||
1132 | p->memcg_batch.memcg = NULL; | ||
1133 | #endif | ||
1096 | 1134 | ||
1097 | p->bts = NULL; | 1135 | p->bts = NULL; |
1098 | 1136 | ||
@@ -1172,9 +1210,10 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1172 | p->sas_ss_sp = p->sas_ss_size = 0; | 1210 | p->sas_ss_sp = p->sas_ss_size = 0; |
1173 | 1211 | ||
1174 | /* | 1212 | /* |
1175 | * Syscall tracing should be turned off in the child regardless | 1213 | * Syscall tracing and stepping should be turned off in the |
1176 | * of CLONE_PTRACE. | 1214 | * child regardless of CLONE_PTRACE. |
1177 | */ | 1215 | */ |
1216 | user_disable_single_step(p); | ||
1178 | clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE); | 1217 | clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE); |
1179 | #ifdef TIF_SYSCALL_EMU | 1218 | #ifdef TIF_SYSCALL_EMU |
1180 | clear_tsk_thread_flag(p, TIF_SYSCALL_EMU); | 1219 | clear_tsk_thread_flag(p, TIF_SYSCALL_EMU); |
@@ -1283,7 +1322,8 @@ bad_fork_free_pid: | |||
1283 | if (pid != &init_struct_pid) | 1322 | if (pid != &init_struct_pid) |
1284 | free_pid(pid); | 1323 | free_pid(pid); |
1285 | bad_fork_cleanup_io: | 1324 | bad_fork_cleanup_io: |
1286 | put_io_context(p->io_context); | 1325 | if (p->io_context) |
1326 | exit_io_context(p); | ||
1287 | bad_fork_cleanup_namespaces: | 1327 | bad_fork_cleanup_namespaces: |
1288 | exit_task_namespaces(p); | 1328 | exit_task_namespaces(p); |
1289 | bad_fork_cleanup_mm: | 1329 | bad_fork_cleanup_mm: |
@@ -1310,9 +1350,6 @@ bad_fork_cleanup_cgroup: | |||
1310 | #endif | 1350 | #endif |
1311 | cgroup_exit(p, cgroup_callbacks_done); | 1351 | cgroup_exit(p, cgroup_callbacks_done); |
1312 | delayacct_tsk_free(p); | 1352 | delayacct_tsk_free(p); |
1313 | if (p->binfmt) | ||
1314 | module_put(p->binfmt->module); | ||
1315 | bad_fork_cleanup_put_domain: | ||
1316 | module_put(task_thread_info(p)->exec_domain->module); | 1353 | module_put(task_thread_info(p)->exec_domain->module); |
1317 | bad_fork_cleanup_count: | 1354 | bad_fork_cleanup_count: |
1318 | atomic_dec(&p->cred->user->processes); | 1355 | atomic_dec(&p->cred->user->processes); |