On 9/2/2026 11:48 PM, Vinay Belgaumkar wrote:
> A typical module unload occurring event when there is an active perf
> connection leads to freeing of the pmu pointer. The call log is something
> like:
>  ..
>  __pmu_detach_event
>  pmu_detach_event
>  pmu_detach_events
>  perf_pmu_unregister
>  ..
>
> __pmu_detach_event() sets event->pmu to null. When the perf connection
> finally is closed, the following stack trace is observed:
>
>  Oops: general protection fault, kernel NULL pointer dereference
>  ...
>  RIP: 0010:_free_event+0x3e/0x370
>  ...
>  Call Trace:
>  ...
>  perf_event_release_kernel+0x260/0x2d0
>  perf_release+0x12/0x20
>
> A call to mediated_pmu_unaccount_event() inside _free_event() is the root
> cause of this crash. Adding a check inside is_include_guest_event() ensures
> we don't accidentally access a null pmu ptr. In addition to this, we will
> now call mediated_pmu_unaccount_event() before clearing the pmu ptr so that
> nr_include_guest_events counts are maintained correctly.
>
> v5: Improve commit message and split patch into 2 (Dapeng)

Please remove this history info when you send to the patches to upstream
community.

Others look good to me.


>
> Fixes: eff95e170275 ("perf: Add APIs to create/release mediated guest vPMUs")
> Cc: Alexander Kanevskiy <[email protected]>
> Cc: Dapeng Mi <[email protected]>
> Assisted-by: Claude:Claude-Sonnet-5
> Signed-off-by: Vinay Belgaumkar <[email protected]>
> ---
>  kernel/events/core.c | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index 94ca277e0819..f19d27ac411d 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -6350,6 +6350,9 @@ static DEFINE_MUTEX(perf_mediated_pmu_mutex);
>  /* !exclude_guest event of PMU with PERF_PMU_CAP_MEDIATED_VPMU */
>  static inline bool is_include_guest_event(struct perf_event *event)
>  {
> +     if (!event->pmu)
> +             return false;
> +
>       if ((event->pmu->capabilities & PERF_PMU_CAP_MEDIATED_VPMU) &&
>           !event->attr.exclude_guest)
>               return true;
> @@ -12977,6 +12980,7 @@ static void __pmu_detach_event(struct pmu *pmu, 
> struct perf_event *event,
>       exclusive_event_destroy(event);
>       module_put(pmu->module);
>  
> +     mediated_pmu_unaccount_event(event);
>       event->pmu = NULL; /* force fault instead of UAF */
>  }
>  

Reply via email to