Commit af5eeab7 authored by Eric W. Biederman's avatar Eric W. Biederman
Browse files

signal: Factor force_sig_perf out of perf_sigtrap

Separate filling in siginfo for TRAP_PERF from deciding that
siginal needs to be sent.

There are enough little details that need to be correct when
properly filling in siginfo_t that it is easy to make mistakes
if filling in the siginfo_t is in the same function with other
logic.  So factor out force_sig_perf to reduce the cognative
load of on reviewers, maintainers and implementors.

v1: https://lkml.kernel.org/r/m17dkjqqxz.fsf_-_@fess.ebiederm.org
v2: https://lkml.kernel.org/r/20210505141101.11519-10-ebiederm@xmission.com
Link: https://lkml.kernel.org/r/20210517195748.8880-3-ebiederm@xmission.com


Reviewed-by: default avatarMarco Elver <elver@google.com>
Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
parent 9abcabe3
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -326,6 +326,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_ptrace_errno_trap(int errno, void __user *addr);

+2 −9
Original line number Diff line number Diff line
@@ -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)
+13 −0
Original line number Diff line number Diff line
@@ -1763,6 +1763,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);
}

/* For the crazy architectures that include trap information in
 * the errno field, instead of an actual errno value.
 */