Merge tag 'devicetree-fixes-for-5.13-2' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / kernel / signal.c
index f271835..f7c6ffc 100644 (file)
@@ -43,7 +43,6 @@
 #include <linux/cn_proc.h>
 #include <linux/compiler.h>
 #include <linux/posix-timers.h>
-#include <linux/livepatch.h>
 #include <linux/cgroup.h>
 #include <linux/audit.h>
 
@@ -181,8 +180,7 @@ void recalc_sigpending_and_wake(struct task_struct *t)
 
 void recalc_sigpending(void)
 {
-       if (!recalc_sigpending_tsk(current) && !freezing(current) &&
-           !klp_patch_pending(current))
+       if (!recalc_sigpending_tsk(current) && !freezing(current))
                clear_thread_flag(TIF_SIGPENDING);
 
 }
@@ -410,7 +408,8 @@ void task_join_group_stop(struct task_struct *task)
  *   appropriate lock must be held to stop the target task from exiting
  */
 static struct sigqueue *
-__sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimit)
+__sigqueue_alloc(int sig, struct task_struct *t, gfp_t gfp_flags,
+                int override_rlimit, const unsigned int sigqueue_flags)
 {
        struct sigqueue *q = NULL;
        struct user_struct *user;
@@ -432,7 +431,16 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi
        rcu_read_unlock();
 
        if (override_rlimit || likely(sigpending <= task_rlimit(t, RLIMIT_SIGPENDING))) {
-               q = kmem_cache_alloc(sigqueue_cachep, flags);
+               /*
+                * Preallocation does not hold sighand::siglock so it can't
+                * use the cache. The lockless caching requires that only
+                * one consumer and only one producer run at a time.
+                */
+               q = READ_ONCE(t->sigqueue_cache);
+               if (!q || sigqueue_flags)
+                       q = kmem_cache_alloc(sigqueue_cachep, gfp_flags);
+               else
+                       WRITE_ONCE(t->sigqueue_cache, NULL);
        } else {
                print_dropped_signal(sig);
        }
@@ -442,20 +450,51 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi
                        free_uid(user);
        } else {
                INIT_LIST_HEAD(&q->list);
-               q->flags = 0;
+               q->flags = sigqueue_flags;
                q->user = user;
        }
 
        return q;
 }
 
+void exit_task_sigqueue_cache(struct task_struct *tsk)
+{
+       /* Race free because @tsk is mopped up */
+       struct sigqueue *q = tsk->sigqueue_cache;
+
+       if (q) {
+               tsk->sigqueue_cache = NULL;
+               /*
+                * Hand it back to the cache as the task might
+                * be self reaping which would leak the object.
+                */
+                kmem_cache_free(sigqueue_cachep, q);
+       }
+}
+
+static void sigqueue_cache_or_free(struct sigqueue *q)
+{
+       /*
+        * Cache one sigqueue per task. This pairs with the consumer side
+        * in __sigqueue_alloc() and needs READ/WRITE_ONCE() to prevent the
+        * compiler from store tearing and to tell KCSAN that the data race
+        * is intentional when run without holding current->sighand->siglock,
+        * which is fine as current obviously cannot run __sigqueue_free()
+        * concurrently.
+        */
+       if (!READ_ONCE(current->sigqueue_cache))
+               WRITE_ONCE(current->sigqueue_cache, q);
+       else
+               kmem_cache_free(sigqueue_cachep, q);
+}
+
 static void __sigqueue_free(struct sigqueue *q)
 {
        if (q->flags & SIGQUEUE_PREALLOC)
                return;
        if (atomic_dec_and_test(&q->user->sigpending))
                free_uid(q->user);
-       kmem_cache_free(sigqueue_cachep, q);
+       sigqueue_cache_or_free(q);
 }
 
 void flush_sigqueue(struct sigpending *queue)
@@ -1113,7 +1152,8 @@ static int __send_signal(int sig, struct kernel_siginfo *info, struct task_struc
        else
                override_rlimit = 0;
 
-       q = __sigqueue_alloc(sig, t, GFP_ATOMIC, override_rlimit);
+       q = __sigqueue_alloc(sig, t, GFP_ATOMIC, override_rlimit, 0);
+
        if (q) {
                list_add_tail(&q->list, &pending->list);
                switch ((unsigned long) info) {
@@ -1196,9 +1236,11 @@ static inline bool has_si_pid_and_uid(struct kernel_siginfo *info)
        case SIL_TIMER:
        case SIL_POLL:
        case SIL_FAULT:
+       case SIL_FAULT_TRAPNO:
        case SIL_FAULT_MCEERR:
        case SIL_FAULT_BNDERR:
        case SIL_FAULT_PKUERR:
+       case SIL_PERF_EVENT:
        case SIL_SYS:
                ret = false;
                break;
@@ -1763,6 +1805,21 @@ int force_sig_pkuerr(void __user *addr, u32 pkey)
 }
 #endif
 
+int force_sig_perf(void __user *addr, u32 type, u64 sig_data)
+{
+       struct kernel_siginfo info;
+
+       clear_siginfo(&info);
+       info.si_signo     = SIGTRAP;
+       info.si_errno     = 0;
+       info.si_code      = TRAP_PERF;
+       info.si_addr      = addr;
+       info.si_perf_data = sig_data;
+       info.si_perf_type = type;
+
+       return force_sig_info(&info);
+}
+
 /* For the crazy architectures that include trap information in
  * the errno field, instead of an actual errno value.
  */
@@ -1807,12 +1864,7 @@ EXPORT_SYMBOL(kill_pid);
  */
 struct sigqueue *sigqueue_alloc(void)
 {
-       struct sigqueue *q = __sigqueue_alloc(-1, current, GFP_KERNEL, 0);
-
-       if (q)
-               q->flags |= SIGQUEUE_PREALLOC;
-
-       return q;
+       return __sigqueue_alloc(-1, current, GFP_KERNEL, 0, SIGQUEUE_PREALLOC);
 }
 
 void sigqueue_free(struct sigqueue *q)
@@ -2528,9 +2580,11 @@ static void hide_si_addr_tag_bits(struct ksignal *ksig)
 {
        switch (siginfo_layout(ksig->sig, ksig->info.si_code)) {
        case SIL_FAULT:
+       case SIL_FAULT_TRAPNO:
        case SIL_FAULT_MCEERR:
        case SIL_FAULT_BNDERR:
        case SIL_FAULT_PKUERR:
+       case SIL_PERF_EVENT:
                ksig->info.si_addr = arch_untagged_si_addr(
                        ksig->info.si_addr, ksig->sig, ksig->info.si_code);
                break;
@@ -3211,6 +3265,12 @@ enum siginfo_layout siginfo_layout(unsigned sig, int si_code)
 #ifdef SEGV_PKUERR
                        else if ((sig == SIGSEGV) && (si_code == SEGV_PKUERR))
                                layout = SIL_FAULT_PKUERR;
+#endif
+                       else if ((sig == SIGTRAP) && (si_code == TRAP_PERF))
+                               layout = SIL_PERF_EVENT;
+#ifdef __ARCH_SI_TRAPNO
+                       else if (layout == SIL_FAULT)
+                               layout = SIL_FAULT_TRAPNO;
 #endif
                }
                else if (si_code <= NSIGPOLL)
@@ -3315,32 +3375,29 @@ void copy_siginfo_to_external32(struct compat_siginfo *to,
                break;
        case SIL_FAULT:
                to->si_addr = ptr_to_compat(from->si_addr);
-#ifdef __ARCH_SI_TRAPNO
+               break;
+       case SIL_FAULT_TRAPNO:
+               to->si_addr = ptr_to_compat(from->si_addr);
                to->si_trapno = from->si_trapno;
-#endif
                break;
        case SIL_FAULT_MCEERR:
                to->si_addr = ptr_to_compat(from->si_addr);
-#ifdef __ARCH_SI_TRAPNO
-               to->si_trapno = from->si_trapno;
-#endif
                to->si_addr_lsb = from->si_addr_lsb;
                break;
        case SIL_FAULT_BNDERR:
                to->si_addr = ptr_to_compat(from->si_addr);
-#ifdef __ARCH_SI_TRAPNO
-               to->si_trapno = from->si_trapno;
-#endif
                to->si_lower = ptr_to_compat(from->si_lower);
                to->si_upper = ptr_to_compat(from->si_upper);
                break;
        case SIL_FAULT_PKUERR:
                to->si_addr = ptr_to_compat(from->si_addr);
-#ifdef __ARCH_SI_TRAPNO
-               to->si_trapno = from->si_trapno;
-#endif
                to->si_pkey = from->si_pkey;
                break;
+       case SIL_PERF_EVENT:
+               to->si_addr = ptr_to_compat(from->si_addr);
+               to->si_perf_data = from->si_perf_data;
+               to->si_perf_type = from->si_perf_type;
+               break;
        case SIL_CHLD:
                to->si_pid = from->si_pid;
                to->si_uid = from->si_uid;
@@ -3395,32 +3452,29 @@ static int post_copy_siginfo_from_user32(kernel_siginfo_t *to,
                break;
        case SIL_FAULT:
                to->si_addr = compat_ptr(from->si_addr);
-#ifdef __ARCH_SI_TRAPNO
+               break;
+       case SIL_FAULT_TRAPNO:
+               to->si_addr = compat_ptr(from->si_addr);
                to->si_trapno = from->si_trapno;
-#endif
                break;
        case SIL_FAULT_MCEERR:
                to->si_addr = compat_ptr(from->si_addr);
-#ifdef __ARCH_SI_TRAPNO
-               to->si_trapno = from->si_trapno;
-#endif
                to->si_addr_lsb = from->si_addr_lsb;
                break;
        case SIL_FAULT_BNDERR:
                to->si_addr = compat_ptr(from->si_addr);
-#ifdef __ARCH_SI_TRAPNO
-               to->si_trapno = from->si_trapno;
-#endif
                to->si_lower = compat_ptr(from->si_lower);
                to->si_upper = compat_ptr(from->si_upper);
                break;
        case SIL_FAULT_PKUERR:
                to->si_addr = compat_ptr(from->si_addr);
-#ifdef __ARCH_SI_TRAPNO
-               to->si_trapno = from->si_trapno;
-#endif
                to->si_pkey = from->si_pkey;
                break;
+       case SIL_PERF_EVENT:
+               to->si_addr = compat_ptr(from->si_addr);
+               to->si_perf_data = from->si_perf_data;
+               to->si_perf_type = from->si_perf_type;
+               break;
        case SIL_CHLD:
                to->si_pid    = from->si_pid;
                to->si_uid    = from->si_uid;
@@ -4597,10 +4651,13 @@ static inline void siginfo_buildtime_checks(void)
 
        /* sigfault */
        CHECK_OFFSET(si_addr);
+       CHECK_OFFSET(si_trapno);
        CHECK_OFFSET(si_addr_lsb);
        CHECK_OFFSET(si_lower);
        CHECK_OFFSET(si_upper);
        CHECK_OFFSET(si_pkey);
+       CHECK_OFFSET(si_perf_data);
+       CHECK_OFFSET(si_perf_type);
 
        /* sigpoll */
        CHECK_OFFSET(si_band);