signal: Introduce TRAP_PERF si_code and si_perf to siginfo

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
This commit is contained in:
Marco Elver 2021-04-08 12:36:00 +02:00 коммит произвёл Peter Zijlstra
Родитель 2e498d0a74
Коммит fb6cc127e0
8 изменённых файлов: 33 добавлений и 3 удалений

Просмотреть файл

@ -622,6 +622,9 @@ static inline void siginfo_build_tests(void)
/* _sigfault._addr_pkey */ /* _sigfault._addr_pkey */
BUILD_BUG_ON(offsetof(siginfo_t, si_pkey) != 0x12); BUILD_BUG_ON(offsetof(siginfo_t, si_pkey) != 0x12);
/* _sigfault._perf */
BUILD_BUG_ON(offsetof(siginfo_t, si_perf) != 0x10);
/* _sigpoll */ /* _sigpoll */
BUILD_BUG_ON(offsetof(siginfo_t, si_band) != 0x0c); BUILD_BUG_ON(offsetof(siginfo_t, si_band) != 0x0c);
BUILD_BUG_ON(offsetof(siginfo_t, si_fd) != 0x10); BUILD_BUG_ON(offsetof(siginfo_t, si_fd) != 0x10);

Просмотреть файл

@ -29,7 +29,7 @@ static inline void signal_compat_build_tests(void)
BUILD_BUG_ON(NSIGFPE != 15); BUILD_BUG_ON(NSIGFPE != 15);
BUILD_BUG_ON(NSIGSEGV != 9); BUILD_BUG_ON(NSIGSEGV != 9);
BUILD_BUG_ON(NSIGBUS != 5); BUILD_BUG_ON(NSIGBUS != 5);
BUILD_BUG_ON(NSIGTRAP != 5); BUILD_BUG_ON(NSIGTRAP != 6);
BUILD_BUG_ON(NSIGCHLD != 6); BUILD_BUG_ON(NSIGCHLD != 6);
BUILD_BUG_ON(NSIGSYS != 2); 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(siginfo_t, si_pkey) != 0x20);
BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pkey) != 0x14); 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_OFFSET(_sigpoll);
CHECK_CSI_SIZE (_sigpoll, 2*sizeof(int)); CHECK_CSI_SIZE (_sigpoll, 2*sizeof(int));
CHECK_SI_SIZE (_sigpoll, 4*sizeof(int)); CHECK_SI_SIZE (_sigpoll, 4*sizeof(int));

Просмотреть файл

@ -134,6 +134,10 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
#endif #endif
new.ssi_addr_lsb = (short) kinfo->si_addr_lsb; new.ssi_addr_lsb = (short) kinfo->si_addr_lsb;
break; break;
case SIL_PERF_EVENT:
new.ssi_addr = (long) kinfo->si_addr;
new.ssi_perf = kinfo->si_perf;
break;
case SIL_CHLD: case SIL_CHLD:
new.ssi_pid = kinfo->si_pid; new.ssi_pid = kinfo->si_pid;
new.ssi_uid = kinfo->si_uid; new.ssi_uid = kinfo->si_uid;

Просмотреть файл

@ -236,6 +236,8 @@ typedef struct compat_siginfo {
char _dummy_pkey[__COMPAT_ADDR_BND_PKEY_PAD]; char _dummy_pkey[__COMPAT_ADDR_BND_PKEY_PAD];
u32 _pkey; u32 _pkey;
} _addr_pkey; } _addr_pkey;
/* used when si_code=TRAP_PERF */
compat_u64 _perf;
}; };
} _sigfault; } _sigfault;

Просмотреть файл

@ -43,6 +43,7 @@ enum siginfo_layout {
SIL_FAULT_MCEERR, SIL_FAULT_MCEERR,
SIL_FAULT_BNDERR, SIL_FAULT_BNDERR,
SIL_FAULT_PKUERR, SIL_FAULT_PKUERR,
SIL_PERF_EVENT,
SIL_CHLD, SIL_CHLD,
SIL_RT, SIL_RT,
SIL_SYS, SIL_SYS,

Просмотреть файл

@ -91,6 +91,8 @@ union __sifields {
char _dummy_pkey[__ADDR_BND_PKEY_PAD]; char _dummy_pkey[__ADDR_BND_PKEY_PAD];
__u32 _pkey; __u32 _pkey;
} _addr_pkey; } _addr_pkey;
/* used when si_code=TRAP_PERF */
__u64 _perf;
}; };
} _sigfault; } _sigfault;
@ -155,6 +157,7 @@ typedef struct siginfo {
#define si_lower _sifields._sigfault._addr_bnd._lower #define si_lower _sifields._sigfault._addr_bnd._lower
#define si_upper _sifields._sigfault._addr_bnd._upper #define si_upper _sifields._sigfault._addr_bnd._upper
#define si_pkey _sifields._sigfault._addr_pkey._pkey #define si_pkey _sifields._sigfault._addr_pkey._pkey
#define si_perf _sifields._sigfault._perf
#define si_band _sifields._sigpoll._band #define si_band _sifields._sigpoll._band
#define si_fd _sifields._sigpoll._fd #define si_fd _sifields._sigpoll._fd
#define si_call_addr _sifields._sigsys._call_addr #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_BRANCH 3 /* process taken branch trap */
#define TRAP_HWBKPT 4 /* hardware breakpoint/watchpoint */ #define TRAP_HWBKPT 4 /* hardware breakpoint/watchpoint */
#define TRAP_UNK 5 /* undiagnosed trap */ #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 * There is an additional set of SIGTRAP si_codes used by ptrace

Просмотреть файл

@ -39,6 +39,8 @@ struct signalfd_siginfo {
__s32 ssi_syscall; __s32 ssi_syscall;
__u64 ssi_call_addr; __u64 ssi_call_addr;
__u32 ssi_arch; __u32 ssi_arch;
__u32 __pad3;
__u64 ssi_perf;
/* /*
* Pad strcture to 128 bytes. Remember to update the * 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 * comes out of a read(2) and we really don't want to have
* a compat on read(2). * a compat on read(2).
*/ */
__u8 __pad[28]; __u8 __pad[16];
}; };

Просмотреть файл

@ -1199,6 +1199,7 @@ static inline bool has_si_pid_and_uid(struct kernel_siginfo *info)
case SIL_FAULT_MCEERR: case SIL_FAULT_MCEERR:
case SIL_FAULT_BNDERR: case SIL_FAULT_BNDERR:
case SIL_FAULT_PKUERR: case SIL_FAULT_PKUERR:
case SIL_PERF_EVENT:
case SIL_SYS: case SIL_SYS:
ret = false; ret = false;
break; break;
@ -2531,6 +2532,7 @@ static void hide_si_addr_tag_bits(struct ksignal *ksig)
case SIL_FAULT_MCEERR: case SIL_FAULT_MCEERR:
case SIL_FAULT_BNDERR: case SIL_FAULT_BNDERR:
case SIL_FAULT_PKUERR: case SIL_FAULT_PKUERR:
case SIL_PERF_EVENT:
ksig->info.si_addr = arch_untagged_si_addr( ksig->info.si_addr = arch_untagged_si_addr(
ksig->info.si_addr, ksig->sig, ksig->info.si_code); ksig->info.si_addr, ksig->sig, ksig->info.si_code);
break; break;
@ -3333,6 +3335,10 @@ void copy_siginfo_to_external32(struct compat_siginfo *to,
#endif #endif
to->si_pkey = from->si_pkey; to->si_pkey = from->si_pkey;
break; break;
case SIL_PERF_EVENT:
to->si_addr = ptr_to_compat(from->si_addr);
to->si_perf = from->si_perf;
break;
case SIL_CHLD: case SIL_CHLD:
to->si_pid = from->si_pid; to->si_pid = from->si_pid;
to->si_uid = from->si_uid; to->si_uid = from->si_uid;
@ -3413,6 +3419,10 @@ static int post_copy_siginfo_from_user32(kernel_siginfo_t *to,
#endif #endif
to->si_pkey = from->si_pkey; to->si_pkey = from->si_pkey;
break; break;
case SIL_PERF_EVENT:
to->si_addr = compat_ptr(from->si_addr);
to->si_perf = from->si_perf;
break;
case SIL_CHLD: case SIL_CHLD:
to->si_pid = from->si_pid; to->si_pid = from->si_pid;
to->si_uid = from->si_uid; to->si_uid = from->si_uid;
@ -4593,6 +4603,7 @@ static inline void siginfo_buildtime_checks(void)
CHECK_OFFSET(si_lower); CHECK_OFFSET(si_lower);
CHECK_OFFSET(si_upper); CHECK_OFFSET(si_upper);
CHECK_OFFSET(si_pkey); CHECK_OFFSET(si_pkey);
CHECK_OFFSET(si_perf);
/* sigpoll */ /* sigpoll */
CHECK_OFFSET(si_band); CHECK_OFFSET(si_band);