From: "Liang, Kan" <kan.liang@linux.intel.com>
To: Dapeng Mi <dapeng1.mi@linux.intel.com>,
Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Namhyung Kim <namhyung@kernel.org>,
Ian Rogers <irogers@google.com>,
Adrian Hunter <adrian.hunter@intel.com>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Andi Kleen <ak@linux.intel.com>,
Eranian Stephane <eranian@google.com>
Cc: linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org,
Dapeng Mi <dapeng1.mi@intel.com>,
kernel test robot <oliver.sang@intel.com>
Subject: Re: [Patch v2 3/6] perf/x86: Check if cpuc->events[*] pointer exists before accessing it
Date: Mon, 11 Aug 2025 16:32:49 -0700 [thread overview]
Message-ID: <17298e98-1a2d-4cdd-9156-73e77cc4eb5b@linux.intel.com> (raw)
In-Reply-To: <20250811090034.51249-4-dapeng1.mi@linux.intel.com>
On 2025-08-11 2:00 a.m., Dapeng Mi wrote:
> The PMI handler could disable some events as the interrupt throttling
> and clear the corresponding items in cpuc->events[] array.
>
> perf_event_overflow()
> -> __perf_event_overflow()
> ->__perf_event_account_interrupt()
> -> perf_event_throttle_group()
> -> perf_event_throttle()
> -> event->pmu->stop()
> -> x86_pmu_stop()
>
> Moreover PMI is NMI on x86 platform and it could interrupt other perf
> code like setup_pebs_adaptive_sample_data().
The PMU is disabled when draining the PEBS records. I don't think a PMI
can be triggered in the setup_pebs_adaptive_sample_data().
> So once PMI handling
> finishes and returns into setup_pebs_adaptive_sample_data() and it could
> find the cpuc->events[*] becomes NULL and accessing this NULL pointer
> triggers an invalid memory access and leads to kernel crashes eventually.
The commit 9734e25fbf5a stops all events in a group when processing the
last records of the leader event. For large PEBS, it's possible that
there are still some records for member events left. It should be the
root cause of the NULL pointer. If so, we should drain those records as
well.
Thanks,
Kan>
> Thus add NULL check before accessing cpuc->events[*] pointer.
>
> Reported-by: kernel test robot <oliver.sang@intel.com>
> Closes: https://lore.kernel.org/oe-lkp/202507042103.a15d2923-lkp@intel.com
> Fixes: 9734e25fbf5a ("perf: Fix the throttle logic for a group")
> Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
> Tested-by: kernel test robot <oliver.sang@intel.com>
> ---
> arch/x86/events/core.c | 3 +++
> arch/x86/events/intel/core.c | 6 +++++-
> arch/x86/events/intel/ds.c | 13 ++++++-------
> 3 files changed, 14 insertions(+), 8 deletions(-)
>
> diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
> index 7610f26dfbd9..f0a3bc57157d 100644
> --- a/arch/x86/events/core.c
> +++ b/arch/x86/events/core.c
> @@ -1711,6 +1711,9 @@ int x86_pmu_handle_irq(struct pt_regs *regs)
> continue;
>
> event = cpuc->events[idx];
> + if (!event)
> + continue;
> +
> last_period = event->hw.last_period;
>
> val = static_call(x86_pmu_update)(event);
> diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
> index 15da60cf69f2..386717b75a09 100644
> --- a/arch/x86/events/intel/core.c
> +++ b/arch/x86/events/intel/core.c
> @@ -2718,6 +2718,8 @@ static void update_saved_topdown_regs(struct perf_event *event, u64 slots,
> if (!is_topdown_idx(idx))
> continue;
> other = cpuc->events[idx];
> + if (!other)
> + continue;
> other->hw.saved_slots = slots;
> other->hw.saved_metric = metrics;
> }
> @@ -2761,6 +2763,8 @@ static u64 intel_update_topdown_event(struct perf_event *event, int metric_end,
> if (!is_topdown_idx(idx))
> continue;
> other = cpuc->events[idx];
> + if (!other)
> + continue;
> __icl_update_topdown_event(other, slots, metrics,
> event ? event->hw.saved_slots : 0,
> event ? event->hw.saved_metric : 0);
> @@ -3138,7 +3142,7 @@ static void x86_pmu_handle_guest_pebs(struct pt_regs *regs,
>
> for_each_set_bit(bit, (unsigned long *)&guest_pebs_idxs, X86_PMC_IDX_MAX) {
> event = cpuc->events[bit];
> - if (!event->attr.precise_ip)
> + if (!event || !event->attr.precise_ip)
> continue;
>
> perf_sample_data_init(data, 0, event->hw.last_period);
> diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
> index c0b7ac1c7594..b23c49e2e06f 100644
> --- a/arch/x86/events/intel/ds.c
> +++ b/arch/x86/events/intel/ds.c
> @@ -2480,6 +2480,8 @@ static void intel_pmu_pebs_event_update_no_drain(struct cpu_hw_events *cpuc, u64
> */
> for_each_set_bit(bit, (unsigned long *)&pebs_enabled, X86_PMC_IDX_MAX) {
> event = cpuc->events[bit];
> + if (!event)
> + continue;
> if (event->hw.flags & PERF_X86_EVENT_AUTO_RELOAD)
> intel_pmu_save_and_restart_reload(event, 0);
> }
> @@ -2579,10 +2581,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs, struct perf_sample_d
> continue;
>
> event = cpuc->events[bit];
> - if (WARN_ON_ONCE(!event))
> - continue;
> -
> - if (WARN_ON_ONCE(!event->attr.precise_ip))
> + if (!event || WARN_ON_ONCE(!event->attr.precise_ip))
> continue;
>
> /* log dropped samples number */
> @@ -2645,9 +2644,7 @@ static void intel_pmu_drain_pebs_icl(struct pt_regs *iregs, struct perf_sample_d
> pebs_status = basic->applicable_counters & cpuc->pebs_enabled & mask;
> for_each_set_bit(bit, (unsigned long *)&pebs_status, X86_PMC_IDX_MAX) {
> event = cpuc->events[bit];
> -
> - if (WARN_ON_ONCE(!event) ||
> - WARN_ON_ONCE(!event->attr.precise_ip))
> + if (!event || WARN_ON_ONCE(!event->attr.precise_ip))
> continue;
>
> if (counts[bit]++) {
> @@ -2663,6 +2660,8 @@ static void intel_pmu_drain_pebs_icl(struct pt_regs *iregs, struct perf_sample_d
> continue;
>
> event = cpuc->events[bit];
> + if (!event)
> + continue;
>
> __intel_pmu_pebs_last_event(event, iregs, regs, data, last[bit],
> counts[bit], setup_pebs_adaptive_sample_data);
next prev parent reply other threads:[~2025-08-11 23:32 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-11 9:00 [Patch v2 0/6] x86 perf bug fixes and optimization Dapeng Mi
2025-08-11 9:00 ` [Patch v2 1/6] perf/x86/intel: Use early_initcall() to hook bts_init() Dapeng Mi
2025-08-11 9:00 ` [Patch v2 2/6] perf/x86/intel: Fix IA32_PMC_x_CFG_B MSRs access error Dapeng Mi
2025-08-11 9:00 ` [Patch v2 3/6] perf/x86: Check if cpuc->events[*] pointer exists before accessing it Dapeng Mi
2025-08-11 23:32 ` Liang, Kan [this message]
2025-08-12 2:33 ` Mi, Dapeng
2025-08-12 18:16 ` Liang, Kan
2025-08-19 8:02 ` Mi, Dapeng
2025-08-19 8:45 ` Peter Zijlstra
2025-08-19 9:21 ` Mi, Dapeng
2025-08-19 9:26 ` Mi, Dapeng
2025-08-11 9:00 ` [Patch v2 4/6] perf/x86: Add PERF_CAP_PEBS_TIMING_INFO flag Dapeng Mi
2025-08-11 9:00 ` [Patch v2 5/6] perf/x86/intel: Change macro GLOBAL_CTRL_EN_PERF_METRICS to BIT_ULL(48) Dapeng Mi
2025-08-11 9:00 ` [Patch v2 6/6] perf/x86/intel: Add ICL_FIXED_0_ADAPTIVE bit into INTEL_FIXED_BITS_MASK Dapeng Mi
2025-08-12 0:00 ` Liang, Kan
2025-08-12 2:54 ` Mi, Dapeng
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=17298e98-1a2d-4cdd-9156-73e77cc4eb5b@linux.intel.com \
--to=kan.liang@linux.intel.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=ak@linux.intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=dapeng1.mi@intel.com \
--cc=dapeng1.mi@linux.intel.com \
--cc=eranian@google.com \
--cc=irogers@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=oliver.sang@intel.com \
--cc=peterz@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).