From: Ihor Solodrai <ihor.solodrai@linux.dev>
To: Borislav Petkov <bp@alien8.de>, Dave Hansen <dave.hansen@intel.com>
Cc: Alexei Starovoitov <ast@kernel.org>,
Andrii Nakryiko <andrii@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Eduard Zingerman <eddyz87@gmail.com>,
Kumar Kartikeya Dwivedi <memxor@gmail.com>,
Andrey Ryabinin <ryabinin.a.a@gmail.com>,
Andrew Morton <akpm@linux-foundation.org>,
bpf@vger.kernel.org, kasan-dev@googlegroups.com,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
Thomas Gleixner <tglx@kernel.org>, Ingo Molnar <mingo@redhat.com>,
Dave Hansen <dave.hansen@linux.intel.com>,
x86@kernel.org, "H. Peter Anvin" <hpa@zytor.com>,
Andrey Konovalov <andreyknvl@gmail.com>
Subject: Re: [PATCH v1] kasan: Fix false-positive wild-memory-access on x86 under 5-level paging
Date: Mon, 22 Jun 2026 17:29:12 -0700 [thread overview]
Message-ID: <87643862-e32e-43c7-8c81-7186f30059ea@linux.dev> (raw)
In-Reply-To: <20260618183815.GDajQ7F-bqTHnrakoi@fat_crate.local>
On 6/18/26 11:38 AM, Borislav Petkov wrote:
> On Thu, Jun 18, 2026 at 11:12:09AM -0700, Dave Hansen wrote:
>> On 6/18/26 10:09, Borislav Petkov wrote:
>>> On Wed, Jun 17, 2026 at 03:13:33PM -0700, Ihor Solodrai wrote:
>>>> So my question to maintainers is what approach seems best?
>>> The CPUID stuff is being rewritten currently and it should address your issue
>>> too. If not, then we need to rewrite it better.
>>>
>>> Can you reproduce with this set applied ontop:
>>>
>>> https://lore.kernel.org/r/20260528153923.403473-1-darwi@linutronix.de
>>
>> Thinking about this a bit more... If Ahmed's series does fix this, I
>> think it will be accidental. It still uses identify_cpu() and also does
>> a memset() of the new c->cpuid structure in addition to the old
>> c->x86_capability structure.
>>
>> I'm not knocking Ahmed's series by any means. It just probably won't fix
>> this issue.
>>
>> In a perfect world early_identify_cpu() and identify_cpu() would either
>> get consolidated into one thing. Or at least become two discrete things
>> that initialize two completely disjoint sets of data. That way,
>> identify_cpu() wouldn't memset() anything.
>>
>> Isn't that the _real_ fix? Instead of trying to hide the inconsistency
>> when good data is blown away, we stop blowing it away in the first place?
>
> early_ is only on the BSP and you want to scan all CPUs.
>
> AFAIR, the last time I was looking at how we scan the CPUID leafs, we do have
> cases where there's blips in time when cap bits get disappeared to be
> rescanned again. The toggling of MSR bits which control feature flags is one
> thing that comes to mind.
>
> But I'm with you on the consolidation approach. I think this is what we should
Hello Dave, Boris. Thank you for the input.
I tried a slight refactoring of the identify_cpu() machinery to
eliminate the memset(x86_capability) from the boot cpu, and it fixes
the splat that I reported.
identify_cpu() is split into two parts:
* identify_cpu_scan() - the top part, up to and including the
generic_identify() call
* identify_cpu() proper with the rest, no memset here
Then (gated on x86_64) identify_boot_cpu() *skips* the
identify_cpu_scan() call, only executing the bottom part of current
identify_cpu(). We can do that because boot cpu already did the _scan
part in early_identify_cpu(), when interrupts are still disabled.
One caveat: get_model_name() is moved from generic_identify() into
identify_cpu(), otherwise it wouldn't be called on boot cpu. Same for
c->loops_per_jiffy = loops_per_jiffy; - it's moved to the "bottom"
identify_cpu().
The behavior for secondary cpus is unchanged: identify_secondary_cpu()
calls identify_cpu_scan() then immediately identify_cpu().
Please take a look at the diff below and let me know if this is a good
way to proceed. I don't know exactly what I'm doing, so concerns and
corrections are welcome.
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index a4268c47f2bc..4a655109cacf 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1978,8 +1978,6 @@ static void generic_identify(struct cpuinfo_x86 *c)
get_cpu_address_sizes(c);
- get_model_name(c); /* Default name */
-
/*
* ESPFIX is a strange bug. All real CPUs have it. Paravirt
* systems that run Linux at CPL > 0 may or may not have the
@@ -1999,13 +1997,12 @@ static void generic_identify(struct cpuinfo_x86 *c)
}
/*
- * This does the hard work of actually picking apart the CPU stuff...
+ * Rebuild capability set from CPUID and re-apply the forced-cap overrides
+ * through generic_identify(). This *should* run with interrupts off, otherwise
+ * an interrupt handler might see the capability bits cleared.
*/
-static void identify_cpu(struct cpuinfo_x86 *c)
+static void identify_cpu_scan(struct cpuinfo_x86 *c)
{
- int i;
-
- c->loops_per_jiffy = loops_per_jiffy;
c->x86_cache_size = 0;
c->x86_vendor = X86_VENDOR_UNKNOWN;
c->x86_model = c->x86_stepping = 0; /* So far unknown... */
@@ -2028,6 +2025,19 @@ static void identify_cpu(struct cpuinfo_x86 *c)
#endif
generic_identify(c);
+}
+
+/*
+ * This is safe to run with interrupts on.
+ * The boot CPU can run just this from arch_cpu_finalize_init(), because
+ * the scan part already happened in early_identify_cpu().
+ */
+static void identify_cpu(struct cpuinfo_x86 *c)
+{
+ int i;
+
+ c->loops_per_jiffy = loops_per_jiffy;
+ get_model_name(c); /* Default name */
cpu_parse_topology(c);
@@ -2154,6 +2164,17 @@ void enable_sep_cpu(void)
static __init void identify_boot_cpu(void)
{
+ /*
+ * The boot CPU's capabilities were already scanned by early_identify_cpu().
+ * Here identify_cpu() only finalizes them.
+ *
+ * 32-bit still needs the full scan here: it sets X86_BUG_ESPFIX (via
+ * generic_identify()) and the no-CPUID cpuid_level default, which the early
+ * path does not.
+ */
+#ifndef CONFIG_X86_64
+ identify_cpu_scan(&boot_cpu_data);
+#endif
identify_cpu(&boot_cpu_data);
if (HAS_KERNEL_IBT && cpu_feature_enabled(X86_FEATURE_IBT))
pr_info("CET detected: Indirect Branch Tracking enabled\n");
@@ -2178,6 +2199,7 @@ void identify_secondary_cpu(unsigned int cpu)
*c = boot_cpu_data;
c->cpu_index = cpu;
+ identify_cpu_scan(c);
identify_cpu(c);
#ifdef CONFIG_X86_32
enable_sep_cpu();
--
2.53.0-Meta
next prev parent reply other threads:[~2026-06-23 0:29 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-10 17:56 [PATCH v1] kasan: Fix false-positive wild-memory-access on x86 under 5-level paging Ihor Solodrai
2026-06-10 18:17 ` sashiko-bot
2026-06-10 18:28 ` Ihor Solodrai
2026-06-10 18:39 ` Andrey Konovalov
2026-06-10 21:55 ` Ihor Solodrai
2026-06-12 16:30 ` Kiryl Shutsemau
2026-06-12 19:42 ` Ihor Solodrai
2026-06-17 22:13 ` Ihor Solodrai
2026-06-18 16:55 ` Andrey Ryabinin
2026-06-18 17:09 ` Borislav Petkov
2026-06-18 18:12 ` Dave Hansen
2026-06-18 18:38 ` Borislav Petkov
2026-06-23 0:29 ` Ihor Solodrai [this message]
2026-06-23 0:35 ` Ihor Solodrai
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=87643862-e32e-43c7-8c81-7186f30059ea@linux.dev \
--to=ihor.solodrai@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=andreyknvl@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bp@alien8.de \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=dave.hansen@intel.com \
--cc=dave.hansen@linux.intel.com \
--cc=eddyz87@gmail.com \
--cc=hpa@zytor.com \
--cc=kasan-dev@googlegroups.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=memxor@gmail.com \
--cc=mingo@redhat.com \
--cc=ryabinin.a.a@gmail.com \
--cc=tglx@kernel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.