[PATCH RFC 00/18] arch, mm: create a generic set_memory/change_page_attr core
From: Mike Rapoport (Microsoft)
Date: Tue Jul 21 2026 - 12:41:40 EST
Currently there are 6 independent implementations for set_memory and
set_direct_map APIs.
With increasing demand for kernel page table manipulations, for example
"Direct Map Removal Support for guest_memfd" [1] and "mm: ASI direct map
management" [2], it makes sense to have a generic core for kernel page
table manipulation in mm/ with helpers in the architecture specific
code.
Coincidentally, there was a recent fix to a UAF bug [3] that had to
touch set memory functionality in subtly different way in different
architectures rather than to fix the core logic in a single place.
x86's implementation is the most versatile and most battle tested and as
such it is the best base for the generic implementation.
As the first step, pull x86 implementation to core mm code and convert
loongarch and riscv to use the new CPA core. These architectures were
chosen because the conversion is quite straight forward and does not
require tens of preparation patches.
Once this settles, the next step I'm planning is to convert arm64. This
would be much more involved than loongarch and riscv together, so I
didn't even aspire to include arm64 in the first RFC. That said, I have
a very ugly arm64 prototype that rewrites arch/arm64/pageattr.c to use
the generic CPA infrastructure and replaces the existing implementation
of page table splits for systems that support bbml2. But there's a lot
of yak shaving there to get from a PoC to actual patches.
Patch 1 is already applied to the tip tree and I posted patch 2
separately [4], but I included them both here for the completeness.
Patches 3-10 reorganize x86 CPA implementation to make it friendlier
for generalization.
Patches 11-14 move CPA core and CPA test from x86 to mm/ and slightly
massage the code to allow its use on other architectures.
Patches 15-16 convert riscv to use the common core and adjust riscv
implementation of _noflush APIs to actually be _noflush.
Patches 17-18 convert loongarch to use the common core and adjust
loongarch implementation of _noflush APIs to actually be _noflush.
The patches are lightly tested on x86 and riscv and build tested on
loongarch.
When converting riscv and loongarch my goal was to keep the new
implementation equivalent to the existing (except the _noflush bit), but
I must say that they way loongarch updates permissions for the entire
large leafs rather than splitting them seems a bit suspicious to me.
Regarding AI use, I started with a two-page prompt describing what I
want and how I want it and then it took me about 10 iterations of
additional half-pagers to explain why I don't like what LLM produced.
In the end I despaired to make it write commit messages the way I like
and edited them manually.
With that, the tool was really instrumental with conflicts resolution
during rebases and building and testing with a single "go!" command.
[1] https://lore.kernel.org/all/20260410151746.61150-1-kalyazin@xxxxxxxxxx
[2] https://lore.kernel.org/all/20250924-b4-asi-page-alloc-v1-0-2d861768041f@xxxxxxxxxx/
[3] https://lore.kernel.org/all/20260717-series-vmap-race-fix-v5-0-606a0ac6d3e5@xxxxxxxxxx
[4] https://lore.kernel.org/all/20260717-verify-rwx-fix-v2-1-fc23141311d6@xxxxxxxxxx
To: linux-mm@xxxxxxxxx
Cc: Albert Ou <aou@xxxxxxxxxxxxxxxxx>
Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
Cc: Andy Lutomirski <luto@xxxxxxxxxx>
Cc: Borislav Petkov <bp@xxxxxxxxx>
Cc: Brendan Jackman <jackmanb@xxxxxxxxxx>
Cc: Catalin Marinas <catalin.marinas@xxxxxxx>
Cc: Dave Hansen <dave.hansen@xxxxxxxxxxxxxxx>
Cc: David Hildenbrand <david@xxxxxxxxxx>
Cc: Huacai Chen <chenhuacai@xxxxxxxxxx>
Cc: Ingo Molnar <mingo@xxxxxxxxxx>
Cc: Ingo Molnar <mingo@xxxxxxxxxx>
Cc: Kevin Brodsky <kevin.brodsky@xxxxxxx>
Cc: "Liam R. Howlett" <liam@xxxxxxxxxxxxx>
Cc: Lorenzo Stoakes <ljs@xxxxxxxxxx>
Cc: Michal Hocko <mhocko@xxxxxxxx>
Cc: Mike Rapoport <rppt@xxxxxxxxxx>
Cc: Palmer Dabbelt <palmer@xxxxxxxxxxx>
Cc: Paul Walmsley <pjw@xxxxxxxxxx>
Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
Cc: "H. Peter Anvin" <hpa@xxxxxxxxx>
Cc: Suren Baghdasaryan <surenb@xxxxxxxxxx>
Cc: Thomas Gleixner <tglx@xxxxxxxxxx>
Cc: Vlastimil Babka <vbabka@xxxxxxxxxx>
Cc: Will Deacon <will@xxxxxxxxxx>
Cc: linux-arm-kernel@xxxxxxxxxxxxxxxxxxx
Cc: linux-kernel@xxxxxxxxxxxxxxx
Cc: linux-riscv@xxxxxxxxxxxxxxxxxxx
Cc: loongarch@xxxxxxxxxxxxxxx
Cc: x86@xxxxxxxxxx
Signed-off-by: Mike Rapoport (Microsoft) <rppt@xxxxxxxxxx>
---
Mike Rapoport (Microsoft) (18):
x86/mm/pat: Don't gate cpa_lock on debug_pagealloc_enabled()
x86/mm/pat: fix effective RW computation in lookup_address_in_pgd_attr()
x86/mm/pat: replace x86-speficic pg_level with generic pgtable_level
x86/mm/pat: use page table accessors for effective RW/NX bits
x86/mm/pat: use a generic helper for the large page size
x86/mm/pat: introduce an inline helper to check if alias needs update
x86/mm/pat: introduce cpa_handle_large_page()
x86/mm/pat: use cpa_split_data structure to pass split parameters
x86/mm/pat: use a single locked lookup for PTE verification
x86/mm/pat: move the large page size calculation to should_split_large_page
x86/mm/pat, mm: set_memory: pull change_page_attr() core to mm/
x86/pat/mm, mm/set_memory: abstract the CPA page table lock
mm/set_memory: read page table entries with pXdp_get()
x86/mm/pat, mm: move cpa-test to mm
riscv: convert set_memory to the generic CPA implementation
riscv: make set_direct_map_*_noflush actually noflush
loongarch: convert set_memory to the generic CPA implementation
loongarch: make set_direct_map_*_noflush actually noflush
arch/loongarch/Kconfig | 1 +
arch/loongarch/include/asm/pgtable.h | 42 +++
arch/loongarch/include/asm/set_memory.h | 9 +
arch/loongarch/mm/pageattr.c | 196 ++++------
arch/riscv/Kconfig | 1 +
arch/riscv/include/asm/pgtable.h | 36 ++
arch/riscv/include/asm/set_memory.h | 7 +
arch/riscv/mm/pageattr.c | 489 ++++++++-----------------
arch/x86/Kconfig | 1 +
arch/x86/Kconfig.debug | 6 -
arch/x86/include/asm/pgtable.h | 36 ++
arch/x86/include/asm/set_memory.h | 50 +++
arch/x86/mm/pat/set_memory.c | 611 ++++----------------------------
include/linux/pgtable.h | 72 +++-
include/linux/set_memory.h | 97 +++++
mm/Kconfig | 3 +
mm/Kconfig.debug | 7 +
mm/Makefile | 1 +
{arch/x86/mm/pat => mm}/cpa-test.c | 66 ++--
mm/set_memory.c | 396 +++++++++++++++++++++
20 files changed, 1092 insertions(+), 1035 deletions(-)
---
base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
change-id: 20260721-generic-set-memory-v0-1-06547a00b2ae
--
Sincerely yours,
Mike.