Merge branch 'akpm' (patches from Andrew)
[linux-2.6-microblaze.git] / kernel / exit.c
index 727150f..733e80f 100644 (file)
@@ -93,7 +93,7 @@ static void __exit_signal(struct task_struct *tsk)
        struct signal_struct *sig = tsk->signal;
        bool group_dead = thread_group_leader(tsk);
        struct sighand_struct *sighand;
-       struct tty_struct *uninitialized_var(tty);
+       struct tty_struct *tty;
        u64 utime, stime;
 
        sighand = rcu_dereference_check(tsk->sighand,
@@ -217,6 +217,7 @@ repeat:
        }
 
        write_unlock_irq(&tasklist_lock);
+       seccomp_filter_release(p);
        proc_flush_pid(thread_pid);
        put_pid(thread_pid);
        release_thread(p);
@@ -731,7 +732,7 @@ void __noreturn do_exit(long code)
         * mm_release()->clear_child_tid() from writing to a user-controlled
         * kernel address.
         */
-       set_fs(USER_DS);
+       force_uaccess_begin();
 
        if (unlikely(in_atomic())) {
                pr_info("note: %s[%d] exited with preempt_count %d\n",
@@ -804,7 +805,6 @@ void __noreturn do_exit(long code)
        exit_task_namespaces(tsk);
        exit_task_work(tsk);
        exit_thread(tsk);
-       exit_umh(tsk);
 
        /*
         * Flush inherited counters to the parent - before the parent
@@ -1626,6 +1626,22 @@ long kernel_wait4(pid_t upid, int __user *stat_addr, int options,
        return ret;
 }
 
+int kernel_wait(pid_t pid, int *stat)
+{
+       struct wait_opts wo = {
+               .wo_type        = PIDTYPE_PID,
+               .wo_pid         = find_get_pid(pid),
+               .wo_flags       = WEXITED,
+       };
+       int ret;
+
+       ret = do_wait(&wo);
+       if (ret > 0 && wo.wo_stat)
+               *stat = wo.wo_stat;
+       put_pid(wo.wo_pid);
+       return ret;
+}
+
 SYSCALL_DEFINE4(wait4, pid_t, upid, int __user *, stat_addr,
                int, options, struct rusage __user *, ru)
 {
@@ -1711,6 +1727,30 @@ Efault:
 }
 #endif
 
+/**
+ * thread_group_exited - check that a thread group has exited
+ * @pid: tgid of thread group to be checked.
+ *
+ * Test if the thread group represented by tgid has exited (all
+ * threads are zombies, dead or completely gone).
+ *
+ * Return: true if the thread group has exited. false otherwise.
+ */
+bool thread_group_exited(struct pid *pid)
+{
+       struct task_struct *task;
+       bool exited;
+
+       rcu_read_lock();
+       task = pid_task(pid, PIDTYPE_PID);
+       exited = !task ||
+               (READ_ONCE(task->exit_state) && thread_group_empty(task));
+       rcu_read_unlock();
+
+       return exited;
+}
+EXPORT_SYMBOL(thread_group_exited);
+
 __weak void abort(void)
 {
        BUG();