* [PATCH] s390/pai: Prevent ioctl(PERF_EVENT_IOC_REFRESH) @ 2026-08-27 6:46 Thomas Richter 2026-08-27 6:57 ` sashiko-bot 0 siblings, 1 reply; 4+ messages in thread From: Thomas Richter @ 2026-08-27 6:46 UTC (permalink / raw) To: linux-s390; +Cc: Thomas Richter Prevent this ioctl(fd, PERF_EVENT_IOC_REFRESH, XXX) to take effect. PAI PMU events CRYPTO_ALL and NNPA_ALL are designed to read out the changed counter values at schedule out time, when these events have been installed system wide. Then they use CPU-context. If an application issues ioctl(fd, PERF_EVENT_IOC_REFRESH, XXX) it expects to read out samples after XXX hits. The PAI PMUs do that read operation and then reset the values because it expects a context switch out. This contradicts the readout at next schedule out time. The reported result is too low. Therefore prevent this call ioctl(PERF_EVENT_IOC_REFRESH) right now. Signed-off-by: Thomas Richter <tmricht@linux.ibm.com> --- arch/s390/kernel/perf_pai.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/s390/kernel/perf_pai.c b/arch/s390/kernel/perf_pai.c index 05f74d74fad1..3e972d940100 100644 --- a/arch/s390/kernel/perf_pai.c +++ b/arch/s390/kernel/perf_pai.c @@ -666,6 +666,8 @@ static void pai_have_sample(struct perf_event *event, struct pai_map *cpump) if (!event) /* No event active */ return; + event->pending_kill = 0; /* prevent ioctl(IOC_REFRESH) */ + atomic_set(&event->event_limit, 0); pp = &pai_pmu[PAI_PMU_IDX(event)]; rawsize = pai_copy(cpump->save, cpump->area, pp, (unsigned long *)PAI_SAVE_AREA(event), -- 2.55.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] s390/pai: Prevent ioctl(PERF_EVENT_IOC_REFRESH) 2026-08-27 6:46 [PATCH] s390/pai: Prevent ioctl(PERF_EVENT_IOC_REFRESH) Thomas Richter @ 2026-08-27 6:57 ` sashiko-bot 2026-08-31 9:45 ` Thomas Richter 0 siblings, 1 reply; 4+ messages in thread From: sashiko-bot @ 2026-08-27 6:57 UTC (permalink / raw) To: Thomas Richter Cc: linux-s390, Heiko Carstens, Alexander Gordeev, Christian Borntraeger, Vasily Gorbik Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [High] Unprotected modification of core perf_event state (pending_kill, event_limit) causes data races, dropped signals, and silently breaks the PERF_EVENT_IOC_REFRESH API. -- commit ae843d6ca679921720078776be6911f36a1931c1 Author: Thomas Richter <tmricht@linux.ibm.com> s390/pai: Prevent ioctl(PERF_EVENT_IOC_REFRESH) This commit prevents ioctl(fd, PERF_EVENT_IOC_REFRESH, XXX) from taking effect on PAI PMU events by clearing event->pending_kill and event->event_limit. The intention is to prevent counter resets that conflict with the schedule-out readouts these PMUs are designed for. > diff --git a/arch/s390/kernel/perf_pai.c b/arch/s390/kernel/perf_pai.c > index cdb8006220ca0..e43b2f1c94471 100644 > --- a/arch/s390/kernel/perf_pai.c > +++ b/arch/s390/kernel/perf_pai.c > @@ -658,6 +658,8 @@ static void pai_have_sample(struct perf_event *event, struct pai_map *cpump) > > if (!event) /* No event active */ > return; > + event->pending_kill = 0; /* prevent ioctl(IOC_REFRESH) */ > + atomic_set(&event->event_limit, 0); [Severity: High] Does this unprotected modification of core perf_event state (pending_kill, event_limit) cause data races, dropped signals, and silently break the PERF_EVENT_IOC_REFRESH API? Bypassing core perf locking rules to directly mutate event_limit and pending_kill causes data races, silently drops pending SIGIO signals, and breaks the API contract. The ioctl will return success, but userspace will never receive the requested signal, leading to application hangs. If a userspace application calls ioctl(fd, PERF_EVENT_IOC_REFRESH, N) on a PAI event, and concurrently, a context switch calls pai_have_sample(), writing to event_limit will race with atomic_add() in the core subsystem, and clearing pending_kill will race with perf_event_wakeup(). PMU drivers should not directly mutate these core fields to implicitly break an ioctl. This approach creates cross-CPU data races because it lacks the synchronization (ctx->mutex for limits, irq_work execution order for signals) used by the core subsystem. Any user with access to the PAI PMU can trigger this state corruption. > pp = &pai_pmu[PAI_PMU_IDX(event)]; > rawsize = pai_copy(cpump->save, cpump->area, pp, > (unsigned long *)PAI_SAVE_AREA(event), -- Sashiko AI review · https://sashiko.dev/#/patchset/20260827064612.3161950-1-tmricht@linux.ibm.com?part=1 ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] s390/pai: Prevent ioctl(PERF_EVENT_IOC_REFRESH) 2026-08-27 6:57 ` sashiko-bot @ 2026-08-31 9:45 ` Thomas Richter 2026-08-31 13:49 ` Heiko Carstens 0 siblings, 1 reply; 4+ messages in thread From: Thomas Richter @ 2026-08-31 9:45 UTC (permalink / raw) To: sashiko-reviews Cc: linux-s390, Heiko Carstens, Alexander Gordeev, Christian Borntraeger, Vasily Gorbik On 8/27/26 08:57, sashiko-bot@kernel.org wrote: > Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: > - [High] Unprotected modification of core perf_event state (pending_kill, event_limit) causes data races, dropped signals, and silently breaks the PERF_EVENT_IOC_REFRESH API. > -- > > commit ae843d6ca679921720078776be6911f36a1931c1 > Author: Thomas Richter <tmricht@linux.ibm.com> > > s390/pai: Prevent ioctl(PERF_EVENT_IOC_REFRESH) > > This commit prevents ioctl(fd, PERF_EVENT_IOC_REFRESH, XXX) from taking effect > on PAI PMU events by clearing event->pending_kill and event->event_limit. The > intention is to prevent counter resets that conflict with the schedule-out > readouts these PMUs are designed for. > >> diff --git a/arch/s390/kernel/perf_pai.c b/arch/s390/kernel/perf_pai.c >> index cdb8006220ca0..e43b2f1c94471 100644 >> --- a/arch/s390/kernel/perf_pai.c >> +++ b/arch/s390/kernel/perf_pai.c >> @@ -658,6 +658,8 @@ static void pai_have_sample(struct perf_event *event, struct pai_map *cpump) >> >> if (!event) /* No event active */ >> return; >> + event->pending_kill = 0; /* prevent ioctl(IOC_REFRESH) */ >> + atomic_set(&event->event_limit, 0); > > [Severity: High] > Does this unprotected modification of core perf_event state (pending_kill, > event_limit) cause data races, dropped signals, and silently break the > PERF_EVENT_IOC_REFRESH API? > > Bypassing core perf locking rules to directly mutate event_limit and > pending_kill causes data races, silently drops pending SIGIO signals, and > breaks the API contract. The ioctl will return success, but userspace will > never receive the requested signal, leading to application hangs. A: The PERF_EVENT_IOC_REFRESH API is disabled on purpose. The PAI PMU relies on data collection on schedule out of a task. This is done by design. Invoking ioctl(fd, PERF_EVENT_IOC_REFRESH API, X) breaks this behavior and should be blocked. The modifications of members perf_event::event_limit and perf_event::pending_kill are protected. The invocation is triggered by the schedule out path and protected via perf_pmu_sched_task() +--> __perf_pmu_sched_task() +--> perf_ctx_lock() This locks the event and protects the states of the event. > > If a userspace application calls ioctl(fd, PERF_EVENT_IOC_REFRESH, N) on a > PAI event, and concurrently, a context switch calls pai_have_sample(), > writing to event_limit will race with atomic_add() in the core subsystem, > and clearing pending_kill will race with perf_event_wakeup(). This requires a common code change to block an ioctl(fd, PERF_EVENT_IOC_REFRESH, N) similar to the PMU check_period call back function. > > PMU drivers should not directly mutate these core fields to implicitly break > an ioctl. This approach creates cross-CPU data races because it lacks the > synchronization (ctx->mutex for limits, irq_work execution order for signals) > used by the core subsystem. Any user with access to the PAI PMU can trigger > this state corruption. > >> pp = &pai_pmu[PAI_PMU_IDX(event)]; >> rawsize = pai_copy(cpump->save, cpump->area, pp, >> (unsigned long *)PAI_SAVE_AREA(event), > -- Thomas Richter, Dept 3303, IBM s390 Linux Development, Boeblingen, Germany -- IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Wolfgang Wendt Geschäftsführung: David Faller Sitz der Gesellschaft: Böblingen / Registergericht: Amtsgericht Stuttgart, HRB 243294 ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] s390/pai: Prevent ioctl(PERF_EVENT_IOC_REFRESH) 2026-08-31 9:45 ` Thomas Richter @ 2026-08-31 13:49 ` Heiko Carstens 0 siblings, 0 replies; 4+ messages in thread From: Heiko Carstens @ 2026-08-31 13:49 UTC (permalink / raw) To: Thomas Richter Cc: sashiko-reviews, linux-s390, Alexander Gordeev, Christian Borntraeger, Vasily Gorbik On Mon, Aug 31, 2026 at 11:45:57AM +0200, Thomas Richter wrote: > On 8/27/26 08:57, sashiko-bot@kernel.org wrote: > > Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: > > - [High] Unprotected modification of core perf_event state (pending_kill, event_limit) causes data races, dropped signals, and silently breaks the PERF_EVENT_IOC_REFRESH API. ... > >> diff --git a/arch/s390/kernel/perf_pai.c b/arch/s390/kernel/perf_pai.c > >> index cdb8006220ca0..e43b2f1c94471 100644 > >> --- a/arch/s390/kernel/perf_pai.c > >> +++ b/arch/s390/kernel/perf_pai.c > >> @@ -658,6 +658,8 @@ static void pai_have_sample(struct perf_event *event, struct pai_map *cpump) > >> > >> if (!event) /* No event active */ > >> return; > >> + event->pending_kill = 0; /* prevent ioctl(IOC_REFRESH) */ > >> + atomic_set(&event->event_limit, 0); > > > > [Severity: High] > > Does this unprotected modification of core perf_event state (pending_kill, > > event_limit) cause data races, dropped signals, and silently break the > > PERF_EVENT_IOC_REFRESH API? > > > > Bypassing core perf locking rules to directly mutate event_limit and > > pending_kill causes data races, silently drops pending SIGIO signals, and > > breaks the API contract. The ioctl will return success, but userspace will > > never receive the requested signal, leading to application hangs. > > A: The PERF_EVENT_IOC_REFRESH API is disabled on purpose. The PAI PMU > relies on data collection on schedule out of a task. This is > done by design. Invoking ioctl(fd, PERF_EVENT_IOC_REFRESH API, X) > breaks this behavior and should be blocked. > > The modifications of members perf_event::event_limit and > perf_event::pending_kill are protected. The invocation > is triggered by the schedule out path and protected via > perf_pmu_sched_task() > +--> __perf_pmu_sched_task() > +--> perf_ctx_lock() > > This locks the event and protects the states of the event. > > > > > If a userspace application calls ioctl(fd, PERF_EVENT_IOC_REFRESH, N) on a > > PAI event, and concurrently, a context switch calls pai_have_sample(), > > writing to event_limit will race with atomic_add() in the core subsystem, > > and clearing pending_kill will race with perf_event_wakeup(). > > This requires a common code change to block an ioctl(fd, PERF_EVENT_IOC_REFRESH, N) > similar to the PMU check_period call back function. The above looks like a layering violation to me. Please resend with common code maintainers on cc, so they can yell if this is not acceptable. ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-08-31 13:50 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-08-27 6:46 [PATCH] s390/pai: Prevent ioctl(PERF_EVENT_IOC_REFRESH) Thomas Richter 2026-08-27 6:57 ` sashiko-bot 2026-08-31 9:45 ` Thomas Richter 2026-08-31 13:49 ` Heiko Carstens
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox