Merge tag 'core-entry-notify-signal' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / kernel / signal.c
index ef8f2a28d37c525b0994701448c026469a533259..923230ff6cfca856453d4856c76c59ac03d68430 100644 (file)
@@ -984,7 +984,7 @@ static inline bool wants_signal(int sig, struct task_struct *p)
        if (task_is_stopped_or_traced(p))
                return false;
 
-       return task_curr(p) || !signal_pending(p);
+       return task_curr(p) || !task_sigpending(p);
 }
 
 static void complete_signal(int sig, struct task_struct *p, enum pid_type type)
@@ -2530,6 +2530,20 @@ bool get_signal(struct ksignal *ksig)
        struct signal_struct *signal = current->signal;
        int signr;
 
+       /*
+        * For non-generic architectures, check for TIF_NOTIFY_SIGNAL so
+        * that the arch handlers don't all have to do it. If we get here
+        * without TIF_SIGPENDING, just exit after running signal work.
+        */
+#ifdef TIF_NOTIFY_SIGNAL
+       if (!IS_ENABLED(CONFIG_GENERIC_ENTRY)) {
+               if (test_thread_flag(TIF_NOTIFY_SIGNAL))
+                       tracehook_notify_signal();
+               if (!task_sigpending(current))
+                       return false;
+       }
+#endif
+
        if (unlikely(uprobe_deny_signal()))
                return false;
 
@@ -2823,7 +2837,7 @@ static void retarget_shared_pending(struct task_struct *tsk, sigset_t *which)
                /* Remove the signals this thread can handle. */
                sigandsets(&retarget, &retarget, &t->blocked);
 
-               if (!signal_pending(t))
+               if (!task_sigpending(t))
                        signal_wake_up(t, 0);
 
                if (sigisemptyset(&retarget))
@@ -2857,7 +2871,7 @@ void exit_signals(struct task_struct *tsk)
 
        cgroup_threadgroup_change_end(tsk);
 
-       if (!signal_pending(tsk))
+       if (!task_sigpending(tsk))
                goto out;
 
        unblocked = tsk->blocked;
@@ -2901,7 +2915,7 @@ long do_no_restart_syscall(struct restart_block *param)
 
 static void __set_task_blocked(struct task_struct *tsk, const sigset_t *newset)
 {
-       if (signal_pending(tsk) && !thread_group_empty(tsk)) {
+       if (task_sigpending(tsk) && !thread_group_empty(tsk)) {
                sigset_t newblocked;
                /* A set of now blocked but previously unblocked signals. */
                sigandnsets(&newblocked, newset, &current->blocked);