The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Rik van Riel <riel@surriel.com>
To: linux-kernel@vger.kernel.org
Cc: x86@kernel.org, kernel-team@meta.com, "Mi,
	Dapeng" <dapeng1.mi@linux.intel.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>,
	Dave Hansen <dave.hansen@linux.intel.com>
Subject: [PATCH] perf/x86/intel/ds: Fix loop ordering in release_ds_buffers()
Date: Wed, 13 May 2026 11:43:33 -0400	[thread overview]
Message-ID: <20260513114333.7eff8a4c@fangorn> (raw)

release_ds_buffers() has three loops:
1. release_ds_buffer() - NULLs hwev->ds for each CPU
2. fini_debug_store_on_cpu() - clears MSR_IA32_DS_AREA
3. release_pebs_buffer()/release_bts_buffer() - unmaps CEA pages and
   frees backing pages

The problem is that fini_debug_store_on_cpu() checks if hwev->ds is
NULL and returns early if so. Since loop 1 already NULLed hwev->ds,
loop 2 never actually clears MSR_IA32_DS_AREA. Then loop 3 unmaps the
CEA pages, leaving the MSR pointing at now-unmapped memory. When a PEBS
overflow fires, the hardware writes to unmapped pages, causing page
faults in random victim code.

Fix by calling fini_debug_store_on_cpu() BEFORE release_ds_buffer(), so the
MSR is cleared while hwev->ds is still valid.

Observed crash signature:
  BUG: unable to handle kernel paging request in __lookup_object
  CR2: fffffe00004b7028 (CEA range)
  RIP: __lookup_object+0x39 (cmp %rdi,%rax -- register-only, can't fault)
  Secondary: TASK stack guard page hit (recursive page fault overflow)

Assisted-by: Claude:claude-opus-4.7 syzkaller
Signed-off-by: Rik van Riel <riel@surriel.com>
---
 arch/x86/events/intel/ds.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index 2abfeb4e2908..85894673f03b 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -973,18 +973,25 @@ void release_ds_buffers(void)
 	if (!x86_pmu.bts && !x86_pmu.ds_pebs)
 		return;
 
-	for_each_possible_cpu(cpu)
-		release_ds_buffer(cpu);
-
 	for_each_possible_cpu(cpu) {
 		/*
-		 * Again, ignore errors from offline CPUs, they will no longer
-		 * observe cpu_hw_events.ds and not program the DS_AREA when
-		 * they come up.
+		 * Clear MSR_IA32_DS_AREA BEFORE NULLing hwev->ds.
+		 * fini_debug_store_on_cpu() checks hwev->ds and bails
+		 * if it's NULL, so calling release_ds_buffer() first
+		 * would prevent the MSR from being cleared. That leaves
+		 * the hardware writing into CEA pages that get unmapped
+		 * below, causing asynchronous page faults at random RIPs.
+		 *
+		 * Ignore errors from offline CPUs, they will no longer
+		 * observe cpu_hw_events.ds and not program the DS_AREA
+		 * when they come up.
 		 */
 		fini_debug_store_on_cpu(cpu);
 	}
 
+	for_each_possible_cpu(cpu)
+		release_ds_buffer(cpu);
+
 	for_each_possible_cpu(cpu) {
 		if (x86_pmu.ds_pebs)
 			release_pebs_buffer(cpu);
-- 
2.53.0-Meta



                 reply	other threads:[~2026-05-13 15:43 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20260513114333.7eff8a4c@fangorn \
    --to=riel@surriel.com \
    --cc=dapeng1.mi@linux.intel.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=kernel-team@meta.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=x86@kernel.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