On Wed, 5 May 2021 at 16:11, Eric W. Beiderman <ebiederm@xxxxxxxxxxxx> wrote: > From: "Eric W. Biederman" <ebiederm@xxxxxxxxxxxx> > > Separate generating the signal from deciding it needs to be sent. > > v1: https://lkml.kernel.org/r/m17dkjqqxz.fsf_-_@xxxxxxxxxxxxxxxxx > Signed-off-by: "Eric W. Biederman" <ebiederm@xxxxxxxxxxxx> Reviewed-by: Marco Elver <elver@xxxxxxxxxx> > --- > include/linux/sched/signal.h | 1 + > kernel/events/core.c | 11 ++--------- > kernel/signal.c | 13 +++++++++++++ > 3 files changed, 16 insertions(+), 9 deletions(-) > > diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h > index 7daa425f3055..1e2f61a1a512 100644 > --- a/include/linux/sched/signal.h > +++ b/include/linux/sched/signal.h > @@ -318,6 +318,7 @@ int send_sig_mceerr(int code, void __user *, short, struct task_struct *); > > int force_sig_bnderr(void __user *addr, void __user *lower, void __user *upper); > int force_sig_pkuerr(void __user *addr, u32 pkey); > +int force_sig_perf(void __user *addr, u32 type, u64 sig_data); > > int force_sig_fault_trapno(int sig, int code, void __user *addr, int trapno); > int send_sig_fault_trapno(int sig, int code, void __user *addr, int trapno, > diff --git a/kernel/events/core.c b/kernel/events/core.c > index 928b166d888e..48ea8863183b 100644 > --- a/kernel/events/core.c > +++ b/kernel/events/core.c > @@ -6394,8 +6394,6 @@ void perf_event_wakeup(struct perf_event *event) > > static void perf_sigtrap(struct perf_event *event) > { > - struct kernel_siginfo info; > - > /* > * We'd expect this to only occur if the irq_work is delayed and either > * ctx->task or current has changed in the meantime. This can be the > @@ -6410,13 +6408,8 @@ static void perf_sigtrap(struct perf_event *event) > if (current->flags & PF_EXITING) > return; > > - clear_siginfo(&info); > - info.si_signo = SIGTRAP; > - info.si_code = TRAP_PERF; > - info.si_errno = event->attr.type; > - info.si_perf = event->attr.sig_data; > - info.si_addr = (void __user *)event->pending_addr; > - force_sig_info(&info); > + force_sig_perf((void __user *)event->pending_addr, > + event->attr.type, event->attr.sig_data); > } > > static void perf_pending_event_disable(struct perf_event *event) > diff --git a/kernel/signal.c b/kernel/signal.c > index 697c5fe58db8..49560ceac048 100644 > --- a/kernel/signal.c > +++ b/kernel/signal.c > @@ -1753,6 +1753,19 @@ 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 = type; > + info.si_code = TRAP_PERF; > + info.si_addr = addr; > + info.si_perf = sig_data; > + return force_sig_info(&info); > +} > + > #if IS_ENABLED(CONFIG_SPARC) > int force_sig_fault_trapno(int sig, int code, void __user *addr, int trapno) > { > -- > 2.30.1 >