Re: [PATCH 1/2] x86/kmsan: Fix CPU entry area metadata lookup

From: Viorel Cernateanu

Date: Sun Nov 01 2026 - 12:04:08 EST


Thanks, Alexander and Peter.

I've reworked v2 to keep the CPU entry areas in CPU order when KMSAN
is enabled. This allows the metadata lookup to identify the CPU directly,
without adding a per-CPU search. Only CPU entry area randomization is
disabled; kernel text randomization remains enabled.

The one-page offset error still needs a separate fix. The lookup now
uses CPU_ENTRY_AREA_PER_CPU rather than CPU_ENTRY_AREA_BASE, excludes
the IDT page, and checks that the calculated CPU is possible before
accessing its per-CPU data.

I've split the changes into four patches:

1. Disable CPU entry area randomization with KMSAN.
2. Correct the base used to calculate the CPU in the metadata lookup.
3. Factor __pfn_valid() out of pfn_valid(), with the caller responsible
for RCU-sched read-side protection.
4. Use __pfn_valid() and the notrace preemption helpers in
kmsan_virt_addr_valid() to avoid recursion through instrumented code.

This reuses the existing PFN validation rather than maintaining a
separate copy. One consequence of the refactoring is that pfn_valid()
also holds the RCU-sched read lock during its initial range checks,
which previously ran before acquiring it.

I tested the cumulative series against the same unpatched base:

- QEMU reproduces the GDT lookup failure and the metadata boundary
failures on the base. The corresponding tests pass with v2, including
the metadata tests with and without KASLR.
- With CONFIG_DEBUG_PREEMPT, the base hangs immediately after KMSAN
starts. The candidate completes all six boots, three with KASLR and
three without.
- On the Ivy Bridge laptop, the candidate boots with KASLR using a
minimal init, and the GDT and metadata tests pass on all four CPUs.
- An x86_64_defconfig build without KMSAN boots to init.

I have not tested CONFIG_DEBUG_LOCK_ALLOC or measured the performance
difference.

On s390, kmsan_virt_addr_valid() still calls preempt_disable() and
reaches pfn_valid() through virt_addr_valid(). This series does not
change the architecture-specific s390 code, but it does refactor the
generic pfn_valid() implementation used by that path.

I also cross-compiled the selected KMSAN and memory-management
objects for s390 on both the base and v2, using identical
configurations with CONFIG_KMSAN=y and CONFIG_DEBUG_PREEMPT=y.
Both object builds completed without compiler diagnostics.

This does not cover linking or booting an s390 kernel. With
CONFIG_DEBUG_PREEMPT, the s390 metadata lookup still calls
preempt_count_add(); I have not validated that path at runtime.

Ilya, could you review the helper's requirements from the s390 side
and advise whether the corresponding architecture-specific change
should accompany this series?

I'll send the revised series separately.