dt-bindings: Revert "dt-bindings: soc: grf: add naneng combo phy register compatible"
[linux-2.6-microblaze.git] / kernel / signal.c
index dfcee38..3860273 100644 (file)
@@ -626,7 +626,8 @@ static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
  *
  * All callers have to hold the siglock.
  */
-int dequeue_signal(struct task_struct *tsk, sigset_t *mask, kernel_siginfo_t *info)
+int dequeue_signal(struct task_struct *tsk, sigset_t *mask,
+                  kernel_siginfo_t *info, enum pid_type *type)
 {
        bool resched_timer = false;
        int signr;
@@ -634,8 +635,10 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, kernel_siginfo_t *in
        /* We only dequeue private signals from ourselves, we don't let
         * signalfd steal them
         */
+       *type = PIDTYPE_PID;
        signr = __dequeue_signal(&tsk->pending, mask, info, &resched_timer);
        if (!signr) {
+               *type = PIDTYPE_TGID;
                signr = __dequeue_signal(&tsk->signal->shared_pending,
                                         mask, info, &resched_timer);
 #ifdef CONFIG_POSIX_TIMERS
@@ -903,8 +906,8 @@ static bool prepare_signal(int sig, struct task_struct *p, bool force)
        struct task_struct *t;
        sigset_t flush;
 
-       if (signal->flags & (SIGNAL_GROUP_EXIT | SIGNAL_GROUP_COREDUMP)) {
-               if (!(signal->flags & SIGNAL_GROUP_EXIT))
+       if (signal->flags & SIGNAL_GROUP_EXIT) {
+               if (signal->core_state)
                        return sig == SIGKILL;
                /*
                 * The process is in the middle of dying, nothing to do.
@@ -1029,7 +1032,7 @@ static void complete_signal(int sig, struct task_struct *p, enum pid_type type)
         * then start taking the whole group down immediately.
         */
        if (sig_fatal(p, sig) &&
-           !(signal->flags & SIGNAL_GROUP_EXIT) &&
+           (signal->core_state || !(signal->flags & SIGNAL_GROUP_EXIT)) &&
            !sigismember(&t->real_blocked, sig) &&
            (sig == SIGKILL || !p->ptrace)) {
                /*
@@ -1820,6 +1823,7 @@ int force_sig_perf(void __user *addr, u32 type, u64 sig_data)
  * force_sig_seccomp - signals the task to allow in-process syscall emulation
  * @syscall: syscall number to send to userland
  * @reason: filter-supplied reason code to send to userland (via si_errno)
+ * @force_coredump: true to trigger a coredump
  *
  * Forces a SIGSYS with a code of SYS_SECCOMP and related sigsys info.
  */
@@ -2383,7 +2387,8 @@ static bool do_signal_stop(int signr)
                WARN_ON_ONCE(signr & ~JOBCTL_STOP_SIGMASK);
 
                if (!likely(current->jobctl & JOBCTL_STOP_DEQUEUED) ||
-                   unlikely(signal_group_exit(sig)))
+                   unlikely(sig->flags & SIGNAL_GROUP_EXIT) ||
+                   unlikely(sig->group_exec_task))
                        return false;
                /*
                 * There is no group stop already in progress.  We must
@@ -2544,7 +2549,7 @@ static void do_freezer_trap(void)
        freezable_schedule();
 }
 
-static int ptrace_signal(int signr, kernel_siginfo_t *info)
+static int ptrace_signal(int signr, kernel_siginfo_t *info, enum pid_type type)
 {
        /*
         * We do not check sig_kernel_stop(signr) but set this marker
@@ -2584,8 +2589,9 @@ static int ptrace_signal(int signr, kernel_siginfo_t *info)
        }
 
        /* If the (new) signal is now blocked, requeue it.  */
-       if (sigismember(&current->blocked, signr)) {
-               send_signal(signr, info, current, PIDTYPE_PID);
+       if (sigismember(&current->blocked, signr) ||
+           fatal_signal_pending(current)) {
+               send_signal(signr, info, current, type);
                signr = 0;
        }
 
@@ -2684,18 +2690,20 @@ relock:
                goto relock;
        }
 
-       /* Has this task already been marked for death? */
-       if (signal_group_exit(signal)) {
-               ksig->info.si_signo = signr = SIGKILL;
-               sigdelset(&current->pending.signal, SIGKILL);
-               trace_signal_deliver(SIGKILL, SEND_SIG_NOINFO,
-                               &sighand->action[SIGKILL - 1]);
-               recalc_sigpending();
-               goto fatal;
-       }
-
        for (;;) {
                struct k_sigaction *ka;
+               enum pid_type type;
+
+               /* Has this task already been marked for death? */
+               if ((signal->flags & SIGNAL_GROUP_EXIT) ||
+                    signal->group_exec_task) {
+                       ksig->info.si_signo = signr = SIGKILL;
+                       sigdelset(&current->pending.signal, SIGKILL);
+                       trace_signal_deliver(SIGKILL, SEND_SIG_NOINFO,
+                               &sighand->action[SIGKILL - 1]);
+                       recalc_sigpending();
+                       goto fatal;
+               }
 
                if (unlikely(current->jobctl & JOBCTL_STOP_PENDING) &&
                    do_signal_stop(0))
@@ -2728,16 +2736,18 @@ relock:
                 * so that the instruction pointer in the signal stack
                 * frame points to the faulting instruction.
                 */
+               type = PIDTYPE_PID;
                signr = dequeue_synchronous_signal(&ksig->info);
                if (!signr)
-                       signr = dequeue_signal(current, &current->blocked, &ksig->info);
+                       signr = dequeue_signal(current, &current->blocked,
+                                              &ksig->info, &type);
 
                if (!signr)
                        break; /* will return 0 */
 
                if (unlikely(current->ptrace) && (signr != SIGKILL) &&
                    !(sighand->action[signr -1].sa.sa_flags & SA_IMMUTABLE)) {
-                       signr = ptrace_signal(signr, &ksig->info);
+                       signr = ptrace_signal(signr, &ksig->info, type);
                        if (!signr)
                                continue;
                }
@@ -2863,13 +2873,13 @@ out:
 }
 
 /**
- * signal_delivered - 
+ * signal_delivered - called after signal delivery to update blocked signals
  * @ksig:              kernel signal struct
  * @stepping:          nonzero if debugger single-step or block-step in use
  *
  * This function should be called when a signal has successfully been
  * delivered. It updates the blocked signals accordingly (@ksig->ka.sa.sa_mask
- * is always blocked, and the signal itself is blocked unless %SA_NODEFER
+ * is always blocked), and the signal itself is blocked unless %SA_NODEFER
  * is set in @ksig->ka.sa.sa_flags.  Tracing is notified.
  */
 static void signal_delivered(struct ksignal *ksig, int stepping)
@@ -2942,7 +2952,7 @@ void exit_signals(struct task_struct *tsk)
         */
        cgroup_threadgroup_change_begin(tsk);
 
-       if (thread_group_empty(tsk) || signal_group_exit(tsk->signal)) {
+       if (thread_group_empty(tsk) || (tsk->signal->flags & SIGNAL_GROUP_EXIT)) {
                tsk->flags |= PF_EXITING;
                cgroup_threadgroup_change_end(tsk);
                return;
@@ -3562,6 +3572,7 @@ static int do_sigtimedwait(const sigset_t *which, kernel_siginfo_t *info,
        ktime_t *to = NULL, timeout = KTIME_MAX;
        struct task_struct *tsk = current;
        sigset_t mask = *which;
+       enum pid_type type;
        int sig, ret = 0;
 
        if (ts) {
@@ -3578,7 +3589,7 @@ static int do_sigtimedwait(const sigset_t *which, kernel_siginfo_t *info,
        signotset(&mask);
 
        spin_lock_irq(&tsk->sighand->siglock);
-       sig = dequeue_signal(tsk, &mask, info);
+       sig = dequeue_signal(tsk, &mask, info, &type);
        if (!sig && timeout) {
                /*
                 * None ready, temporarily unblock those we're interested
@@ -3597,7 +3608,7 @@ static int do_sigtimedwait(const sigset_t *which, kernel_siginfo_t *info,
                spin_lock_irq(&tsk->sighand->siglock);
                __set_task_blocked(tsk, &tsk->real_blocked);
                sigemptyset(&tsk->real_blocked);
-               sig = dequeue_signal(tsk, &mask, info);
+               sig = dequeue_signal(tsk, &mask, info, &type);
        }
        spin_unlock_irq(&tsk->sighand->siglock);