Consider the following scenario, While scheduling out an IBS event from perf's core scheduling path, event_sched_out() disables the IBS event by clearing the IBS enable bit in perf_ibs_disable_event(). However, if a delayed IBS NMI is delivered after the IBS enable bit is cleared, the IBS NMI handler may still observe the valid bit set and incorrectly treat the sample as valid. As a result, it re-enables IBS by setting the enable bit, even though the event has already been scheduled out. This leads to a situation where IBS is re-enabled after being explicitly disabled, which is incorrect. Although this race does not have visible side effects, it violates the expected behavior of the perf subsystem. The race is particularly noticeable when userspace repeatedly disables and re-enables IBS using PERF_EVENT_IOC_DISABLE and PERF_EVENT_IOC_ENABLE ioctls in a loop. Fix this by checking the IBS_STOPPING bit in the IBS NMI handler before re-enabling the IBS event. If the IBS_STOPPING bit is set, it indicates that the event is either disabled or in the process of being disabled, and the NMI handler should not re-enable it. Signed-off-by: Manali Shukla --- arch/x86/events/amd/ibs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c index eeb607b84dda..09b56bab510a 100644 --- a/arch/x86/events/amd/ibs.c +++ b/arch/x86/events/amd/ibs.c @@ -1582,7 +1582,8 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs) } new_config |= period >> 4; - perf_ibs_enable_event(perf_ibs, hwc, new_config); + if (!test_bit(IBS_STOPPING, pcpu->state)) + perf_ibs_enable_event(perf_ibs, hwc, new_config); } perf_event_update_userpage(event); -- 2.43.0