signal: Introduce TRAP_PERF si_code and si_perf to siginfo
authorMarco Elver <elver@google.com>
Thu, 8 Apr 2021 10:36:00 +0000 (12:36 +0200)
committerPeter Zijlstra <peterz@infradead.org>
Fri, 16 Apr 2021 14:32:41 +0000 (16:32 +0200)
Introduces the TRAP_PERF si_code, and associated siginfo_t field
si_perf. These will be used by the perf event subsystem to send signals
(if requested) to the task where an event occurred.

Signed-off-by: Marco Elver <elver@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org> # m68k
Acked-by: Arnd Bergmann <arnd@arndb.de> # asm-generic
Link: https://lkml.kernel.org/r/20210408103605.1676875-6-elver@google.com
arch/m68k/kernel/signal.c
arch/x86/kernel/signal_compat.c
fs/signalfd.c
include/linux/compat.h
include/linux/signal.h
include/uapi/asm-generic/siginfo.h
include/uapi/linux/signalfd.h
kernel/signal.c

index 349570f16a7869b6725a562974f64ebe3741afd5..a4b7ee1df211936ca569b673b9efe693f2ebd0af 100644 (file)
@@ -622,6 +622,9 @@ static inline void siginfo_build_tests(void)
        /* _sigfault._addr_pkey */
        BUILD_BUG_ON(offsetof(siginfo_t, si_pkey) != 0x12);
 
+       /* _sigfault._perf */
+       BUILD_BUG_ON(offsetof(siginfo_t, si_perf) != 0x10);
+
        /* _sigpoll */
        BUILD_BUG_ON(offsetof(siginfo_t, si_band)   != 0x0c);
        BUILD_BUG_ON(offsetof(siginfo_t, si_fd)     != 0x10);
index a5330ff498f04583e90b9c11f48afe348a2b92d3..0e5d0a7e203b36f5b6171cde4b4207ee67cbb32c 100644 (file)
@@ -29,7 +29,7 @@ static inline void signal_compat_build_tests(void)
        BUILD_BUG_ON(NSIGFPE  != 15);
        BUILD_BUG_ON(NSIGSEGV != 9);
        BUILD_BUG_ON(NSIGBUS  != 5);
-       BUILD_BUG_ON(NSIGTRAP != 5);
+       BUILD_BUG_ON(NSIGTRAP != 6);
        BUILD_BUG_ON(NSIGCHLD != 6);
        BUILD_BUG_ON(NSIGSYS  != 2);
 
@@ -138,6 +138,9 @@ static inline void signal_compat_build_tests(void)
        BUILD_BUG_ON(offsetof(siginfo_t, si_pkey) != 0x20);
        BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pkey) != 0x14);
 
+       BUILD_BUG_ON(offsetof(siginfo_t, si_perf) != 0x18);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf) != 0x10);
+
        CHECK_CSI_OFFSET(_sigpoll);
        CHECK_CSI_SIZE  (_sigpoll, 2*sizeof(int));
        CHECK_SI_SIZE   (_sigpoll, 4*sizeof(int));
index 456046e158737450055c77283321867f03b23ee0..040a1142915fcd494dfb39c6ba036279c7492de1 100644 (file)
@@ -134,6 +134,10 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
 #endif
                new.ssi_addr_lsb = (short) kinfo->si_addr_lsb;
                break;
+       case SIL_PERF_EVENT:
+               new.ssi_addr = (long) kinfo->si_addr;
+               new.ssi_perf = kinfo->si_perf;
+               break;
        case SIL_CHLD:
                new.ssi_pid    = kinfo->si_pid;
                new.ssi_uid    = kinfo->si_uid;
index 6e65be75360321444993b4f58df13d4d9fb04562..c8821d966812764f880d6ea6d21676bd4314bf39 100644 (file)
@@ -236,6 +236,8 @@ typedef struct compat_siginfo {
                                        char _dummy_pkey[__COMPAT_ADDR_BND_PKEY_PAD];
                                        u32 _pkey;
                                } _addr_pkey;
+                               /* used when si_code=TRAP_PERF */
+                               compat_u64 _perf;
                        };
                } _sigfault;
 
index 205526c4003aa10dba00560af3820b748928afe2..1e98548d7cf6852564204ee85c116190621dbf93 100644 (file)
@@ -43,6 +43,7 @@ enum siginfo_layout {
        SIL_FAULT_MCEERR,
        SIL_FAULT_BNDERR,
        SIL_FAULT_PKUERR,
+       SIL_PERF_EVENT,
        SIL_CHLD,
        SIL_RT,
        SIL_SYS,
index d2597000407a3daac1c357abb2d50d933d2d22ea..d0bb9125c8535925e4d280493a3223b41586e928 100644 (file)
@@ -91,6 +91,8 @@ union __sifields {
                                char _dummy_pkey[__ADDR_BND_PKEY_PAD];
                                __u32 _pkey;
                        } _addr_pkey;
+                       /* used when si_code=TRAP_PERF */
+                       __u64 _perf;
                };
        } _sigfault;
 
@@ -155,6 +157,7 @@ typedef struct siginfo {
 #define si_lower       _sifields._sigfault._addr_bnd._lower
 #define si_upper       _sifields._sigfault._addr_bnd._upper
 #define si_pkey                _sifields._sigfault._addr_pkey._pkey
+#define si_perf                _sifields._sigfault._perf
 #define si_band                _sifields._sigpoll._band
 #define si_fd          _sifields._sigpoll._fd
 #define si_call_addr   _sifields._sigsys._call_addr
@@ -253,7 +256,8 @@ typedef struct siginfo {
 #define TRAP_BRANCH     3      /* process taken branch trap */
 #define TRAP_HWBKPT     4      /* hardware breakpoint/watchpoint */
 #define TRAP_UNK       5       /* undiagnosed trap */
-#define NSIGTRAP       5
+#define TRAP_PERF      6       /* perf event with sigtrap=1 */
+#define NSIGTRAP       6
 
 /*
  * There is an additional set of SIGTRAP si_codes used by ptrace
index 83429a05b698e32fcc9be74827577058a5aec974..7e333042c7e3a1e2522f7146c4eb7021fbe7c288 100644 (file)
@@ -39,6 +39,8 @@ struct signalfd_siginfo {
        __s32 ssi_syscall;
        __u64 ssi_call_addr;
        __u32 ssi_arch;
+       __u32 __pad3;
+       __u64 ssi_perf;
 
        /*
         * Pad strcture to 128 bytes. Remember to update the
@@ -49,7 +51,7 @@ struct signalfd_siginfo {
         * comes out of a read(2) and we really don't want to have
         * a compat on read(2).
         */
-       __u8 __pad[28];
+       __u8 __pad[16];
 };
 
 
index ba4d1ef39a9ead9847985954c8edb3629114eb6d..f68351825e5edc585db37288d51fd7a7d8649f82 100644 (file)
@@ -1199,6 +1199,7 @@ static inline bool has_si_pid_and_uid(struct kernel_siginfo *info)
        case SIL_FAULT_MCEERR:
        case SIL_FAULT_BNDERR:
        case SIL_FAULT_PKUERR:
+       case SIL_PERF_EVENT:
        case SIL_SYS:
                ret = false;
                break;
@@ -2531,6 +2532,7 @@ static void hide_si_addr_tag_bits(struct ksignal *ksig)
        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;
@@ -3333,6 +3335,10 @@ void copy_siginfo_to_external32(struct compat_siginfo *to,
 #endif
                to->si_pkey = from->si_pkey;
                break;
+       case SIL_PERF_EVENT:
+               to->si_addr = ptr_to_compat(from->si_addr);
+               to->si_perf = from->si_perf;
+               break;
        case SIL_CHLD:
                to->si_pid = from->si_pid;
                to->si_uid = from->si_uid;
@@ -3413,6 +3419,10 @@ static int post_copy_siginfo_from_user32(kernel_siginfo_t *to,
 #endif
                to->si_pkey = from->si_pkey;
                break;
+       case SIL_PERF_EVENT:
+               to->si_addr = compat_ptr(from->si_addr);
+               to->si_perf = from->si_perf;
+               break;
        case SIL_CHLD:
                to->si_pid    = from->si_pid;
                to->si_uid    = from->si_uid;
@@ -4593,6 +4603,7 @@ static inline void siginfo_buildtime_checks(void)
        CHECK_OFFSET(si_lower);
        CHECK_OFFSET(si_upper);
        CHECK_OFFSET(si_pkey);
+       CHECK_OFFSET(si_perf);
 
        /* sigpoll */
        CHECK_OFFSET(si_band);