Skip to content

Commit

Permalink
Merge tag 'perf_urgent_for_v6.1_rc7' of git://git.kernel.org/pub/scm/…
Browse files Browse the repository at this point in the history
…linux/kernel/git/tip/tip

Pull perf fixes from Borislav Petkov:
 "Two more fixes to the perf sigtrap handling:

   - output the address in the sample only when it has been requested

   - handle the case where user-only events can hit in kernel and thus
     upset the sigtrap sanity checking"

* tag 'perf_urgent_for_v6.1_rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  perf: Consider OS filter fail
  perf: Fixup SIGTRAP and sample_flags interaction
  • Loading branch information
Linus Torvalds committed Nov 27, 2022
2 parents bf82d38 + 030a976 commit 5afcab2
Showing 1 changed file with 25 additions and 2 deletions.
27 changes: 25 additions & 2 deletions kernel/events/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -9273,6 +9273,19 @@ int perf_event_account_interrupt(struct perf_event *event)
return __perf_event_account_interrupt(event, 1);
}

static inline bool sample_is_allowed(struct perf_event *event, struct pt_regs *regs)
{
/*
* Due to interrupt latency (AKA "skid"), we may enter the
* kernel before taking an overflow, even if the PMU is only
* counting user events.
*/
if (event->attr.exclude_kernel && !user_mode(regs))
return false;

return true;
}

/*
* Generic event overflow handling, sampling.
*/
Expand Down Expand Up @@ -9306,14 +9319,21 @@ static int __perf_event_overflow(struct perf_event *event,
}

if (event->attr.sigtrap) {
/*
* The desired behaviour of sigtrap vs invalid samples is a bit
* tricky; on the one hand, one should not loose the SIGTRAP if
* it is the first event, on the other hand, we should also not
* trigger the WARN or override the data address.
*/
bool valid_sample = sample_is_allowed(event, regs);
unsigned int pending_id = 1;

if (regs)
pending_id = hash32_ptr((void *)instruction_pointer(regs)) ?: 1;
if (!event->pending_sigtrap) {
event->pending_sigtrap = pending_id;
local_inc(&event->ctx->nr_pending);
} else if (event->attr.exclude_kernel) {
} else if (event->attr.exclude_kernel && valid_sample) {
/*
* Should not be able to return to user space without
* consuming pending_sigtrap; with exceptions:
Expand All @@ -9328,7 +9348,10 @@ static int __perf_event_overflow(struct perf_event *event,
*/
WARN_ON_ONCE(event->pending_sigtrap != pending_id);
}
event->pending_addr = data->addr;

event->pending_addr = 0;
if (valid_sample && (data->sample_flags & PERF_SAMPLE_ADDR))
event->pending_addr = data->addr;
irq_work_queue(&event->pending_irq);
}

Expand Down

0 comments on commit 5afcab2

Please sign in to comment.