* [PATCH 00/22] Simplify special kernel page table handling
@ 2026-07-14 14:03 ` Kevin Brodsky
0 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:03 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
Page table constructors and destructors were originally introduced
specifically for user PTE pages. Over time, their use became more
widespread, and starting from v6.16 they are called at all levels
and for both user and kernel page tables [1]. Or so I thought. Turns
out, we still have various special kernel page tables where the
ctor/dtor are not called; vmemmap page tables is one such case.
Looking closer, we do not actually need per-level ctors for kernel
page tables. In fact we do not need ctors for them at all, because
nothing is specific to kernel page tables in the ctor/dtor and
nowadays they should be allocated with pagetable_alloc().
Here's the plan: all the generic page table handling moves to
pagetable_{alloc,free}(). Whatever is left is specific to user page
tables; the ctor/dtor are only called for user page tables at the
required levels (PTE/PMD), and renamed to make that clear.
Doing this will allow us to remove a good amount of special casing,
but there's quite a bit of churn to get there. Here's what this
series does:
1. Introduce the concept of "kernel mm" and replace most comparisons
with &init_mm with a flag check (patch 1-12); no functional change
so far.
2. Move the page table accounting/type setting to pagetable_{alloc,free}
(patch 13-15). Kernel mm's do not need to call the ctor/dtor any
more.
3. Mark special mm's (efi_mm, tboot_mm on x86) as kernel mm's (patch
16-19). They now abide by the same rules as init_mm, which means
in particular that split page table locks are no longer used.
4. Remove the ctor/dtor calls (now no-ops) for special kernel page
tables on arm/arm64/riscv (patch 20-22).
[1] https://lore.kernel.org/all/20250408095222.860601-1-kevin.brodsky@arm.com/
---
I stopped there for part 1 to keep it digestible. Part 2 will then
ensure that the ctor/dtor are only called for user PTE/PMD pages and
rename them accordingly. This is comparatively simpler but also
involves a lot of churn.
This series was suggested in reaction to [2]; removing dtor calls
entirely for kernel page tables systematically solves such issues.
Worth noting that some comparisons against &init_mm have been left
untouched, as they are truly specific to init_mm. Reviewers are
encouraged to take a look at the remaining cases:
$ git grep -nE '([=!]= *&init_mm|&init_mm *[=!]=)'
Documentation/mm/active_mm.rst:78: if (current->mm == &init_mm)
Documentation/translations/zh_CN/mm/active_mm.rst:76: if (current->mm == &init_mm)
arch/arm/include/asm/mmu_context.h:144: if (mm != &init_mm)
arch/arm64/include/asm/mmu_context.h:100: if (mm != &init_mm && !system_uses_ttbr0_pan())
arch/arm64/include/asm/mmu_context.h:210: if (mm == &init_mm)
arch/arm64/include/asm/mmu_context.h:242: if (next == &init_mm) {
arch/arm64/mm/fault.c:121: if (mm == &init_mm)
arch/arm64/mm/fault.c:139: if (mm == &init_mm) {
arch/arm64/mm/fault.c:154: mm == &init_mm ? "swapper" : "user", PAGE_SIZE / SZ_1K,
arch/arm64/mm/mmu.c:997: BUG_ON(mm == &init_mm);
arch/powerpc/xmon/xmon.c:3314: if (mm == &init_mm)
arch/riscv/mm/fault.c:42: mm == &init_mm ? (u64)__pa_symbol(mm->pgd) : virt_to_phys(mm->pgd));
kernel/cpu.c:917: WARN_ON(mm != &init_mm);
kernel/fork.c:725: BUG_ON(mm == &init_mm);
kernel/sched/core.c:8390: if (mm != &init_mm) {
mm/ptdump.c:182: if (mm != &init_mm)
mm/ptdump.c:191: if (mm != &init_mm)
Testing:
* Built all modified architectures
* arm64
- mm kselftests (FVP)
- Hot adding/removing memory + memory-hotplug kselftests (QEMU)
- Reading /sys/kernel/debug/{efi,kernel}_page_tables
- Reading from /sys/firmware/efi/efivars/
*riscv
- memory-hotplug kselftests (QEMU)
* x86
- mm kselftests (lkvm)
- tboot page table setup using a fake tboot shared page (QEMU)
- CONFIG_EFI_PGT_DUMP=y (QEMU)
Patches based on mm-unstable.
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
[2] https://lore.kernel.org/all/20260521032730.2104017-1-apopple@nvidia.com/
---
To: linux-mm@kvack.org
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: "Liam R. Howlett" <liam@infradead.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Huacai Chen <chenhuacai@kernel.org>
Cc: loongarch@lists.linux.dev
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: Helge Deller <deller@gmx.de>
Cc: linux-parisc@vger.kernel.org
Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Paul Walmsley <pjw@kernel.org>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: linux-riscv@lists.infradead.org
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
Cc: linux-s390@vger.kernel.org
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Andreas Larsson <andreas@gaisler.com>
Cc: sparclinux@vger.kernel.org
Cc: Richard Weinberger <richard@nod.at>
Cc: Anton Ivanov <anton.ivanov@cambridgegreys.com>
Cc: Johannes Berg <johannes@sipsolutions.net>
Cc: linux-um@lists.infradead.org
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ning Sun <ning.sun@intel.com>
Cc: x86@kernel.org
Cc: tboot-devel@lists.sourceforge.net
Cc: Ard Biesheuvel <ardb@kernel.org>
Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Cc: linux-efi@vger.kernel.org
Cc: Vishal Moola <vishal.moola@gmail.com>
Cc: Alistair Popple <apopple@nvidia.com>
Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Cc: linux-kernel@vger.kernel.org
Cc: linux-arch@vger.kernel.org
---
Kevin Brodsky (22):
mm: drop unused __mm_flags_set_mask_bits_word()
mm: move mm_flags helpers to mm_types.h
mm: introduce MMF_KERNEL flag and set it for init_mm
mm: use mm_is_kernel() in generic page table code
arm64: mm: use mm_is_kernel() for kernel mm checks
loongarch: mm: use mm_is_kernel() in switch_mm_irqs_off()
parisc: mm: use mm_is_kernel() for kernel mm checks
powerpc: mm: use mm_is_kernel() for kernel mm checks
s390: mm: use mm_is_kernel() for kernel mm checks
sparc: mm: use mm_is_kernel() for kernel mm checks
um: mm: use mm_is_kernel() in TLB sync
x86/mm: use mm_is_kernel() for kernel mm checks
mm: account page table pages when allocated
mm: set page table page type when allocated
mm: only initialise pt_share_count for user pgtables
efi: mark efi_mm as a kernel mm
mm: pagewalk: drop redundant address check for kernel mm walks
arm64: mm: drop explicit mm_is_efi() check in contpte
x86/tboot: mark tboot_mm as a kernel mm
arm64: mm: drop ctor/dtor calls for kernel page tables
arm: mm: drop ctor call for kernel page tables
riscv: mm: drop ctor/dtor calls for kernel page tables
arch/arm/mm/mmu.c | 3 +-
arch/arm64/include/asm/pgalloc.h | 10 ++--
arch/arm64/mm/contpte.c | 26 ++++------
arch/arm64/mm/hugetlbpage.c | 2 +-
arch/arm64/mm/mmu.c | 82 +++++++++-----------------------
arch/loongarch/include/asm/mmu_context.h | 2 +-
arch/parisc/include/asm/mmu_context.h | 2 +-
arch/parisc/include/asm/pgalloc.h | 2 +-
arch/parisc/include/asm/tlbflush.h | 2 +-
arch/powerpc/include/asm/pgalloc.h | 2 +-
arch/powerpc/mm/book3s64/pgtable.c | 2 +-
arch/powerpc/mm/mmu_context.c | 2 +-
arch/powerpc/mm/pgtable.c | 2 +-
arch/riscv/mm/init.c | 63 ++++++------------------
arch/s390/include/asm/mmu_context.h | 2 +-
arch/s390/include/asm/pgtable.h | 6 +--
arch/s390/mm/pgalloc.c | 4 +-
arch/sparc/include/asm/mmu_context_64.h | 2 +-
arch/sparc/include/asm/pgtable_64.h | 6 +--
arch/sparc/mm/init_64.c | 2 +-
arch/sparc/mm/tlb.c | 2 +-
arch/um/kernel/tlb.c | 2 +-
arch/x86/include/asm/tlbflush.h | 8 ++--
arch/x86/kernel/tboot.c | 4 +-
arch/x86/mm/pgtable.c | 2 +-
arch/x86/mm/tlb.c | 9 ++--
drivers/firmware/efi/efi.c | 1 +
include/asm-generic/pgalloc.h | 16 +++----
include/linux/mm.h | 69 +++++++--------------------
include/linux/mm_types.h | 52 +++++++++++++++-----
mm/init-mm.c | 1 +
mm/memory.c | 6 +--
mm/page_table_check.c | 14 +++---
mm/pagewalk.c | 7 +--
34 files changed, 163 insertions(+), 254 deletions(-)
---
base-commit: a531f0cf705af3374388eafe4115f651c625d8db
change-id: 20260611-remove_pgtable_cdtor-3b123938f8cd
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 00/22] Simplify special kernel page table handling
@ 2026-07-14 14:03 ` Kevin Brodsky
0 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:03 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
Page table constructors and destructors were originally introduced
specifically for user PTE pages. Over time, their use became more
widespread, and starting from v6.16 they are called at all levels
and for both user and kernel page tables [1]. Or so I thought. Turns
out, we still have various special kernel page tables where the
ctor/dtor are not called; vmemmap page tables is one such case.
Looking closer, we do not actually need per-level ctors for kernel
page tables. In fact we do not need ctors for them at all, because
nothing is specific to kernel page tables in the ctor/dtor and
nowadays they should be allocated with pagetable_alloc().
Here's the plan: all the generic page table handling moves to
pagetable_{alloc,free}(). Whatever is left is specific to user page
tables; the ctor/dtor are only called for user page tables at the
required levels (PTE/PMD), and renamed to make that clear.
Doing this will allow us to remove a good amount of special casing,
but there's quite a bit of churn to get there. Here's what this
series does:
1. Introduce the concept of "kernel mm" and replace most comparisons
with &init_mm with a flag check (patch 1-12); no functional change
so far.
2. Move the page table accounting/type setting to pagetable_{alloc,free}
(patch 13-15). Kernel mm's do not need to call the ctor/dtor any
more.
3. Mark special mm's (efi_mm, tboot_mm on x86) as kernel mm's (patch
16-19). They now abide by the same rules as init_mm, which means
in particular that split page table locks are no longer used.
4. Remove the ctor/dtor calls (now no-ops) for special kernel page
tables on arm/arm64/riscv (patch 20-22).
[1] https://lore.kernel.org/all/20250408095222.860601-1-kevin.brodsky@arm.com/
---
I stopped there for part 1 to keep it digestible. Part 2 will then
ensure that the ctor/dtor are only called for user PTE/PMD pages and
rename them accordingly. This is comparatively simpler but also
involves a lot of churn.
This series was suggested in reaction to [2]; removing dtor calls
entirely for kernel page tables systematically solves such issues.
Worth noting that some comparisons against &init_mm have been left
untouched, as they are truly specific to init_mm. Reviewers are
encouraged to take a look at the remaining cases:
$ git grep -nE '([=!]= *&init_mm|&init_mm *[=!]=)'
Documentation/mm/active_mm.rst:78: if (current->mm == &init_mm)
Documentation/translations/zh_CN/mm/active_mm.rst:76: if (current->mm == &init_mm)
arch/arm/include/asm/mmu_context.h:144: if (mm != &init_mm)
arch/arm64/include/asm/mmu_context.h:100: if (mm != &init_mm && !system_uses_ttbr0_pan())
arch/arm64/include/asm/mmu_context.h:210: if (mm == &init_mm)
arch/arm64/include/asm/mmu_context.h:242: if (next == &init_mm) {
arch/arm64/mm/fault.c:121: if (mm == &init_mm)
arch/arm64/mm/fault.c:139: if (mm == &init_mm) {
arch/arm64/mm/fault.c:154: mm == &init_mm ? "swapper" : "user", PAGE_SIZE / SZ_1K,
arch/arm64/mm/mmu.c:997: BUG_ON(mm == &init_mm);
arch/powerpc/xmon/xmon.c:3314: if (mm == &init_mm)
arch/riscv/mm/fault.c:42: mm == &init_mm ? (u64)__pa_symbol(mm->pgd) : virt_to_phys(mm->pgd));
kernel/cpu.c:917: WARN_ON(mm != &init_mm);
kernel/fork.c:725: BUG_ON(mm == &init_mm);
kernel/sched/core.c:8390: if (mm != &init_mm) {
mm/ptdump.c:182: if (mm != &init_mm)
mm/ptdump.c:191: if (mm != &init_mm)
Testing:
* Built all modified architectures
* arm64
- mm kselftests (FVP)
- Hot adding/removing memory + memory-hotplug kselftests (QEMU)
- Reading /sys/kernel/debug/{efi,kernel}_page_tables
- Reading from /sys/firmware/efi/efivars/
*riscv
- memory-hotplug kselftests (QEMU)
* x86
- mm kselftests (lkvm)
- tboot page table setup using a fake tboot shared page (QEMU)
- CONFIG_EFI_PGT_DUMP=y (QEMU)
Patches based on mm-unstable.
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
[2] https://lore.kernel.org/all/20260521032730.2104017-1-apopple@nvidia.com/
---
To: linux-mm@kvack.org
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: "Liam R. Howlett" <liam@infradead.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Huacai Chen <chenhuacai@kernel.org>
Cc: loongarch@lists.linux.dev
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: Helge Deller <deller@gmx.de>
Cc: linux-parisc@vger.kernel.org
Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Paul Walmsley <pjw@kernel.org>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: linux-riscv@lists.infradead.org
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
Cc: linux-s390@vger.kernel.org
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Andreas Larsson <andreas@gaisler.com>
Cc: sparclinux@vger.kernel.org
Cc: Richard Weinberger <richard@nod.at>
Cc: Anton Ivanov <anton.ivanov@cambridgegreys.com>
Cc: Johannes Berg <johannes@sipsolutions.net>
Cc: linux-um@lists.infradead.org
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ning Sun <ning.sun@intel.com>
Cc: x86@kernel.org
Cc: tboot-devel@lists.sourceforge.net
Cc: Ard Biesheuvel <ardb@kernel.org>
Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Cc: linux-efi@vger.kernel.org
Cc: Vishal Moola <vishal.moola@gmail.com>
Cc: Alistair Popple <apopple@nvidia.com>
Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Cc: linux-kernel@vger.kernel.org
Cc: linux-arch@vger.kernel.org
---
Kevin Brodsky (22):
mm: drop unused __mm_flags_set_mask_bits_word()
mm: move mm_flags helpers to mm_types.h
mm: introduce MMF_KERNEL flag and set it for init_mm
mm: use mm_is_kernel() in generic page table code
arm64: mm: use mm_is_kernel() for kernel mm checks
loongarch: mm: use mm_is_kernel() in switch_mm_irqs_off()
parisc: mm: use mm_is_kernel() for kernel mm checks
powerpc: mm: use mm_is_kernel() for kernel mm checks
s390: mm: use mm_is_kernel() for kernel mm checks
sparc: mm: use mm_is_kernel() for kernel mm checks
um: mm: use mm_is_kernel() in TLB sync
x86/mm: use mm_is_kernel() for kernel mm checks
mm: account page table pages when allocated
mm: set page table page type when allocated
mm: only initialise pt_share_count for user pgtables
efi: mark efi_mm as a kernel mm
mm: pagewalk: drop redundant address check for kernel mm walks
arm64: mm: drop explicit mm_is_efi() check in contpte
x86/tboot: mark tboot_mm as a kernel mm
arm64: mm: drop ctor/dtor calls for kernel page tables
arm: mm: drop ctor call for kernel page tables
riscv: mm: drop ctor/dtor calls for kernel page tables
arch/arm/mm/mmu.c | 3 +-
arch/arm64/include/asm/pgalloc.h | 10 ++--
arch/arm64/mm/contpte.c | 26 ++++------
arch/arm64/mm/hugetlbpage.c | 2 +-
arch/arm64/mm/mmu.c | 82 +++++++++-----------------------
arch/loongarch/include/asm/mmu_context.h | 2 +-
arch/parisc/include/asm/mmu_context.h | 2 +-
arch/parisc/include/asm/pgalloc.h | 2 +-
arch/parisc/include/asm/tlbflush.h | 2 +-
arch/powerpc/include/asm/pgalloc.h | 2 +-
arch/powerpc/mm/book3s64/pgtable.c | 2 +-
arch/powerpc/mm/mmu_context.c | 2 +-
arch/powerpc/mm/pgtable.c | 2 +-
arch/riscv/mm/init.c | 63 ++++++------------------
arch/s390/include/asm/mmu_context.h | 2 +-
arch/s390/include/asm/pgtable.h | 6 +--
arch/s390/mm/pgalloc.c | 4 +-
arch/sparc/include/asm/mmu_context_64.h | 2 +-
arch/sparc/include/asm/pgtable_64.h | 6 +--
arch/sparc/mm/init_64.c | 2 +-
arch/sparc/mm/tlb.c | 2 +-
arch/um/kernel/tlb.c | 2 +-
arch/x86/include/asm/tlbflush.h | 8 ++--
arch/x86/kernel/tboot.c | 4 +-
arch/x86/mm/pgtable.c | 2 +-
arch/x86/mm/tlb.c | 9 ++--
drivers/firmware/efi/efi.c | 1 +
include/asm-generic/pgalloc.h | 16 +++----
include/linux/mm.h | 69 +++++++--------------------
include/linux/mm_types.h | 52 +++++++++++++++-----
mm/init-mm.c | 1 +
mm/memory.c | 6 +--
mm/page_table_check.c | 14 +++---
mm/pagewalk.c | 7 +--
34 files changed, 163 insertions(+), 254 deletions(-)
---
base-commit: a531f0cf705af3374388eafe4115f651c625d8db
change-id: 20260611-remove_pgtable_cdtor-3b123938f8cd
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 62+ messages in thread
* [PATCH 01/22] mm: drop unused __mm_flags_set_mask_bits_word()
2026-07-14 14:03 ` Kevin Brodsky
@ 2026-07-14 14:03 ` Kevin Brodsky
-1 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:03 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
Commit 39f8049cd49f ("mm: update coredump logic to correctly
use bitmap mm flags") added coredump-specific helpers for the
remaining masked mm-flags update users.
That left __mm_flags_set_mask_bits_word() without any callers.
This is a special-purpose helper that is unlikely to be useful for
other purposes; best to remove it.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
include/linux/mm_types.h | 12 ------------
1 file changed, 12 deletions(-)
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index ae9bca4eda5c..b4129beb9c4a 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -1432,18 +1432,6 @@ static inline unsigned long __mm_flags_get_word(const struct mm_struct *mm)
return *__mm_flags_get_bitmap(mm);
}
-/*
- * Update the first system word of mm flags ONLY, applying the specified mask to
- * it, then setting all flags specified by bits.
- */
-static inline void __mm_flags_set_mask_bits_word(struct mm_struct *mm,
- unsigned long mask, unsigned long bits)
-{
- unsigned long *bitmap = ACCESS_PRIVATE(&mm->flags, __mm_flags);
-
- set_mask_bits(bitmap, mask, bits);
-}
-
#define MM_MT_FLAGS (MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN | \
MT_FLAGS_USE_RCU)
extern struct mm_struct init_mm;
--
2.51.2
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 01/22] mm: drop unused __mm_flags_set_mask_bits_word()
@ 2026-07-14 14:03 ` Kevin Brodsky
0 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:03 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
Commit 39f8049cd49f ("mm: update coredump logic to correctly
use bitmap mm flags") added coredump-specific helpers for the
remaining masked mm-flags update users.
That left __mm_flags_set_mask_bits_word() without any callers.
This is a special-purpose helper that is unlikely to be useful for
other purposes; best to remove it.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
include/linux/mm_types.h | 12 ------------
1 file changed, 12 deletions(-)
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index ae9bca4eda5c..b4129beb9c4a 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -1432,18 +1432,6 @@ static inline unsigned long __mm_flags_get_word(const struct mm_struct *mm)
return *__mm_flags_get_bitmap(mm);
}
-/*
- * Update the first system word of mm flags ONLY, applying the specified mask to
- * it, then setting all flags specified by bits.
- */
-static inline void __mm_flags_set_mask_bits_word(struct mm_struct *mm,
- unsigned long mask, unsigned long bits)
-{
- unsigned long *bitmap = ACCESS_PRIVATE(&mm->flags, __mm_flags);
-
- set_mask_bits(bitmap, mask, bits);
-}
-
#define MM_MT_FLAGS (MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN | \
MT_FLAGS_USE_RCU)
extern struct mm_struct init_mm;
--
2.51.2
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 02/22] mm: move mm_flags helpers to mm_types.h
2026-07-14 14:03 ` Kevin Brodsky
@ 2026-07-14 14:03 ` Kevin Brodsky
-1 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:03 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
Some of the mm_flags helpers are defined in <linux/mm_types.h>,
while others are defined in <linux/mm.h>. We will soon need to call
one of the latter helpers from mm_types.h.
Regroup all the helpers in mm_types.h to keep things simple.
Also remove #include's that were added specifically for these
helpers in mm.h.
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
include/linux/mm.h | 32 --------------------------------
include/linux/mm_types.h | 30 ++++++++++++++++++++++++++++++
2 files changed, 30 insertions(+), 32 deletions(-)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 32bb723ffbb9..7a4b8e7ac8f4 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -34,8 +34,6 @@
#include <linux/slab.h>
#include <linux/cacheinfo.h>
#include <linux/rcuwait.h>
-#include <linux/bitmap.h>
-#include <linux/bitops.h>
#include <linux/iommu-debug-pagealloc.h>
#include <linux/kcsan-checks.h>
@@ -948,36 +946,6 @@ static inline void assert_fault_locked(const struct vm_fault *vmf)
}
#endif /* CONFIG_PER_VMA_LOCK */
-static inline bool mm_flags_test(int flag, const struct mm_struct *mm)
-{
- return test_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags));
-}
-
-static inline bool mm_flags_test_and_set(int flag, struct mm_struct *mm)
-{
- return test_and_set_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags));
-}
-
-static inline bool mm_flags_test_and_clear(int flag, struct mm_struct *mm)
-{
- return test_and_clear_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags));
-}
-
-static inline void mm_flags_set(int flag, struct mm_struct *mm)
-{
- set_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags));
-}
-
-static inline void mm_flags_clear(int flag, struct mm_struct *mm)
-{
- clear_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags));
-}
-
-static inline void mm_flags_clear_all(struct mm_struct *mm)
-{
- bitmap_zero(ACCESS_PRIVATE(&mm->flags, __mm_flags), NUM_MM_FLAG_BITS);
-}
-
extern const struct vm_operations_struct vma_dummy_vm_ops;
static inline void vma_init(struct vm_area_struct *vma, struct mm_struct *mm)
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index b4129beb9c4a..a2e0dc5892ff 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -1414,6 +1414,36 @@ struct mm_struct {
char flexible_array[] __aligned(__alignof__(unsigned long));
};
+static inline bool mm_flags_test(int flag, const struct mm_struct *mm)
+{
+ return test_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags));
+}
+
+static inline bool mm_flags_test_and_set(int flag, struct mm_struct *mm)
+{
+ return test_and_set_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags));
+}
+
+static inline bool mm_flags_test_and_clear(int flag, struct mm_struct *mm)
+{
+ return test_and_clear_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags));
+}
+
+static inline void mm_flags_set(int flag, struct mm_struct *mm)
+{
+ set_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags));
+}
+
+static inline void mm_flags_clear(int flag, struct mm_struct *mm)
+{
+ clear_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags));
+}
+
+static inline void mm_flags_clear_all(struct mm_struct *mm)
+{
+ bitmap_zero(ACCESS_PRIVATE(&mm->flags, __mm_flags), NUM_MM_FLAG_BITS);
+}
+
/* Copy value to the first system word of mm flags, non-atomically. */
static inline void __mm_flags_overwrite_word(struct mm_struct *mm, unsigned long value)
{
--
2.51.2
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 02/22] mm: move mm_flags helpers to mm_types.h
@ 2026-07-14 14:03 ` Kevin Brodsky
0 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:03 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
Some of the mm_flags helpers are defined in <linux/mm_types.h>,
while others are defined in <linux/mm.h>. We will soon need to call
one of the latter helpers from mm_types.h.
Regroup all the helpers in mm_types.h to keep things simple.
Also remove #include's that were added specifically for these
helpers in mm.h.
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
include/linux/mm.h | 32 --------------------------------
include/linux/mm_types.h | 30 ++++++++++++++++++++++++++++++
2 files changed, 30 insertions(+), 32 deletions(-)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 32bb723ffbb9..7a4b8e7ac8f4 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -34,8 +34,6 @@
#include <linux/slab.h>
#include <linux/cacheinfo.h>
#include <linux/rcuwait.h>
-#include <linux/bitmap.h>
-#include <linux/bitops.h>
#include <linux/iommu-debug-pagealloc.h>
#include <linux/kcsan-checks.h>
@@ -948,36 +946,6 @@ static inline void assert_fault_locked(const struct vm_fault *vmf)
}
#endif /* CONFIG_PER_VMA_LOCK */
-static inline bool mm_flags_test(int flag, const struct mm_struct *mm)
-{
- return test_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags));
-}
-
-static inline bool mm_flags_test_and_set(int flag, struct mm_struct *mm)
-{
- return test_and_set_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags));
-}
-
-static inline bool mm_flags_test_and_clear(int flag, struct mm_struct *mm)
-{
- return test_and_clear_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags));
-}
-
-static inline void mm_flags_set(int flag, struct mm_struct *mm)
-{
- set_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags));
-}
-
-static inline void mm_flags_clear(int flag, struct mm_struct *mm)
-{
- clear_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags));
-}
-
-static inline void mm_flags_clear_all(struct mm_struct *mm)
-{
- bitmap_zero(ACCESS_PRIVATE(&mm->flags, __mm_flags), NUM_MM_FLAG_BITS);
-}
-
extern const struct vm_operations_struct vma_dummy_vm_ops;
static inline void vma_init(struct vm_area_struct *vma, struct mm_struct *mm)
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index b4129beb9c4a..a2e0dc5892ff 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -1414,6 +1414,36 @@ struct mm_struct {
char flexible_array[] __aligned(__alignof__(unsigned long));
};
+static inline bool mm_flags_test(int flag, const struct mm_struct *mm)
+{
+ return test_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags));
+}
+
+static inline bool mm_flags_test_and_set(int flag, struct mm_struct *mm)
+{
+ return test_and_set_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags));
+}
+
+static inline bool mm_flags_test_and_clear(int flag, struct mm_struct *mm)
+{
+ return test_and_clear_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags));
+}
+
+static inline void mm_flags_set(int flag, struct mm_struct *mm)
+{
+ set_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags));
+}
+
+static inline void mm_flags_clear(int flag, struct mm_struct *mm)
+{
+ clear_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags));
+}
+
+static inline void mm_flags_clear_all(struct mm_struct *mm)
+{
+ bitmap_zero(ACCESS_PRIVATE(&mm->flags, __mm_flags), NUM_MM_FLAG_BITS);
+}
+
/* Copy value to the first system word of mm flags, non-atomically. */
static inline void __mm_flags_overwrite_word(struct mm_struct *mm, unsigned long value)
{
--
2.51.2
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 03/22] mm: introduce MMF_KERNEL flag and set it for init_mm
2026-07-14 14:03 ` Kevin Brodsky
@ 2026-07-14 14:03 ` Kevin Brodsky
-1 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:03 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
mm code often needs to know whether some mm represents a kernel or
user address space. This is currently done by comparing the mm
pointer with &init_mm; besides not being particularly elegant, this
ignores the fact that other mm's (e.g. efi_mm) may also represent
parts of the kernel address space.
Introduce a new mm flag MMF_KERNEL and set it for init_mm.
Subsequent patches will use this flag to replace comparisons with
&init_mm. No functional change is introduced for now.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
include/linux/mm_types.h | 10 ++++++++++
mm/init-mm.c | 1 +
2 files changed, 11 insertions(+)
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index a2e0dc5892ff..7838ea3aac00 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -1414,6 +1414,8 @@ struct mm_struct {
char flexible_array[] __aligned(__alignof__(unsigned long));
};
+#define MM_FLAGS_INIT(flags) { .__mm_flags = { BITMAP_FROM_U64(flags) } }
+
static inline bool mm_flags_test(int flag, const struct mm_struct *mm)
{
return test_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags));
@@ -2001,6 +2003,9 @@ enum {
#define MMF_TOPDOWN 31 /* mm searches top down by default */
#define MMF_TOPDOWN_MASK BIT(MMF_TOPDOWN)
+#define MMF_KERNEL 32 /* mm belongs to the kernel */
+#define MMF_KERNEL_MASK BIT_ULL(MMF_KERNEL)
+
#define MMF_INIT_LEGACY_MASK (MMF_DUMP_FILTER_MASK |\
MMF_DISABLE_THP_MASK | MMF_HAS_MDWE_MASK |\
MMF_VM_MERGE_ANY_MASK | MMF_TOPDOWN_MASK)
@@ -2008,6 +2013,11 @@ enum {
/* Legacy flags must fit within 32 bits. */
static_assert((u64)MMF_INIT_LEGACY_MASK <= (u64)UINT_MAX);
+static inline bool mm_is_kernel(const struct mm_struct *mm)
+{
+ return mm && mm_flags_test(MMF_KERNEL, mm);
+}
+
/*
* Initialise legacy flags according to masks, propagating selected flags on
* fork. Further flag manipulation can be performed by the caller.
diff --git a/mm/init-mm.c b/mm/init-mm.c
index 3e792aad7626..93773269bf87 100644
--- a/mm/init-mm.c
+++ b/mm/init-mm.c
@@ -34,6 +34,7 @@ struct mm_struct init_mm = {
.pgd = swapper_pg_dir,
.mm_users = ATOMIC_INIT(2),
.mm_count = ATOMIC_INIT(1),
+ .flags = MM_FLAGS_INIT(MMF_KERNEL_MASK),
.write_protect_seq = SEQCNT_ZERO(init_mm.write_protect_seq),
MMAP_LOCK_INITIALIZER(init_mm)
.page_table_lock = __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock),
--
2.51.2
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 03/22] mm: introduce MMF_KERNEL flag and set it for init_mm
@ 2026-07-14 14:03 ` Kevin Brodsky
0 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:03 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
mm code often needs to know whether some mm represents a kernel or
user address space. This is currently done by comparing the mm
pointer with &init_mm; besides not being particularly elegant, this
ignores the fact that other mm's (e.g. efi_mm) may also represent
parts of the kernel address space.
Introduce a new mm flag MMF_KERNEL and set it for init_mm.
Subsequent patches will use this flag to replace comparisons with
&init_mm. No functional change is introduced for now.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
include/linux/mm_types.h | 10 ++++++++++
mm/init-mm.c | 1 +
2 files changed, 11 insertions(+)
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index a2e0dc5892ff..7838ea3aac00 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -1414,6 +1414,8 @@ struct mm_struct {
char flexible_array[] __aligned(__alignof__(unsigned long));
};
+#define MM_FLAGS_INIT(flags) { .__mm_flags = { BITMAP_FROM_U64(flags) } }
+
static inline bool mm_flags_test(int flag, const struct mm_struct *mm)
{
return test_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags));
@@ -2001,6 +2003,9 @@ enum {
#define MMF_TOPDOWN 31 /* mm searches top down by default */
#define MMF_TOPDOWN_MASK BIT(MMF_TOPDOWN)
+#define MMF_KERNEL 32 /* mm belongs to the kernel */
+#define MMF_KERNEL_MASK BIT_ULL(MMF_KERNEL)
+
#define MMF_INIT_LEGACY_MASK (MMF_DUMP_FILTER_MASK |\
MMF_DISABLE_THP_MASK | MMF_HAS_MDWE_MASK |\
MMF_VM_MERGE_ANY_MASK | MMF_TOPDOWN_MASK)
@@ -2008,6 +2013,11 @@ enum {
/* Legacy flags must fit within 32 bits. */
static_assert((u64)MMF_INIT_LEGACY_MASK <= (u64)UINT_MAX);
+static inline bool mm_is_kernel(const struct mm_struct *mm)
+{
+ return mm && mm_flags_test(MMF_KERNEL, mm);
+}
+
/*
* Initialise legacy flags according to masks, propagating selected flags on
* fork. Further flag manipulation can be performed by the caller.
diff --git a/mm/init-mm.c b/mm/init-mm.c
index 3e792aad7626..93773269bf87 100644
--- a/mm/init-mm.c
+++ b/mm/init-mm.c
@@ -34,6 +34,7 @@ struct mm_struct init_mm = {
.pgd = swapper_pg_dir,
.mm_users = ATOMIC_INIT(2),
.mm_count = ATOMIC_INIT(1),
+ .flags = MM_FLAGS_INIT(MMF_KERNEL_MASK),
.write_protect_seq = SEQCNT_ZERO(init_mm.write_protect_seq),
MMAP_LOCK_INITIALIZER(init_mm)
.page_table_lock = __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock),
--
2.51.2
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 04/22] mm: use mm_is_kernel() in generic page table code
2026-07-14 14:03 ` Kevin Brodsky
@ 2026-07-14 14:03 ` Kevin Brodsky
-1 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:03 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
Generic page-table allocation, constructor and walker code uses
init_mm comparisons to select kernel page table handling. Use
mm_is_kernel() instead so kernel-owned mm's can share that handling
once they are marked with MMF_KERNEL.
No functional change as only init_mm has MMF_KERNEL set for now.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
include/asm-generic/pgalloc.h | 16 ++++++++--------
include/linux/mm.h | 4 ++--
mm/memory.c | 6 +++---
mm/page_table_check.c | 14 +++++++-------
mm/pagewalk.c | 4 ++--
5 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/include/asm-generic/pgalloc.h b/include/asm-generic/pgalloc.h
index 051aa1331051..a283280e3140 100644
--- a/include/asm-generic/pgalloc.h
+++ b/include/asm-generic/pgalloc.h
@@ -138,7 +138,7 @@ static inline pmd_t *pmd_alloc_one_noprof(struct mm_struct *mm, unsigned long ad
struct ptdesc *ptdesc;
gfp_t gfp = GFP_PGTABLE_USER;
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
gfp = GFP_PGTABLE_KERNEL;
ptdesc = pagetable_alloc_noprof(gfp, 0);
if (!ptdesc)
@@ -148,7 +148,7 @@ static inline pmd_t *pmd_alloc_one_noprof(struct mm_struct *mm, unsigned long ad
return NULL;
}
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
ptdesc_set_kernel(ptdesc);
return ptdesc_address(ptdesc);
@@ -175,7 +175,7 @@ static inline pud_t *__pud_alloc_one_noprof(struct mm_struct *mm, unsigned long
gfp_t gfp = GFP_PGTABLE_USER;
struct ptdesc *ptdesc;
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
gfp = GFP_PGTABLE_KERNEL;
ptdesc = pagetable_alloc_noprof(gfp, 0);
@@ -184,7 +184,7 @@ static inline pud_t *__pud_alloc_one_noprof(struct mm_struct *mm, unsigned long
pagetable_pud_ctor(ptdesc);
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
ptdesc_set_kernel(ptdesc);
return ptdesc_address(ptdesc);
@@ -232,7 +232,7 @@ static inline p4d_t *__p4d_alloc_one_noprof(struct mm_struct *mm, unsigned long
gfp_t gfp = GFP_PGTABLE_USER;
struct ptdesc *ptdesc;
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
gfp = GFP_PGTABLE_KERNEL;
ptdesc = pagetable_alloc_noprof(gfp, 0);
@@ -241,7 +241,7 @@ static inline p4d_t *__p4d_alloc_one_noprof(struct mm_struct *mm, unsigned long
pagetable_p4d_ctor(ptdesc);
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
ptdesc_set_kernel(ptdesc);
return ptdesc_address(ptdesc);
@@ -279,7 +279,7 @@ static inline pgd_t *__pgd_alloc_noprof(struct mm_struct *mm, unsigned int order
gfp_t gfp = GFP_PGTABLE_USER;
struct ptdesc *ptdesc;
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
gfp = GFP_PGTABLE_KERNEL;
ptdesc = pagetable_alloc_noprof(gfp, order);
@@ -288,7 +288,7 @@ static inline pgd_t *__pgd_alloc_noprof(struct mm_struct *mm, unsigned int order
pagetable_pgd_ctor(ptdesc);
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
ptdesc_set_kernel(ptdesc);
return ptdesc_address(ptdesc);
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 7a4b8e7ac8f4..b336eb32faa0 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -3818,7 +3818,7 @@ static inline void pagetable_dtor_free(struct ptdesc *ptdesc)
static inline bool pagetable_pte_ctor(struct mm_struct *mm,
struct ptdesc *ptdesc)
{
- if (mm != &init_mm && !ptlock_init(ptdesc))
+ if (!mm_is_kernel(mm) && !ptlock_init(ptdesc))
return false;
__pagetable_ctor(ptdesc);
return true;
@@ -3909,7 +3909,7 @@ static inline spinlock_t *pmd_lock(struct mm_struct *mm, pmd_t *pmd)
static inline bool pagetable_pmd_ctor(struct mm_struct *mm,
struct ptdesc *ptdesc)
{
- if (mm != &init_mm && !pmd_ptlock_init(ptdesc))
+ if (!mm_is_kernel(mm) && !pmd_ptlock_init(ptdesc))
return false;
ptdesc_pmd_pts_init(ptdesc);
__pagetable_ctor(ptdesc);
diff --git a/mm/memory.c b/mm/memory.c
index d5e87624f692..c0244c0b0756 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -3394,13 +3394,13 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
spinlock_t *ptl;
if (create) {
- mapped_pte = pte = (mm == &init_mm) ?
+ mapped_pte = pte = mm_is_kernel(mm) ?
pte_alloc_kernel_track(pmd, addr, mask) :
pte_alloc_map_lock(mm, pmd, addr, &ptl);
if (!pte)
return -ENOMEM;
} else {
- mapped_pte = pte = (mm == &init_mm) ?
+ mapped_pte = pte = mm_is_kernel(mm) ?
pte_offset_kernel(pmd, addr) :
pte_offset_map_lock(mm, pmd, addr, &ptl);
if (!pte)
@@ -3422,7 +3422,7 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
lazy_mmu_mode_disable();
- if (mm != &init_mm)
+ if (!mm_is_kernel(mm))
pte_unmap_unlock(mapped_pte, ptl);
return err;
}
diff --git a/mm/page_table_check.c b/mm/page_table_check.c
index 3fb995e5d40d..a5382c245b32 100644
--- a/mm/page_table_check.c
+++ b/mm/page_table_check.c
@@ -148,7 +148,7 @@ void __page_table_check_zero(struct page *page, unsigned int order)
void __page_table_check_pte_clear(struct mm_struct *mm, unsigned long addr,
pte_t pte)
{
- if (&init_mm == mm)
+ if (mm_is_kernel(mm))
return;
if (pte_user_accessible_page(mm, addr, pte))
@@ -159,7 +159,7 @@ EXPORT_SYMBOL(__page_table_check_pte_clear);
void __page_table_check_pmd_clear(struct mm_struct *mm, unsigned long addr,
pmd_t pmd)
{
- if (&init_mm == mm)
+ if (mm_is_kernel(mm))
return;
if (pmd_user_accessible_page(mm, addr, pmd))
@@ -170,7 +170,7 @@ EXPORT_SYMBOL(__page_table_check_pmd_clear);
void __page_table_check_pud_clear(struct mm_struct *mm, unsigned long addr,
pud_t pud)
{
- if (&init_mm == mm)
+ if (mm_is_kernel(mm))
return;
if (pud_user_accessible_page(mm, addr, pud))
@@ -201,7 +201,7 @@ void __page_table_check_ptes_set(struct mm_struct *mm, unsigned long addr,
{
unsigned int i;
- if (&init_mm == mm)
+ if (mm_is_kernel(mm))
return;
page_table_check_pte_flags(pte);
@@ -231,7 +231,7 @@ void __page_table_check_pmds_set(struct mm_struct *mm, unsigned long addr,
unsigned long stride = PMD_SIZE >> PAGE_SHIFT;
unsigned int i;
- if (&init_mm == mm)
+ if (mm_is_kernel(mm))
return;
page_table_check_pmd_flags(pmd);
@@ -249,7 +249,7 @@ void __page_table_check_puds_set(struct mm_struct *mm, unsigned long addr,
unsigned long stride = PUD_SIZE >> PAGE_SHIFT;
unsigned int i;
- if (&init_mm == mm)
+ if (mm_is_kernel(mm))
return;
for (i = 0; i < nr; i++)
@@ -263,7 +263,7 @@ void __page_table_check_pte_clear_range(struct mm_struct *mm,
unsigned long addr,
pmd_t pmd)
{
- if (&init_mm == mm)
+ if (mm_is_kernel(mm))
return;
if (!pmd_bad(pmd) && !pmd_leaf(pmd)) {
diff --git a/mm/pagewalk.c b/mm/pagewalk.c
index ed4860c01936..a3f47d1de3c5 100644
--- a/mm/pagewalk.c
+++ b/mm/pagewalk.c
@@ -72,13 +72,13 @@ static int walk_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
* fit its pmd_bad() check (_PAGE_NX set and _PAGE_RW clear),
* and CONFIG_EFI_PGT_DUMP efi_mm goes so far as to walk them.
*/
- if (walk->mm == &init_mm || addr >= TASK_SIZE)
+ if (mm_is_kernel(walk->mm) || addr >= TASK_SIZE)
pte = pte_offset_kernel(pmd, addr);
else
pte = pte_offset_map(pmd, addr);
if (pte) {
err = walk_pte_range_inner(pte, addr, end, walk);
- if (walk->mm != &init_mm && addr < TASK_SIZE)
+ if (!mm_is_kernel(walk->mm) && addr < TASK_SIZE)
pte_unmap(pte);
}
} else {
--
2.51.2
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 04/22] mm: use mm_is_kernel() in generic page table code
@ 2026-07-14 14:03 ` Kevin Brodsky
0 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:03 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
Generic page-table allocation, constructor and walker code uses
init_mm comparisons to select kernel page table handling. Use
mm_is_kernel() instead so kernel-owned mm's can share that handling
once they are marked with MMF_KERNEL.
No functional change as only init_mm has MMF_KERNEL set for now.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
include/asm-generic/pgalloc.h | 16 ++++++++--------
include/linux/mm.h | 4 ++--
mm/memory.c | 6 +++---
mm/page_table_check.c | 14 +++++++-------
mm/pagewalk.c | 4 ++--
5 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/include/asm-generic/pgalloc.h b/include/asm-generic/pgalloc.h
index 051aa1331051..a283280e3140 100644
--- a/include/asm-generic/pgalloc.h
+++ b/include/asm-generic/pgalloc.h
@@ -138,7 +138,7 @@ static inline pmd_t *pmd_alloc_one_noprof(struct mm_struct *mm, unsigned long ad
struct ptdesc *ptdesc;
gfp_t gfp = GFP_PGTABLE_USER;
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
gfp = GFP_PGTABLE_KERNEL;
ptdesc = pagetable_alloc_noprof(gfp, 0);
if (!ptdesc)
@@ -148,7 +148,7 @@ static inline pmd_t *pmd_alloc_one_noprof(struct mm_struct *mm, unsigned long ad
return NULL;
}
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
ptdesc_set_kernel(ptdesc);
return ptdesc_address(ptdesc);
@@ -175,7 +175,7 @@ static inline pud_t *__pud_alloc_one_noprof(struct mm_struct *mm, unsigned long
gfp_t gfp = GFP_PGTABLE_USER;
struct ptdesc *ptdesc;
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
gfp = GFP_PGTABLE_KERNEL;
ptdesc = pagetable_alloc_noprof(gfp, 0);
@@ -184,7 +184,7 @@ static inline pud_t *__pud_alloc_one_noprof(struct mm_struct *mm, unsigned long
pagetable_pud_ctor(ptdesc);
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
ptdesc_set_kernel(ptdesc);
return ptdesc_address(ptdesc);
@@ -232,7 +232,7 @@ static inline p4d_t *__p4d_alloc_one_noprof(struct mm_struct *mm, unsigned long
gfp_t gfp = GFP_PGTABLE_USER;
struct ptdesc *ptdesc;
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
gfp = GFP_PGTABLE_KERNEL;
ptdesc = pagetable_alloc_noprof(gfp, 0);
@@ -241,7 +241,7 @@ static inline p4d_t *__p4d_alloc_one_noprof(struct mm_struct *mm, unsigned long
pagetable_p4d_ctor(ptdesc);
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
ptdesc_set_kernel(ptdesc);
return ptdesc_address(ptdesc);
@@ -279,7 +279,7 @@ static inline pgd_t *__pgd_alloc_noprof(struct mm_struct *mm, unsigned int order
gfp_t gfp = GFP_PGTABLE_USER;
struct ptdesc *ptdesc;
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
gfp = GFP_PGTABLE_KERNEL;
ptdesc = pagetable_alloc_noprof(gfp, order);
@@ -288,7 +288,7 @@ static inline pgd_t *__pgd_alloc_noprof(struct mm_struct *mm, unsigned int order
pagetable_pgd_ctor(ptdesc);
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
ptdesc_set_kernel(ptdesc);
return ptdesc_address(ptdesc);
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 7a4b8e7ac8f4..b336eb32faa0 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -3818,7 +3818,7 @@ static inline void pagetable_dtor_free(struct ptdesc *ptdesc)
static inline bool pagetable_pte_ctor(struct mm_struct *mm,
struct ptdesc *ptdesc)
{
- if (mm != &init_mm && !ptlock_init(ptdesc))
+ if (!mm_is_kernel(mm) && !ptlock_init(ptdesc))
return false;
__pagetable_ctor(ptdesc);
return true;
@@ -3909,7 +3909,7 @@ static inline spinlock_t *pmd_lock(struct mm_struct *mm, pmd_t *pmd)
static inline bool pagetable_pmd_ctor(struct mm_struct *mm,
struct ptdesc *ptdesc)
{
- if (mm != &init_mm && !pmd_ptlock_init(ptdesc))
+ if (!mm_is_kernel(mm) && !pmd_ptlock_init(ptdesc))
return false;
ptdesc_pmd_pts_init(ptdesc);
__pagetable_ctor(ptdesc);
diff --git a/mm/memory.c b/mm/memory.c
index d5e87624f692..c0244c0b0756 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -3394,13 +3394,13 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
spinlock_t *ptl;
if (create) {
- mapped_pte = pte = (mm == &init_mm) ?
+ mapped_pte = pte = mm_is_kernel(mm) ?
pte_alloc_kernel_track(pmd, addr, mask) :
pte_alloc_map_lock(mm, pmd, addr, &ptl);
if (!pte)
return -ENOMEM;
} else {
- mapped_pte = pte = (mm == &init_mm) ?
+ mapped_pte = pte = mm_is_kernel(mm) ?
pte_offset_kernel(pmd, addr) :
pte_offset_map_lock(mm, pmd, addr, &ptl);
if (!pte)
@@ -3422,7 +3422,7 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
lazy_mmu_mode_disable();
- if (mm != &init_mm)
+ if (!mm_is_kernel(mm))
pte_unmap_unlock(mapped_pte, ptl);
return err;
}
diff --git a/mm/page_table_check.c b/mm/page_table_check.c
index 3fb995e5d40d..a5382c245b32 100644
--- a/mm/page_table_check.c
+++ b/mm/page_table_check.c
@@ -148,7 +148,7 @@ void __page_table_check_zero(struct page *page, unsigned int order)
void __page_table_check_pte_clear(struct mm_struct *mm, unsigned long addr,
pte_t pte)
{
- if (&init_mm == mm)
+ if (mm_is_kernel(mm))
return;
if (pte_user_accessible_page(mm, addr, pte))
@@ -159,7 +159,7 @@ EXPORT_SYMBOL(__page_table_check_pte_clear);
void __page_table_check_pmd_clear(struct mm_struct *mm, unsigned long addr,
pmd_t pmd)
{
- if (&init_mm == mm)
+ if (mm_is_kernel(mm))
return;
if (pmd_user_accessible_page(mm, addr, pmd))
@@ -170,7 +170,7 @@ EXPORT_SYMBOL(__page_table_check_pmd_clear);
void __page_table_check_pud_clear(struct mm_struct *mm, unsigned long addr,
pud_t pud)
{
- if (&init_mm == mm)
+ if (mm_is_kernel(mm))
return;
if (pud_user_accessible_page(mm, addr, pud))
@@ -201,7 +201,7 @@ void __page_table_check_ptes_set(struct mm_struct *mm, unsigned long addr,
{
unsigned int i;
- if (&init_mm == mm)
+ if (mm_is_kernel(mm))
return;
page_table_check_pte_flags(pte);
@@ -231,7 +231,7 @@ void __page_table_check_pmds_set(struct mm_struct *mm, unsigned long addr,
unsigned long stride = PMD_SIZE >> PAGE_SHIFT;
unsigned int i;
- if (&init_mm == mm)
+ if (mm_is_kernel(mm))
return;
page_table_check_pmd_flags(pmd);
@@ -249,7 +249,7 @@ void __page_table_check_puds_set(struct mm_struct *mm, unsigned long addr,
unsigned long stride = PUD_SIZE >> PAGE_SHIFT;
unsigned int i;
- if (&init_mm == mm)
+ if (mm_is_kernel(mm))
return;
for (i = 0; i < nr; i++)
@@ -263,7 +263,7 @@ void __page_table_check_pte_clear_range(struct mm_struct *mm,
unsigned long addr,
pmd_t pmd)
{
- if (&init_mm == mm)
+ if (mm_is_kernel(mm))
return;
if (!pmd_bad(pmd) && !pmd_leaf(pmd)) {
diff --git a/mm/pagewalk.c b/mm/pagewalk.c
index ed4860c01936..a3f47d1de3c5 100644
--- a/mm/pagewalk.c
+++ b/mm/pagewalk.c
@@ -72,13 +72,13 @@ static int walk_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
* fit its pmd_bad() check (_PAGE_NX set and _PAGE_RW clear),
* and CONFIG_EFI_PGT_DUMP efi_mm goes so far as to walk them.
*/
- if (walk->mm == &init_mm || addr >= TASK_SIZE)
+ if (mm_is_kernel(walk->mm) || addr >= TASK_SIZE)
pte = pte_offset_kernel(pmd, addr);
else
pte = pte_offset_map(pmd, addr);
if (pte) {
err = walk_pte_range_inner(pte, addr, end, walk);
- if (walk->mm != &init_mm && addr < TASK_SIZE)
+ if (!mm_is_kernel(walk->mm) && addr < TASK_SIZE)
pte_unmap(pte);
}
} else {
--
2.51.2
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 05/22] arm64: mm: use mm_is_kernel() for kernel mm checks
2026-07-14 14:03 ` Kevin Brodsky
@ 2026-07-14 14:03 ` Kevin Brodsky
-1 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:03 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
The new MMF_KERNEL flag identifies kernel-owned mm's. Checking the
flag with mm_is_kernel() is preferred over comparing directly
against &init_mm.
In some cases, such as show_pte(), the handling is truly specific to
init_mm and we leave those comparisons with &init_mm unchanged.
No functional change, as only init_mm has MMF_KERNEL set for now.
mm_is_user() will eventually be replaced with !mm_is_kernel(), once
efi_mm is also marked with MMF_KERNEL.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/arm64/include/asm/pgalloc.h | 10 +++++-----
arch/arm64/mm/contpte.c | 2 +-
arch/arm64/mm/hugetlbpage.c | 2 +-
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index 1b4509d3382c..33db4fa3c619 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -30,7 +30,7 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmdp)
{
pudval_t pudval = PUD_TYPE_TABLE | PUD_TABLE_AF;
- pudval |= (mm == &init_mm) ? PUD_TABLE_UXN : PUD_TABLE_PXN;
+ pudval |= mm_is_kernel(mm) ? PUD_TABLE_UXN : PUD_TABLE_PXN;
__pud_populate(pudp, __pa(pmdp), pudval);
}
#else
@@ -52,7 +52,7 @@ static inline void p4d_populate(struct mm_struct *mm, p4d_t *p4dp, pud_t *pudp)
{
p4dval_t p4dval = P4D_TYPE_TABLE | P4D_TABLE_AF;
- p4dval |= (mm == &init_mm) ? P4D_TABLE_UXN : P4D_TABLE_PXN;
+ p4dval |= mm_is_kernel(mm) ? P4D_TABLE_UXN : P4D_TABLE_PXN;
__p4d_populate(p4dp, __pa(pudp), p4dval);
}
@@ -81,7 +81,7 @@ static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgdp, p4d_t *p4dp)
{
pgdval_t pgdval = PGD_TYPE_TABLE | PGD_TABLE_AF;
- pgdval |= (mm == &init_mm) ? PGD_TABLE_UXN : PGD_TABLE_PXN;
+ pgdval |= mm_is_kernel(mm) ? PGD_TABLE_UXN : PGD_TABLE_PXN;
__pgd_populate(pgdp, __pa(p4dp), pgdval);
}
@@ -108,7 +108,7 @@ static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t ptep,
static inline void
pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
{
- VM_BUG_ON(mm && mm != &init_mm);
+ VM_BUG_ON(mm && !mm_is_kernel(mm));
__pmd_populate(pmdp, __pa(ptep),
PMD_TYPE_TABLE | PMD_TABLE_AF | PMD_TABLE_UXN);
}
@@ -116,7 +116,7 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
static inline void
pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep)
{
- VM_BUG_ON(mm == &init_mm);
+ VM_BUG_ON(mm_is_kernel(mm));
__pmd_populate(pmdp, page_to_phys(ptep),
PMD_TYPE_TABLE | PMD_TABLE_AF | PMD_TABLE_PXN);
}
diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
index 2de12656b4d8..ad5c04cf66ff 100644
--- a/arch/arm64/mm/contpte.c
+++ b/arch/arm64/mm/contpte.c
@@ -18,7 +18,7 @@ static inline bool mm_is_user(struct mm_struct *mm)
*/
if (unlikely(mm_is_efi(mm)))
return false;
- return mm != &init_mm;
+ return !mm_is_kernel(mm);
}
static inline pte_t *contpte_align_down(pte_t *ptep)
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 25f04d01aabe..4d054fadf51c 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -212,7 +212,7 @@ static void clear_flush(struct mm_struct *mm,
for (i = 0; i < ncontig; i++, addr += pgsize, ptep++)
__ptep_get_and_clear_anysz(mm, addr, ptep, pgsize);
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
flush_tlb_kernel_range(saddr, addr);
else
__flush_hugetlb_tlb_range(&vma, saddr, addr, pgsize, TLBF_NOWALKCACHE);
--
2.51.2
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 05/22] arm64: mm: use mm_is_kernel() for kernel mm checks
@ 2026-07-14 14:03 ` Kevin Brodsky
0 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:03 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
The new MMF_KERNEL flag identifies kernel-owned mm's. Checking the
flag with mm_is_kernel() is preferred over comparing directly
against &init_mm.
In some cases, such as show_pte(), the handling is truly specific to
init_mm and we leave those comparisons with &init_mm unchanged.
No functional change, as only init_mm has MMF_KERNEL set for now.
mm_is_user() will eventually be replaced with !mm_is_kernel(), once
efi_mm is also marked with MMF_KERNEL.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/arm64/include/asm/pgalloc.h | 10 +++++-----
arch/arm64/mm/contpte.c | 2 +-
arch/arm64/mm/hugetlbpage.c | 2 +-
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index 1b4509d3382c..33db4fa3c619 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -30,7 +30,7 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmdp)
{
pudval_t pudval = PUD_TYPE_TABLE | PUD_TABLE_AF;
- pudval |= (mm == &init_mm) ? PUD_TABLE_UXN : PUD_TABLE_PXN;
+ pudval |= mm_is_kernel(mm) ? PUD_TABLE_UXN : PUD_TABLE_PXN;
__pud_populate(pudp, __pa(pmdp), pudval);
}
#else
@@ -52,7 +52,7 @@ static inline void p4d_populate(struct mm_struct *mm, p4d_t *p4dp, pud_t *pudp)
{
p4dval_t p4dval = P4D_TYPE_TABLE | P4D_TABLE_AF;
- p4dval |= (mm == &init_mm) ? P4D_TABLE_UXN : P4D_TABLE_PXN;
+ p4dval |= mm_is_kernel(mm) ? P4D_TABLE_UXN : P4D_TABLE_PXN;
__p4d_populate(p4dp, __pa(pudp), p4dval);
}
@@ -81,7 +81,7 @@ static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgdp, p4d_t *p4dp)
{
pgdval_t pgdval = PGD_TYPE_TABLE | PGD_TABLE_AF;
- pgdval |= (mm == &init_mm) ? PGD_TABLE_UXN : PGD_TABLE_PXN;
+ pgdval |= mm_is_kernel(mm) ? PGD_TABLE_UXN : PGD_TABLE_PXN;
__pgd_populate(pgdp, __pa(p4dp), pgdval);
}
@@ -108,7 +108,7 @@ static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t ptep,
static inline void
pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
{
- VM_BUG_ON(mm && mm != &init_mm);
+ VM_BUG_ON(mm && !mm_is_kernel(mm));
__pmd_populate(pmdp, __pa(ptep),
PMD_TYPE_TABLE | PMD_TABLE_AF | PMD_TABLE_UXN);
}
@@ -116,7 +116,7 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
static inline void
pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep)
{
- VM_BUG_ON(mm == &init_mm);
+ VM_BUG_ON(mm_is_kernel(mm));
__pmd_populate(pmdp, page_to_phys(ptep),
PMD_TYPE_TABLE | PMD_TABLE_AF | PMD_TABLE_PXN);
}
diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
index 2de12656b4d8..ad5c04cf66ff 100644
--- a/arch/arm64/mm/contpte.c
+++ b/arch/arm64/mm/contpte.c
@@ -18,7 +18,7 @@ static inline bool mm_is_user(struct mm_struct *mm)
*/
if (unlikely(mm_is_efi(mm)))
return false;
- return mm != &init_mm;
+ return !mm_is_kernel(mm);
}
static inline pte_t *contpte_align_down(pte_t *ptep)
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 25f04d01aabe..4d054fadf51c 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -212,7 +212,7 @@ static void clear_flush(struct mm_struct *mm,
for (i = 0; i < ncontig; i++, addr += pgsize, ptep++)
__ptep_get_and_clear_anysz(mm, addr, ptep, pgsize);
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
flush_tlb_kernel_range(saddr, addr);
else
__flush_hugetlb_tlb_range(&vma, saddr, addr, pgsize, TLBF_NOWALKCACHE);
--
2.51.2
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 06/22] loongarch: mm: use mm_is_kernel() in switch_mm_irqs_off()
2026-07-14 14:03 ` Kevin Brodsky
@ 2026-07-14 14:03 ` Kevin Brodsky
-1 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:03 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
The new MMF_KERNEL flag identifies kernel-owned mm's. Checking the
flag with mm_is_kernel() is preferred over comparing directly
against &init_mm.
No functional change, as only init_mm has MMF_KERNEL set for now.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/loongarch/include/asm/mmu_context.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/loongarch/include/asm/mmu_context.h b/arch/loongarch/include/asm/mmu_context.h
index 304363bd3935..6d51f11427b4 100644
--- a/arch/loongarch/include/asm/mmu_context.h
+++ b/arch/loongarch/include/asm/mmu_context.h
@@ -95,7 +95,7 @@ static inline void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *
if (!asid_valid(next, cpu))
get_new_mmu_context(next, cpu, &need_flush);
- if (next != &init_mm)
+ if (!mm_is_kernel(next))
atomic_update_pgd_asid(cpu_asid(cpu, next), (unsigned long)next->pgd);
else
atomic_update_pgd_asid(cpu_asid(cpu, next), (unsigned long)invalid_pg_dir);
--
2.51.2
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 06/22] loongarch: mm: use mm_is_kernel() in switch_mm_irqs_off()
@ 2026-07-14 14:03 ` Kevin Brodsky
0 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:03 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
The new MMF_KERNEL flag identifies kernel-owned mm's. Checking the
flag with mm_is_kernel() is preferred over comparing directly
against &init_mm.
No functional change, as only init_mm has MMF_KERNEL set for now.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/loongarch/include/asm/mmu_context.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/loongarch/include/asm/mmu_context.h b/arch/loongarch/include/asm/mmu_context.h
index 304363bd3935..6d51f11427b4 100644
--- a/arch/loongarch/include/asm/mmu_context.h
+++ b/arch/loongarch/include/asm/mmu_context.h
@@ -95,7 +95,7 @@ static inline void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *
if (!asid_valid(next, cpu))
get_new_mmu_context(next, cpu, &need_flush);
- if (next != &init_mm)
+ if (!mm_is_kernel(next))
atomic_update_pgd_asid(cpu_asid(cpu, next), (unsigned long)next->pgd);
else
atomic_update_pgd_asid(cpu_asid(cpu, next), (unsigned long)invalid_pg_dir);
--
2.51.2
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 07/22] parisc: mm: use mm_is_kernel() for kernel mm checks
2026-07-14 14:03 ` Kevin Brodsky
@ 2026-07-14 14:03 ` Kevin Brodsky
-1 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:03 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
The new MMF_KERNEL flag identifies kernel-owned mm's. Checking the
flag with mm_is_kernel() is preferred over comparing directly
against &init_mm.
No functional change, as only init_mm has MMF_KERNEL set for now.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/parisc/include/asm/mmu_context.h | 2 +-
arch/parisc/include/asm/pgalloc.h | 2 +-
arch/parisc/include/asm/tlbflush.h | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/parisc/include/asm/mmu_context.h b/arch/parisc/include/asm/mmu_context.h
index c9187fe836a3..e265da67559e 100644
--- a/arch/parisc/include/asm/mmu_context.h
+++ b/arch/parisc/include/asm/mmu_context.h
@@ -87,7 +87,7 @@ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next)
* already, so we should be OK.
*/
- BUG_ON(next == &init_mm); /* Should never happen */
+ BUG_ON(mm_is_kernel(next)); /* Should never happen */
if (next->context.space_id == 0)
next->context.space_id = alloc_sid();
diff --git a/arch/parisc/include/asm/pgalloc.h b/arch/parisc/include/asm/pgalloc.h
index 3b84ee93edaa..9f09cc4fa5dd 100644
--- a/arch/parisc/include/asm/pgalloc.h
+++ b/arch/parisc/include/asm/pgalloc.h
@@ -34,7 +34,7 @@ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
struct ptdesc *ptdesc;
gfp_t gfp = GFP_PGTABLE_USER;
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
gfp = GFP_PGTABLE_KERNEL;
ptdesc = pagetable_alloc(gfp, PMD_TABLE_ORDER);
if (!ptdesc)
diff --git a/arch/parisc/include/asm/tlbflush.h b/arch/parisc/include/asm/tlbflush.h
index 5ffd7c17f593..a5a6cfff295c 100644
--- a/arch/parisc/include/asm/tlbflush.h
+++ b/arch/parisc/include/asm/tlbflush.h
@@ -35,7 +35,7 @@ int __flush_tlb_range(unsigned long sid,
static inline void flush_tlb_mm(struct mm_struct *mm)
{
- BUG_ON(mm == &init_mm); /* Should never happen */
+ BUG_ON(mm_is_kernel(mm)); /* Should never happen */
#if 1 || defined(CONFIG_SMP)
/* Except for very small threads, flushing the whole TLB is
--
2.51.2
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 07/22] parisc: mm: use mm_is_kernel() for kernel mm checks
@ 2026-07-14 14:03 ` Kevin Brodsky
0 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:03 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
The new MMF_KERNEL flag identifies kernel-owned mm's. Checking the
flag with mm_is_kernel() is preferred over comparing directly
against &init_mm.
No functional change, as only init_mm has MMF_KERNEL set for now.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/parisc/include/asm/mmu_context.h | 2 +-
arch/parisc/include/asm/pgalloc.h | 2 +-
arch/parisc/include/asm/tlbflush.h | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/parisc/include/asm/mmu_context.h b/arch/parisc/include/asm/mmu_context.h
index c9187fe836a3..e265da67559e 100644
--- a/arch/parisc/include/asm/mmu_context.h
+++ b/arch/parisc/include/asm/mmu_context.h
@@ -87,7 +87,7 @@ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next)
* already, so we should be OK.
*/
- BUG_ON(next == &init_mm); /* Should never happen */
+ BUG_ON(mm_is_kernel(next)); /* Should never happen */
if (next->context.space_id == 0)
next->context.space_id = alloc_sid();
diff --git a/arch/parisc/include/asm/pgalloc.h b/arch/parisc/include/asm/pgalloc.h
index 3b84ee93edaa..9f09cc4fa5dd 100644
--- a/arch/parisc/include/asm/pgalloc.h
+++ b/arch/parisc/include/asm/pgalloc.h
@@ -34,7 +34,7 @@ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
struct ptdesc *ptdesc;
gfp_t gfp = GFP_PGTABLE_USER;
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
gfp = GFP_PGTABLE_KERNEL;
ptdesc = pagetable_alloc(gfp, PMD_TABLE_ORDER);
if (!ptdesc)
diff --git a/arch/parisc/include/asm/tlbflush.h b/arch/parisc/include/asm/tlbflush.h
index 5ffd7c17f593..a5a6cfff295c 100644
--- a/arch/parisc/include/asm/tlbflush.h
+++ b/arch/parisc/include/asm/tlbflush.h
@@ -35,7 +35,7 @@ int __flush_tlb_range(unsigned long sid,
static inline void flush_tlb_mm(struct mm_struct *mm)
{
- BUG_ON(mm == &init_mm); /* Should never happen */
+ BUG_ON(mm_is_kernel(mm)); /* Should never happen */
#if 1 || defined(CONFIG_SMP)
/* Except for very small threads, flushing the whole TLB is
--
2.51.2
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 08/22] powerpc: mm: use mm_is_kernel() for kernel mm checks
2026-07-14 14:03 ` Kevin Brodsky
@ 2026-07-14 14:03 ` Kevin Brodsky
-1 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:03 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
The new MMF_KERNEL flag identifies kernel-owned mm's. Checking the
flag with mm_is_kernel() is preferred over comparing directly
against &init_mm.
No functional change, as only init_mm has MMF_KERNEL set for now.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/powerpc/include/asm/pgalloc.h | 2 +-
arch/powerpc/mm/book3s64/pgtable.c | 2 +-
arch/powerpc/mm/mmu_context.c | 2 +-
arch/powerpc/mm/pgtable.c | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/include/asm/pgalloc.h b/arch/powerpc/include/asm/pgalloc.h
index 3a971e2a8c73..88acccc5b06e 100644
--- a/arch/powerpc/include/asm/pgalloc.h
+++ b/arch/powerpc/include/asm/pgalloc.h
@@ -7,7 +7,7 @@
#ifndef MODULE
static inline gfp_t pgtable_gfp_flags(struct mm_struct *mm, gfp_t gfp)
{
- if (unlikely(mm == &init_mm))
+ if (unlikely(mm_is_kernel(mm)))
return gfp;
return gfp | __GFP_ACCOUNT;
}
diff --git a/arch/powerpc/mm/book3s64/pgtable.c b/arch/powerpc/mm/book3s64/pgtable.c
index 85ab6723c8f2..eb365f7c8907 100644
--- a/arch/powerpc/mm/book3s64/pgtable.c
+++ b/arch/powerpc/mm/book3s64/pgtable.c
@@ -395,7 +395,7 @@ static pmd_t *__alloc_for_pmdcache(struct mm_struct *mm)
struct ptdesc *ptdesc;
gfp_t gfp = GFP_KERNEL_ACCOUNT | __GFP_ZERO;
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
gfp &= ~__GFP_ACCOUNT;
ptdesc = pagetable_alloc(gfp, 0);
if (!ptdesc)
diff --git a/arch/powerpc/mm/mmu_context.c b/arch/powerpc/mm/mmu_context.c
index 3e3af29b4523..b51934c511f3 100644
--- a/arch/powerpc/mm/mmu_context.c
+++ b/arch/powerpc/mm/mmu_context.c
@@ -48,7 +48,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
/* Mark this context has been used on the new CPU */
if (!cpumask_test_cpu(cpu, mm_cpumask(next))) {
- VM_WARN_ON_ONCE(next == &init_mm);
+ VM_WARN_ON_ONCE(mm_is_kernel(next));
cpumask_set_cpu(cpu, mm_cpumask(next));
inc_mm_active_cpus(next);
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index a9be337be3e4..d04f4fecfc7c 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -393,7 +393,7 @@ void assert_pte_locked(struct mm_struct *mm, unsigned long addr)
pte_t *pte;
spinlock_t *ptl;
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
return;
pgd = mm->pgd + pgd_index(addr);
BUG_ON(pgd_none(*pgd));
--
2.51.2
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 08/22] powerpc: mm: use mm_is_kernel() for kernel mm checks
@ 2026-07-14 14:03 ` Kevin Brodsky
0 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:03 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
The new MMF_KERNEL flag identifies kernel-owned mm's. Checking the
flag with mm_is_kernel() is preferred over comparing directly
against &init_mm.
No functional change, as only init_mm has MMF_KERNEL set for now.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/powerpc/include/asm/pgalloc.h | 2 +-
arch/powerpc/mm/book3s64/pgtable.c | 2 +-
arch/powerpc/mm/mmu_context.c | 2 +-
arch/powerpc/mm/pgtable.c | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/include/asm/pgalloc.h b/arch/powerpc/include/asm/pgalloc.h
index 3a971e2a8c73..88acccc5b06e 100644
--- a/arch/powerpc/include/asm/pgalloc.h
+++ b/arch/powerpc/include/asm/pgalloc.h
@@ -7,7 +7,7 @@
#ifndef MODULE
static inline gfp_t pgtable_gfp_flags(struct mm_struct *mm, gfp_t gfp)
{
- if (unlikely(mm == &init_mm))
+ if (unlikely(mm_is_kernel(mm)))
return gfp;
return gfp | __GFP_ACCOUNT;
}
diff --git a/arch/powerpc/mm/book3s64/pgtable.c b/arch/powerpc/mm/book3s64/pgtable.c
index 85ab6723c8f2..eb365f7c8907 100644
--- a/arch/powerpc/mm/book3s64/pgtable.c
+++ b/arch/powerpc/mm/book3s64/pgtable.c
@@ -395,7 +395,7 @@ static pmd_t *__alloc_for_pmdcache(struct mm_struct *mm)
struct ptdesc *ptdesc;
gfp_t gfp = GFP_KERNEL_ACCOUNT | __GFP_ZERO;
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
gfp &= ~__GFP_ACCOUNT;
ptdesc = pagetable_alloc(gfp, 0);
if (!ptdesc)
diff --git a/arch/powerpc/mm/mmu_context.c b/arch/powerpc/mm/mmu_context.c
index 3e3af29b4523..b51934c511f3 100644
--- a/arch/powerpc/mm/mmu_context.c
+++ b/arch/powerpc/mm/mmu_context.c
@@ -48,7 +48,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
/* Mark this context has been used on the new CPU */
if (!cpumask_test_cpu(cpu, mm_cpumask(next))) {
- VM_WARN_ON_ONCE(next == &init_mm);
+ VM_WARN_ON_ONCE(mm_is_kernel(next));
cpumask_set_cpu(cpu, mm_cpumask(next));
inc_mm_active_cpus(next);
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index a9be337be3e4..d04f4fecfc7c 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -393,7 +393,7 @@ void assert_pte_locked(struct mm_struct *mm, unsigned long addr)
pte_t *pte;
spinlock_t *ptl;
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
return;
pgd = mm->pgd + pgd_index(addr);
BUG_ON(pgd_none(*pgd));
--
2.51.2
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 09/22] s390: mm: use mm_is_kernel() for kernel mm checks
2026-07-14 14:03 ` Kevin Brodsky
@ 2026-07-14 14:03 ` Kevin Brodsky
-1 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:03 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
The new MMF_KERNEL flag identifies kernel-owned mm's. Checking the
flag with mm_is_kernel() is preferred over comparing directly
against &init_mm.
No functional change, as only init_mm has MMF_KERNEL set for now.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/s390/include/asm/mmu_context.h | 2 +-
arch/s390/include/asm/pgtable.h | 6 +++---
arch/s390/mm/pgalloc.c | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h
index bd1ef5e2d2eb..675f270d0b70 100644
--- a/arch/s390/include/asm/mmu_context.h
+++ b/arch/s390/include/asm/mmu_context.h
@@ -69,7 +69,7 @@ static inline void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *
{
int cpu = smp_processor_id();
- if (next == &init_mm)
+ if (mm_is_kernel(next))
get_lowcore()->user_asce = s390_invalid_asce;
else
get_lowcore()->user_asce.val = next->context.asce;
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index e882663a58e7..f7741e6b417e 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -1836,21 +1836,21 @@ static inline int has_transparent_hugepage(void)
#ifdef CONFIG_PAGE_TABLE_CHECK
static inline bool pte_user_accessible_page(struct mm_struct *mm, unsigned long addr, pte_t pte)
{
- VM_BUG_ON(mm == &init_mm);
+ VM_BUG_ON(mm_is_kernel(mm));
return pte_present(pte);
}
static inline bool pmd_user_accessible_page(struct mm_struct *mm, unsigned long addr, pmd_t pmd)
{
- VM_BUG_ON(mm == &init_mm);
+ VM_BUG_ON(mm_is_kernel(mm));
return pmd_leaf(pmd) && (pmd_val(pmd) & _SEGMENT_ENTRY_READ);
}
static inline bool pud_user_accessible_page(struct mm_struct *mm, unsigned long addr, pud_t pud)
{
- VM_BUG_ON(mm == &init_mm);
+ VM_BUG_ON(mm_is_kernel(mm));
return pud_leaf(pud);
}
diff --git a/arch/s390/mm/pgalloc.c b/arch/s390/mm/pgalloc.c
index 7ac44543e051..d0456b7e73d4 100644
--- a/arch/s390/mm/pgalloc.c
+++ b/arch/s390/mm/pgalloc.c
@@ -20,7 +20,7 @@ unsigned long *crst_table_alloc_noprof(struct mm_struct *mm)
struct ptdesc *ptdesc;
unsigned long *table;
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
gfp &= ~__GFP_ACCOUNT;
ptdesc = pagetable_alloc_noprof(gfp, CRST_ALLOC_ORDER);
if (!ptdesc)
@@ -120,7 +120,7 @@ unsigned long *page_table_alloc_noprof(struct mm_struct *mm)
struct ptdesc *ptdesc;
unsigned long *table;
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
gfp &= ~__GFP_ACCOUNT;
ptdesc = pagetable_alloc_noprof(gfp, 0);
if (!ptdesc)
--
2.51.2
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 09/22] s390: mm: use mm_is_kernel() for kernel mm checks
@ 2026-07-14 14:03 ` Kevin Brodsky
0 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:03 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
The new MMF_KERNEL flag identifies kernel-owned mm's. Checking the
flag with mm_is_kernel() is preferred over comparing directly
against &init_mm.
No functional change, as only init_mm has MMF_KERNEL set for now.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/s390/include/asm/mmu_context.h | 2 +-
arch/s390/include/asm/pgtable.h | 6 +++---
arch/s390/mm/pgalloc.c | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h
index bd1ef5e2d2eb..675f270d0b70 100644
--- a/arch/s390/include/asm/mmu_context.h
+++ b/arch/s390/include/asm/mmu_context.h
@@ -69,7 +69,7 @@ static inline void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *
{
int cpu = smp_processor_id();
- if (next == &init_mm)
+ if (mm_is_kernel(next))
get_lowcore()->user_asce = s390_invalid_asce;
else
get_lowcore()->user_asce.val = next->context.asce;
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index e882663a58e7..f7741e6b417e 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -1836,21 +1836,21 @@ static inline int has_transparent_hugepage(void)
#ifdef CONFIG_PAGE_TABLE_CHECK
static inline bool pte_user_accessible_page(struct mm_struct *mm, unsigned long addr, pte_t pte)
{
- VM_BUG_ON(mm == &init_mm);
+ VM_BUG_ON(mm_is_kernel(mm));
return pte_present(pte);
}
static inline bool pmd_user_accessible_page(struct mm_struct *mm, unsigned long addr, pmd_t pmd)
{
- VM_BUG_ON(mm == &init_mm);
+ VM_BUG_ON(mm_is_kernel(mm));
return pmd_leaf(pmd) && (pmd_val(pmd) & _SEGMENT_ENTRY_READ);
}
static inline bool pud_user_accessible_page(struct mm_struct *mm, unsigned long addr, pud_t pud)
{
- VM_BUG_ON(mm == &init_mm);
+ VM_BUG_ON(mm_is_kernel(mm));
return pud_leaf(pud);
}
diff --git a/arch/s390/mm/pgalloc.c b/arch/s390/mm/pgalloc.c
index 7ac44543e051..d0456b7e73d4 100644
--- a/arch/s390/mm/pgalloc.c
+++ b/arch/s390/mm/pgalloc.c
@@ -20,7 +20,7 @@ unsigned long *crst_table_alloc_noprof(struct mm_struct *mm)
struct ptdesc *ptdesc;
unsigned long *table;
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
gfp &= ~__GFP_ACCOUNT;
ptdesc = pagetable_alloc_noprof(gfp, CRST_ALLOC_ORDER);
if (!ptdesc)
@@ -120,7 +120,7 @@ unsigned long *page_table_alloc_noprof(struct mm_struct *mm)
struct ptdesc *ptdesc;
unsigned long *table;
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
gfp &= ~__GFP_ACCOUNT;
ptdesc = pagetable_alloc_noprof(gfp, 0);
if (!ptdesc)
--
2.51.2
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 10/22] sparc: mm: use mm_is_kernel() for kernel mm checks
2026-07-14 14:03 ` Kevin Brodsky
@ 2026-07-14 14:03 ` Kevin Brodsky
-1 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:03 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
The new MMF_KERNEL flag identifies kernel-owned mm's. Checking the
flag with mm_is_kernel() is preferred over comparing directly
against &init_mm.
No functional change, as only init_mm has MMF_KERNEL set for now.
pgtable_64.h previously forward-declared init_mm to avoid pulling
in mm_types.h. It seems that including mm_types.h is not causing
troubles any more, so we can also use mm_is_kernel() there and drop
the forward declaration.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/sparc/include/asm/mmu_context_64.h | 2 +-
arch/sparc/include/asm/pgtable_64.h | 6 ++----
arch/sparc/mm/init_64.c | 2 +-
arch/sparc/mm/tlb.c | 2 +-
4 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/arch/sparc/include/asm/mmu_context_64.h b/arch/sparc/include/asm/mmu_context_64.h
index 78bbacc14d2d..e88bc61aeb04 100644
--- a/arch/sparc/include/asm/mmu_context_64.h
+++ b/arch/sparc/include/asm/mmu_context_64.h
@@ -83,7 +83,7 @@ static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, str
int cpu = smp_processor_id();
per_cpu(per_cpu_secondary_mm, cpu) = mm;
- if (unlikely(mm == &init_mm))
+ if (unlikely(mm_is_kernel(mm)))
return;
spin_lock_irqsave(&mm->context.lock, flags);
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h
index 0837ebbc5dce..960f8bf1ec5a 100644
--- a/arch/sparc/include/asm/pgtable_64.h
+++ b/arch/sparc/include/asm/pgtable_64.h
@@ -86,6 +86,7 @@ extern unsigned long VMALLOC_END;
#define vmemmap ((struct page *)VMEMMAP_BASE)
#include <linux/sched.h>
+#include <linux/mm_types.h>
#include <asm/tlbflush.h>
bool kern_addr_valid(unsigned long addr);
@@ -885,9 +886,6 @@ static inline unsigned long pud_pfn(pud_t pud)
#define p4d_set(p4dp, pudp) \
(p4d_val(*(p4dp)) = (__pa((unsigned long) (pudp))))
-/* We cannot include <linux/mm_types.h> at this point yet: */
-extern struct mm_struct init_mm;
-
/* Actual page table PTE updates. */
void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
pte_t *ptep, pte_t orig, int fullmm,
@@ -903,7 +901,7 @@ static void maybe_tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
* SUN4V NOTE: _PAGE_VALID is the same value in both the SUN4U
* and SUN4V pte layout, so this inline test is fine.
*/
- if (likely(mm != &init_mm) && pte_accessible(mm, orig))
+ if (likely(!mm_is_kernel(mm)) && pte_accessible(mm, orig))
tlb_batch_add(mm, vaddr, ptep, orig, fullmm, hugepage_shift);
}
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 103db4683b16..e0b678349e3a 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -788,7 +788,7 @@ static void mmu_context_wrap(void)
*/
mm = per_cpu(per_cpu_secondary_mm, cpu);
- if (unlikely(!mm || mm == &init_mm))
+ if (unlikely(!mm || mm_is_kernel(mm)))
continue;
old_ctx = mm->context.sparc64_ctx_val;
diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c
index 6d9dd5eb1328..47083c287a94 100644
--- a/arch/sparc/mm/tlb.c
+++ b/arch/sparc/mm/tlb.c
@@ -179,7 +179,7 @@ static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr,
static void __set_pmd_acct(struct mm_struct *mm, unsigned long addr,
pmd_t orig, pmd_t pmd)
{
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
return;
if ((pmd_val(pmd) ^ pmd_val(orig)) & _PAGE_PMD_HUGE) {
--
2.51.2
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 10/22] sparc: mm: use mm_is_kernel() for kernel mm checks
@ 2026-07-14 14:03 ` Kevin Brodsky
0 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:03 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
The new MMF_KERNEL flag identifies kernel-owned mm's. Checking the
flag with mm_is_kernel() is preferred over comparing directly
against &init_mm.
No functional change, as only init_mm has MMF_KERNEL set for now.
pgtable_64.h previously forward-declared init_mm to avoid pulling
in mm_types.h. It seems that including mm_types.h is not causing
troubles any more, so we can also use mm_is_kernel() there and drop
the forward declaration.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/sparc/include/asm/mmu_context_64.h | 2 +-
arch/sparc/include/asm/pgtable_64.h | 6 ++----
arch/sparc/mm/init_64.c | 2 +-
arch/sparc/mm/tlb.c | 2 +-
4 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/arch/sparc/include/asm/mmu_context_64.h b/arch/sparc/include/asm/mmu_context_64.h
index 78bbacc14d2d..e88bc61aeb04 100644
--- a/arch/sparc/include/asm/mmu_context_64.h
+++ b/arch/sparc/include/asm/mmu_context_64.h
@@ -83,7 +83,7 @@ static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, str
int cpu = smp_processor_id();
per_cpu(per_cpu_secondary_mm, cpu) = mm;
- if (unlikely(mm == &init_mm))
+ if (unlikely(mm_is_kernel(mm)))
return;
spin_lock_irqsave(&mm->context.lock, flags);
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h
index 0837ebbc5dce..960f8bf1ec5a 100644
--- a/arch/sparc/include/asm/pgtable_64.h
+++ b/arch/sparc/include/asm/pgtable_64.h
@@ -86,6 +86,7 @@ extern unsigned long VMALLOC_END;
#define vmemmap ((struct page *)VMEMMAP_BASE)
#include <linux/sched.h>
+#include <linux/mm_types.h>
#include <asm/tlbflush.h>
bool kern_addr_valid(unsigned long addr);
@@ -885,9 +886,6 @@ static inline unsigned long pud_pfn(pud_t pud)
#define p4d_set(p4dp, pudp) \
(p4d_val(*(p4dp)) = (__pa((unsigned long) (pudp))))
-/* We cannot include <linux/mm_types.h> at this point yet: */
-extern struct mm_struct init_mm;
-
/* Actual page table PTE updates. */
void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
pte_t *ptep, pte_t orig, int fullmm,
@@ -903,7 +901,7 @@ static void maybe_tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
* SUN4V NOTE: _PAGE_VALID is the same value in both the SUN4U
* and SUN4V pte layout, so this inline test is fine.
*/
- if (likely(mm != &init_mm) && pte_accessible(mm, orig))
+ if (likely(!mm_is_kernel(mm)) && pte_accessible(mm, orig))
tlb_batch_add(mm, vaddr, ptep, orig, fullmm, hugepage_shift);
}
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 103db4683b16..e0b678349e3a 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -788,7 +788,7 @@ static void mmu_context_wrap(void)
*/
mm = per_cpu(per_cpu_secondary_mm, cpu);
- if (unlikely(!mm || mm == &init_mm))
+ if (unlikely(!mm || mm_is_kernel(mm)))
continue;
old_ctx = mm->context.sparc64_ctx_val;
diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c
index 6d9dd5eb1328..47083c287a94 100644
--- a/arch/sparc/mm/tlb.c
+++ b/arch/sparc/mm/tlb.c
@@ -179,7 +179,7 @@ static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr,
static void __set_pmd_acct(struct mm_struct *mm, unsigned long addr,
pmd_t orig, pmd_t pmd)
{
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
return;
if ((pmd_val(pmd) ^ pmd_val(orig)) & _PAGE_PMD_HUGE) {
--
2.51.2
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 11/22] um: mm: use mm_is_kernel() in TLB sync
2026-07-14 14:03 ` Kevin Brodsky
@ 2026-07-14 14:04 ` Kevin Brodsky
-1 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:04 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
The new MMF_KERNEL flag identifies kernel-owned mm's. Checking the
flag with mm_is_kernel() is preferred over comparing directly
against &init_mm.
No functional change, as only init_mm has MMF_KERNEL set for now.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/um/kernel/tlb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
index 1f175716b474..fa34a710203e 100644
--- a/arch/um/kernel/tlb.c
+++ b/arch/um/kernel/tlb.c
@@ -171,7 +171,7 @@ int um_tlb_sync(struct mm_struct *mm)
return 0;
ops.mm_idp = &mm->context.id;
- if (mm == &init_mm) {
+ if (mm_is_kernel(mm)) {
ops.mmap = kern_map;
ops.unmap = kern_unmap;
} else {
--
2.51.2
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 11/22] um: mm: use mm_is_kernel() in TLB sync
@ 2026-07-14 14:04 ` Kevin Brodsky
0 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:04 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
The new MMF_KERNEL flag identifies kernel-owned mm's. Checking the
flag with mm_is_kernel() is preferred over comparing directly
against &init_mm.
No functional change, as only init_mm has MMF_KERNEL set for now.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/um/kernel/tlb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
index 1f175716b474..fa34a710203e 100644
--- a/arch/um/kernel/tlb.c
+++ b/arch/um/kernel/tlb.c
@@ -171,7 +171,7 @@ int um_tlb_sync(struct mm_struct *mm)
return 0;
ops.mm_idp = &mm->context.id;
- if (mm == &init_mm) {
+ if (mm_is_kernel(mm)) {
ops.mmap = kern_map;
ops.unmap = kern_unmap;
} else {
--
2.51.2
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 12/22] x86/mm: use mm_is_kernel() for kernel mm checks
2026-07-14 14:03 ` Kevin Brodsky
@ 2026-07-14 14:04 ` Kevin Brodsky
-1 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:04 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
The new MMF_KERNEL flag identifies kernel-owned mm's. Checking the
flag with mm_is_kernel() is preferred over comparing directly
against &init_mm.
No functional change, as only init_mm has MMF_KERNEL set for now.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/x86/include/asm/tlbflush.h | 8 ++++----
arch/x86/mm/pgtable.c | 2 +-
arch/x86/mm/tlb.c | 9 +++++----
3 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index 0545fe75c3fa..4af1cf711a60 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -159,10 +159,10 @@ struct tlb_state_shared {
* - Actively using an mm. Our CPU's bit will be set in
* mm_cpumask(loaded_mm) and is_lazy == false;
*
- * - Not using a real mm. loaded_mm == &init_mm. Our CPU's bit
- * will not be set in mm_cpumask(&init_mm) and is_lazy == false.
+ * - Not using a real mm. loaded_mm is a kernel mm. Our CPU's bit
+ * will not be set in mm_cpumask(loaded_mm) and is_lazy == false.
*
- * - Lazily using a real mm. loaded_mm != &init_mm, our bit
+ * - Lazily using a real mm. loaded_mm is not a kernel mm, our bit
* is set in mm_cpumask(loaded_mm), but is_lazy == true.
* We're heuristically guessing that the CR3 load we
* skipped more than makes up for the overhead added by
@@ -188,7 +188,7 @@ DECLARE_PER_CPU_SHARED_ALIGNED(struct tlb_state_shared, cpu_tlbstate_shared);
#define enter_lazy_tlb enter_lazy_tlb
static __always_inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
{
- if (this_cpu_read(cpu_tlbstate.loaded_mm) == &init_mm)
+ if (mm_is_kernel(this_cpu_read(cpu_tlbstate.loaded_mm)))
return;
this_cpu_write(cpu_tlbstate_shared.is_lazy, true);
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index f32facdb3035..91d2a6f2ac5a 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -168,7 +168,7 @@ static int preallocate_pmds(struct mm_struct *mm, pmd_t *pmds[], int count)
bool failed = false;
gfp_t gfp = GFP_PGTABLE_USER;
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
gfp &= ~__GFP_ACCOUNT;
gfp &= ~__GFP_HIGHMEM;
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 1023acadd8f8..5517cab8ad00 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -594,7 +594,7 @@ void leave_mm(void)
* This needs to happen before any other sanity checks due to
* intel_idle's shenanigans.
*/
- if (loaded_mm == &init_mm)
+ if (mm_is_kernel(loaded_mm))
return;
/* Warn if we're not lazy. */
@@ -855,7 +855,7 @@ void switch_mm_irqs_off(struct mm_struct *unused, struct mm_struct *next,
* cpu_tlbstate_shared.is_lazy whether or not to send an IPI.
*/
if (IS_ENABLED(CONFIG_DEBUG_VM) &&
- WARN_ON_ONCE(prev != &init_mm && !is_notrack_mm(prev) &&
+ WARN_ON_ONCE(!mm_is_kernel(prev) && !is_notrack_mm(prev) &&
!cpumask_test_cpu(cpu, mm_cpumask(next))))
cpumask_set_cpu(cpu, mm_cpumask(next));
@@ -932,7 +932,8 @@ void switch_mm_irqs_off(struct mm_struct *unused, struct mm_struct *next,
* This way switch_mm() must see the new tlb_gen or
* flush_tlb_mm_range() must see the new loaded_mm, or both.
*/
- if (next != &init_mm && !cpumask_test_cpu(cpu, mm_cpumask(next)))
+ if (!mm_is_kernel(next) &&
+ !cpumask_test_cpu(cpu, mm_cpumask(next)))
cpumask_set_cpu(cpu, mm_cpumask(next));
else
smp_mb();
@@ -1134,7 +1135,7 @@ static void flush_tlb_func(void *info)
return;
}
- if (unlikely(loaded_mm == &init_mm))
+ if (unlikely(mm_is_kernel(loaded_mm)))
return;
/* Reload the ASID if transitioning into or out of a global ASID */
--
2.51.2
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 12/22] x86/mm: use mm_is_kernel() for kernel mm checks
@ 2026-07-14 14:04 ` Kevin Brodsky
0 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:04 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
The new MMF_KERNEL flag identifies kernel-owned mm's. Checking the
flag with mm_is_kernel() is preferred over comparing directly
against &init_mm.
No functional change, as only init_mm has MMF_KERNEL set for now.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/x86/include/asm/tlbflush.h | 8 ++++----
arch/x86/mm/pgtable.c | 2 +-
arch/x86/mm/tlb.c | 9 +++++----
3 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index 0545fe75c3fa..4af1cf711a60 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -159,10 +159,10 @@ struct tlb_state_shared {
* - Actively using an mm. Our CPU's bit will be set in
* mm_cpumask(loaded_mm) and is_lazy == false;
*
- * - Not using a real mm. loaded_mm == &init_mm. Our CPU's bit
- * will not be set in mm_cpumask(&init_mm) and is_lazy == false.
+ * - Not using a real mm. loaded_mm is a kernel mm. Our CPU's bit
+ * will not be set in mm_cpumask(loaded_mm) and is_lazy == false.
*
- * - Lazily using a real mm. loaded_mm != &init_mm, our bit
+ * - Lazily using a real mm. loaded_mm is not a kernel mm, our bit
* is set in mm_cpumask(loaded_mm), but is_lazy == true.
* We're heuristically guessing that the CR3 load we
* skipped more than makes up for the overhead added by
@@ -188,7 +188,7 @@ DECLARE_PER_CPU_SHARED_ALIGNED(struct tlb_state_shared, cpu_tlbstate_shared);
#define enter_lazy_tlb enter_lazy_tlb
static __always_inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
{
- if (this_cpu_read(cpu_tlbstate.loaded_mm) == &init_mm)
+ if (mm_is_kernel(this_cpu_read(cpu_tlbstate.loaded_mm)))
return;
this_cpu_write(cpu_tlbstate_shared.is_lazy, true);
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index f32facdb3035..91d2a6f2ac5a 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -168,7 +168,7 @@ static int preallocate_pmds(struct mm_struct *mm, pmd_t *pmds[], int count)
bool failed = false;
gfp_t gfp = GFP_PGTABLE_USER;
- if (mm == &init_mm)
+ if (mm_is_kernel(mm))
gfp &= ~__GFP_ACCOUNT;
gfp &= ~__GFP_HIGHMEM;
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 1023acadd8f8..5517cab8ad00 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -594,7 +594,7 @@ void leave_mm(void)
* This needs to happen before any other sanity checks due to
* intel_idle's shenanigans.
*/
- if (loaded_mm == &init_mm)
+ if (mm_is_kernel(loaded_mm))
return;
/* Warn if we're not lazy. */
@@ -855,7 +855,7 @@ void switch_mm_irqs_off(struct mm_struct *unused, struct mm_struct *next,
* cpu_tlbstate_shared.is_lazy whether or not to send an IPI.
*/
if (IS_ENABLED(CONFIG_DEBUG_VM) &&
- WARN_ON_ONCE(prev != &init_mm && !is_notrack_mm(prev) &&
+ WARN_ON_ONCE(!mm_is_kernel(prev) && !is_notrack_mm(prev) &&
!cpumask_test_cpu(cpu, mm_cpumask(next))))
cpumask_set_cpu(cpu, mm_cpumask(next));
@@ -932,7 +932,8 @@ void switch_mm_irqs_off(struct mm_struct *unused, struct mm_struct *next,
* This way switch_mm() must see the new tlb_gen or
* flush_tlb_mm_range() must see the new loaded_mm, or both.
*/
- if (next != &init_mm && !cpumask_test_cpu(cpu, mm_cpumask(next)))
+ if (!mm_is_kernel(next) &&
+ !cpumask_test_cpu(cpu, mm_cpumask(next)))
cpumask_set_cpu(cpu, mm_cpumask(next));
else
smp_mb();
@@ -1134,7 +1135,7 @@ static void flush_tlb_func(void *info)
return;
}
- if (unlikely(loaded_mm == &init_mm))
+ if (unlikely(mm_is_kernel(loaded_mm)))
return;
/* Reload the ASID if transitioning into or out of a global ASID */
--
2.51.2
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 13/22] mm: account page table pages when allocated
2026-07-14 14:03 ` Kevin Brodsky
@ 2026-07-14 14:04 ` Kevin Brodsky
-1 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:04 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
As a step towards removing pagetable ctor/dtor calls for kernel
mm's, move the memory accounting from the ctor/dtor to
pagetable_{alloc,free}.
The ctor is normally called after pagetable_alloc() (and dtor before
pagetable_free()) so this patch should have no functional effect in
most cases. Where calls to ctor/dtor are currently missing (e.g.
x86's split_large_page()), this patch should improve the accounting.
This patch is based on Matthew's earlier implementation linked
below, with the difference that when freeing the accounting is
updated in __pagetable_free(), meaning that the update is delayed
until the pages are actually freed in the
CONFIG_ASYNC_KERNEL_PGTABLE_FREE case. This shouldn't matter in
practice.
Suggested-by: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Link: https://lore.kernel.org/r/20251113140448.1814860-3-willy@infradead.org
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
include/linux/mm.h | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index b336eb32faa0..361a0d7b74c5 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -3681,6 +3681,11 @@ static inline struct ptdesc *pagetable_alloc_noprof(gfp_t gfp, unsigned int orde
{
struct page *page = alloc_pages_noprof(gfp | __GFP_COMP, order);
+ if (!page)
+ return NULL;
+
+ lruvec_stat_add_folio(page_folio(page), NR_PAGETABLE);
+
return page_ptdesc(page);
}
#define pagetable_alloc(...) alloc_hooks(pagetable_alloc_noprof(__VA_ARGS__))
@@ -3689,6 +3694,8 @@ static inline void __pagetable_free(struct ptdesc *pt)
{
struct page *page = ptdesc_page(pt);
+ lruvec_stat_sub_folio(page_folio(page), NR_PAGETABLE);
+
__free_pages(page, compound_order(page));
}
@@ -3797,7 +3804,6 @@ static inline void __pagetable_ctor(struct ptdesc *ptdesc)
struct folio *folio = ptdesc_folio(ptdesc);
__folio_set_pgtable(folio);
- lruvec_stat_add_folio(folio, NR_PAGETABLE);
}
static inline void pagetable_dtor(struct ptdesc *ptdesc)
@@ -3806,7 +3812,6 @@ static inline void pagetable_dtor(struct ptdesc *ptdesc)
ptlock_free(ptdesc);
__folio_clear_pgtable(folio);
- lruvec_stat_sub_folio(folio, NR_PAGETABLE);
}
static inline void pagetable_dtor_free(struct ptdesc *ptdesc)
--
2.51.2
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 13/22] mm: account page table pages when allocated
@ 2026-07-14 14:04 ` Kevin Brodsky
0 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:04 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
As a step towards removing pagetable ctor/dtor calls for kernel
mm's, move the memory accounting from the ctor/dtor to
pagetable_{alloc,free}.
The ctor is normally called after pagetable_alloc() (and dtor before
pagetable_free()) so this patch should have no functional effect in
most cases. Where calls to ctor/dtor are currently missing (e.g.
x86's split_large_page()), this patch should improve the accounting.
This patch is based on Matthew's earlier implementation linked
below, with the difference that when freeing the accounting is
updated in __pagetable_free(), meaning that the update is delayed
until the pages are actually freed in the
CONFIG_ASYNC_KERNEL_PGTABLE_FREE case. This shouldn't matter in
practice.
Suggested-by: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Link: https://lore.kernel.org/r/20251113140448.1814860-3-willy@infradead.org
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
include/linux/mm.h | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index b336eb32faa0..361a0d7b74c5 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -3681,6 +3681,11 @@ static inline struct ptdesc *pagetable_alloc_noprof(gfp_t gfp, unsigned int orde
{
struct page *page = alloc_pages_noprof(gfp | __GFP_COMP, order);
+ if (!page)
+ return NULL;
+
+ lruvec_stat_add_folio(page_folio(page), NR_PAGETABLE);
+
return page_ptdesc(page);
}
#define pagetable_alloc(...) alloc_hooks(pagetable_alloc_noprof(__VA_ARGS__))
@@ -3689,6 +3694,8 @@ static inline void __pagetable_free(struct ptdesc *pt)
{
struct page *page = ptdesc_page(pt);
+ lruvec_stat_sub_folio(page_folio(page), NR_PAGETABLE);
+
__free_pages(page, compound_order(page));
}
@@ -3797,7 +3804,6 @@ static inline void __pagetable_ctor(struct ptdesc *ptdesc)
struct folio *folio = ptdesc_folio(ptdesc);
__folio_set_pgtable(folio);
- lruvec_stat_add_folio(folio, NR_PAGETABLE);
}
static inline void pagetable_dtor(struct ptdesc *ptdesc)
@@ -3806,7 +3812,6 @@ static inline void pagetable_dtor(struct ptdesc *ptdesc)
ptlock_free(ptdesc);
__folio_clear_pgtable(folio);
- lruvec_stat_sub_folio(folio, NR_PAGETABLE);
}
static inline void pagetable_dtor_free(struct ptdesc *ptdesc)
--
2.51.2
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 14/22] mm: set page table page type when allocated
2026-07-14 14:03 ` Kevin Brodsky
@ 2026-07-14 14:04 ` Kevin Brodsky
-1 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:04 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
As a step towards removing pagetable ctor/dtor calls for kernel
mm's, move the page type updates from the ctor/dtor to
pagetable_{alloc,free}.
__pagetable_ctor() is now empty so remove it;
pagetable_{pud,p4d,pgd}_ctor() will be removed at a later stage.
The ctor is normally called after pagetable_alloc() (and dtor before
pagetable_free()) so this patch should have no functional effect in
most cases. Where calls to ctor/dtor are currently missing (e.g.
x86's split_large_page()), this patch will ensure the page type is
set correctly.
This patch is based on Matthew's earlier implementation linked
below, with the difference that when freeing the page type is
cleared in __pagetable_free(), meaning that the update is delayed
until the pages are actually freed in the
CONFIG_ASYNC_KERNEL_PGTABLE_FREE case. This shouldn't matter in
practice.
Suggested-by: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Link: https://lore.kernel.org/r/20251113140448.1814860-4-willy@infradead.org
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
include/linux/mm.h | 17 ++---------------
1 file changed, 2 insertions(+), 15 deletions(-)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 361a0d7b74c5..94f0fb1c662a 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -3684,6 +3684,7 @@ static inline struct ptdesc *pagetable_alloc_noprof(gfp_t gfp, unsigned int orde
if (!page)
return NULL;
+ __folio_set_pgtable(page_folio(page));
lruvec_stat_add_folio(page_folio(page), NR_PAGETABLE);
return page_ptdesc(page);
@@ -3694,6 +3695,7 @@ static inline void __pagetable_free(struct ptdesc *pt)
{
struct page *page = ptdesc_page(pt);
+ __folio_clear_pgtable(page_folio(page));
lruvec_stat_sub_folio(page_folio(page), NR_PAGETABLE);
__free_pages(page, compound_order(page));
@@ -3799,19 +3801,9 @@ static inline bool ptlock_init(struct ptdesc *ptdesc) { return true; }
static inline void ptlock_free(struct ptdesc *ptdesc) {}
#endif /* defined(CONFIG_SPLIT_PTE_PTLOCKS) */
-static inline void __pagetable_ctor(struct ptdesc *ptdesc)
-{
- struct folio *folio = ptdesc_folio(ptdesc);
-
- __folio_set_pgtable(folio);
-}
-
static inline void pagetable_dtor(struct ptdesc *ptdesc)
{
- struct folio *folio = ptdesc_folio(ptdesc);
-
ptlock_free(ptdesc);
- __folio_clear_pgtable(folio);
}
static inline void pagetable_dtor_free(struct ptdesc *ptdesc)
@@ -3825,7 +3817,6 @@ static inline bool pagetable_pte_ctor(struct mm_struct *mm,
{
if (!mm_is_kernel(mm) && !ptlock_init(ptdesc))
return false;
- __pagetable_ctor(ptdesc);
return true;
}
@@ -3917,7 +3908,6 @@ static inline bool pagetable_pmd_ctor(struct mm_struct *mm,
if (!mm_is_kernel(mm) && !pmd_ptlock_init(ptdesc))
return false;
ptdesc_pmd_pts_init(ptdesc);
- __pagetable_ctor(ptdesc);
return true;
}
@@ -3942,17 +3932,14 @@ static inline spinlock_t *pud_lock(struct mm_struct *mm, pud_t *pud)
static inline void pagetable_pud_ctor(struct ptdesc *ptdesc)
{
- __pagetable_ctor(ptdesc);
}
static inline void pagetable_p4d_ctor(struct ptdesc *ptdesc)
{
- __pagetable_ctor(ptdesc);
}
static inline void pagetable_pgd_ctor(struct ptdesc *ptdesc)
{
- __pagetable_ctor(ptdesc);
}
extern void __init pagecache_init(void);
--
2.51.2
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 14/22] mm: set page table page type when allocated
@ 2026-07-14 14:04 ` Kevin Brodsky
0 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:04 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
As a step towards removing pagetable ctor/dtor calls for kernel
mm's, move the page type updates from the ctor/dtor to
pagetable_{alloc,free}.
__pagetable_ctor() is now empty so remove it;
pagetable_{pud,p4d,pgd}_ctor() will be removed at a later stage.
The ctor is normally called after pagetable_alloc() (and dtor before
pagetable_free()) so this patch should have no functional effect in
most cases. Where calls to ctor/dtor are currently missing (e.g.
x86's split_large_page()), this patch will ensure the page type is
set correctly.
This patch is based on Matthew's earlier implementation linked
below, with the difference that when freeing the page type is
cleared in __pagetable_free(), meaning that the update is delayed
until the pages are actually freed in the
CONFIG_ASYNC_KERNEL_PGTABLE_FREE case. This shouldn't matter in
practice.
Suggested-by: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Link: https://lore.kernel.org/r/20251113140448.1814860-4-willy@infradead.org
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
include/linux/mm.h | 17 ++---------------
1 file changed, 2 insertions(+), 15 deletions(-)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 361a0d7b74c5..94f0fb1c662a 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -3684,6 +3684,7 @@ static inline struct ptdesc *pagetable_alloc_noprof(gfp_t gfp, unsigned int orde
if (!page)
return NULL;
+ __folio_set_pgtable(page_folio(page));
lruvec_stat_add_folio(page_folio(page), NR_PAGETABLE);
return page_ptdesc(page);
@@ -3694,6 +3695,7 @@ static inline void __pagetable_free(struct ptdesc *pt)
{
struct page *page = ptdesc_page(pt);
+ __folio_clear_pgtable(page_folio(page));
lruvec_stat_sub_folio(page_folio(page), NR_PAGETABLE);
__free_pages(page, compound_order(page));
@@ -3799,19 +3801,9 @@ static inline bool ptlock_init(struct ptdesc *ptdesc) { return true; }
static inline void ptlock_free(struct ptdesc *ptdesc) {}
#endif /* defined(CONFIG_SPLIT_PTE_PTLOCKS) */
-static inline void __pagetable_ctor(struct ptdesc *ptdesc)
-{
- struct folio *folio = ptdesc_folio(ptdesc);
-
- __folio_set_pgtable(folio);
-}
-
static inline void pagetable_dtor(struct ptdesc *ptdesc)
{
- struct folio *folio = ptdesc_folio(ptdesc);
-
ptlock_free(ptdesc);
- __folio_clear_pgtable(folio);
}
static inline void pagetable_dtor_free(struct ptdesc *ptdesc)
@@ -3825,7 +3817,6 @@ static inline bool pagetable_pte_ctor(struct mm_struct *mm,
{
if (!mm_is_kernel(mm) && !ptlock_init(ptdesc))
return false;
- __pagetable_ctor(ptdesc);
return true;
}
@@ -3917,7 +3908,6 @@ static inline bool pagetable_pmd_ctor(struct mm_struct *mm,
if (!mm_is_kernel(mm) && !pmd_ptlock_init(ptdesc))
return false;
ptdesc_pmd_pts_init(ptdesc);
- __pagetable_ctor(ptdesc);
return true;
}
@@ -3942,17 +3932,14 @@ static inline spinlock_t *pud_lock(struct mm_struct *mm, pud_t *pud)
static inline void pagetable_pud_ctor(struct ptdesc *ptdesc)
{
- __pagetable_ctor(ptdesc);
}
static inline void pagetable_p4d_ctor(struct ptdesc *ptdesc)
{
- __pagetable_ctor(ptdesc);
}
static inline void pagetable_pgd_ctor(struct ptdesc *ptdesc)
{
- __pagetable_ctor(ptdesc);
}
extern void __init pagecache_init(void);
--
2.51.2
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 15/22] mm: only initialise pt_share_count for user pgtables
2026-07-14 14:03 ` Kevin Brodsky
@ 2026-07-14 14:04 ` Kevin Brodsky
-1 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:04 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
ptdesc_pmd_pts_init() initialises the pt_share_count ptdesc field.
That field is only used for hugetlb tracking purposes, so there is
no need to initialise it for kernel page tables. Skip the call for
kernel page tables, like pmd_ptlock_init().
From now on pagetable_*_ctor() and pagetable_dtor() do nothing for
kernel page tables.
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
include/linux/mm.h | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 94f0fb1c662a..b217ccbed5a3 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -3905,9 +3905,12 @@ static inline spinlock_t *pmd_lock(struct mm_struct *mm, pmd_t *pmd)
static inline bool pagetable_pmd_ctor(struct mm_struct *mm,
struct ptdesc *ptdesc)
{
- if (!mm_is_kernel(mm) && !pmd_ptlock_init(ptdesc))
- return false;
- ptdesc_pmd_pts_init(ptdesc);
+ if (!mm_is_kernel(mm)) {
+ if (!pmd_ptlock_init(ptdesc))
+ return false;
+ ptdesc_pmd_pts_init(ptdesc);
+ }
+
return true;
}
--
2.51.2
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 15/22] mm: only initialise pt_share_count for user pgtables
@ 2026-07-14 14:04 ` Kevin Brodsky
0 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:04 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
ptdesc_pmd_pts_init() initialises the pt_share_count ptdesc field.
That field is only used for hugetlb tracking purposes, so there is
no need to initialise it for kernel page tables. Skip the call for
kernel page tables, like pmd_ptlock_init().
From now on pagetable_*_ctor() and pagetable_dtor() do nothing for
kernel page tables.
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
include/linux/mm.h | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 94f0fb1c662a..b217ccbed5a3 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -3905,9 +3905,12 @@ static inline spinlock_t *pmd_lock(struct mm_struct *mm, pmd_t *pmd)
static inline bool pagetable_pmd_ctor(struct mm_struct *mm,
struct ptdesc *ptdesc)
{
- if (!mm_is_kernel(mm) && !pmd_ptlock_init(ptdesc))
- return false;
- ptdesc_pmd_pts_init(ptdesc);
+ if (!mm_is_kernel(mm)) {
+ if (!pmd_ptlock_init(ptdesc))
+ return false;
+ ptdesc_pmd_pts_init(ptdesc);
+ }
+
return true;
}
--
2.51.2
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 16/22] efi: mark efi_mm as a kernel mm
2026-07-14 14:03 ` Kevin Brodsky
@ 2026-07-14 14:04 ` Kevin Brodsky
-1 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:04 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
efi_mm is a kernel-owned address space used for EFI runtime
mappings, but it is currently treated like a user address space when
manipulating its page tables. There does not seem to be a good
reason for this, and it creates unnecessary complications when
creating its page tables.
Mark it with the new MMF_KERNEL flag so that the page table handling
treats it like init_mm. In particular, this means that:
* Split page table locks are no longer initialised or used for
efi_mm's page tables.
* pagetable_*_ctor() and pagetable_dtor() no longer need to be
called for efi_mm's page tables.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
drivers/firmware/efi/efi.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 0327a39d31fa..e5ca45bdc890 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -69,6 +69,7 @@ struct mm_struct efi_mm = {
.mm_mt = MTREE_INIT_EXT(mm_mt, MM_MT_FLAGS, efi_mm.mmap_lock),
.mm_users = ATOMIC_INIT(2),
.mm_count = ATOMIC_INIT(1),
+ .flags = MM_FLAGS_INIT(MMF_KERNEL_MASK),
.write_protect_seq = SEQCNT_ZERO(efi_mm.write_protect_seq),
MMAP_LOCK_INITIALIZER(efi_mm)
.page_table_lock = __SPIN_LOCK_UNLOCKED(efi_mm.page_table_lock),
--
2.51.2
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 16/22] efi: mark efi_mm as a kernel mm
@ 2026-07-14 14:04 ` Kevin Brodsky
0 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:04 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
efi_mm is a kernel-owned address space used for EFI runtime
mappings, but it is currently treated like a user address space when
manipulating its page tables. There does not seem to be a good
reason for this, and it creates unnecessary complications when
creating its page tables.
Mark it with the new MMF_KERNEL flag so that the page table handling
treats it like init_mm. In particular, this means that:
* Split page table locks are no longer initialised or used for
efi_mm's page tables.
* pagetable_*_ctor() and pagetable_dtor() no longer need to be
called for efi_mm's page tables.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
drivers/firmware/efi/efi.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 0327a39d31fa..e5ca45bdc890 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -69,6 +69,7 @@ struct mm_struct efi_mm = {
.mm_mt = MTREE_INIT_EXT(mm_mt, MM_MT_FLAGS, efi_mm.mmap_lock),
.mm_users = ATOMIC_INIT(2),
.mm_count = ATOMIC_INIT(1),
+ .flags = MM_FLAGS_INIT(MMF_KERNEL_MASK),
.write_protect_seq = SEQCNT_ZERO(efi_mm.write_protect_seq),
MMAP_LOCK_INITIALIZER(efi_mm)
.page_table_lock = __SPIN_LOCK_UNLOCKED(efi_mm.page_table_lock),
--
2.51.2
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 17/22] mm: pagewalk: drop redundant address check for kernel mm walks
2026-07-14 14:03 ` Kevin Brodsky
@ 2026-07-14 14:04 ` Kevin Brodsky
-1 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:04 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
Commit 8b1cb4a2e819 ("mm/pagewalk: fix EFI_PGT_DUMP of
espfix area") made no-VMA page table walks use
pte_offset_kernel() for any address above TASK_SIZE. This avoided
pte_offset_map() validation on EFI page table dumps, where efi_mm
could walk x86 espfix PMDs that intentionally look bad to pmd_bad().
efi_mm is now marked with MMF_KERNEL, and no-VMA walks use
mm_is_kernel() to select pte_offset_kernel() for kernel mm's. As a
result we no longer need to handle the EFI_PGT_DUMP case explicitly.The
address check is therefore redundant for EFI_PGT_DUMP and makes the
condition harder to reason about.
Remove the address check and associated comment; mm_is_kernel()
should be sufficient on its own.
Tested by booting x86 QEMU with CONFIG_EFI_PGT_DUMP=y and reading
/sys/kernel/debug/page_tables/efi.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
mm/pagewalk.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/mm/pagewalk.c b/mm/pagewalk.c
index a3f47d1de3c5..0dd9d4ad9b68 100644
--- a/mm/pagewalk.c
+++ b/mm/pagewalk.c
@@ -68,17 +68,14 @@ static int walk_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
if (walk->no_vma) {
/*
* pte_offset_map() might apply user-specific validation.
- * Indeed, on x86_64 the pmd entries set up by init_espfix_ap()
- * fit its pmd_bad() check (_PAGE_NX set and _PAGE_RW clear),
- * and CONFIG_EFI_PGT_DUMP efi_mm goes so far as to walk them.
*/
- if (mm_is_kernel(walk->mm) || addr >= TASK_SIZE)
+ if (mm_is_kernel(walk->mm))
pte = pte_offset_kernel(pmd, addr);
else
pte = pte_offset_map(pmd, addr);
if (pte) {
err = walk_pte_range_inner(pte, addr, end, walk);
- if (!mm_is_kernel(walk->mm) && addr < TASK_SIZE)
+ if (!mm_is_kernel(walk->mm))
pte_unmap(pte);
}
} else {
--
2.51.2
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 17/22] mm: pagewalk: drop redundant address check for kernel mm walks
@ 2026-07-14 14:04 ` Kevin Brodsky
0 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:04 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
Commit 8b1cb4a2e819 ("mm/pagewalk: fix EFI_PGT_DUMP of
espfix area") made no-VMA page table walks use
pte_offset_kernel() for any address above TASK_SIZE. This avoided
pte_offset_map() validation on EFI page table dumps, where efi_mm
could walk x86 espfix PMDs that intentionally look bad to pmd_bad().
efi_mm is now marked with MMF_KERNEL, and no-VMA walks use
mm_is_kernel() to select pte_offset_kernel() for kernel mm's. As a
result we no longer need to handle the EFI_PGT_DUMP case explicitly.The
address check is therefore redundant for EFI_PGT_DUMP and makes the
condition harder to reason about.
Remove the address check and associated comment; mm_is_kernel()
should be sufficient on its own.
Tested by booting x86 QEMU with CONFIG_EFI_PGT_DUMP=y and reading
/sys/kernel/debug/page_tables/efi.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
mm/pagewalk.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/mm/pagewalk.c b/mm/pagewalk.c
index a3f47d1de3c5..0dd9d4ad9b68 100644
--- a/mm/pagewalk.c
+++ b/mm/pagewalk.c
@@ -68,17 +68,14 @@ static int walk_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
if (walk->no_vma) {
/*
* pte_offset_map() might apply user-specific validation.
- * Indeed, on x86_64 the pmd entries set up by init_espfix_ap()
- * fit its pmd_bad() check (_PAGE_NX set and _PAGE_RW clear),
- * and CONFIG_EFI_PGT_DUMP efi_mm goes so far as to walk them.
*/
- if (mm_is_kernel(walk->mm) || addr >= TASK_SIZE)
+ if (mm_is_kernel(walk->mm))
pte = pte_offset_kernel(pmd, addr);
else
pte = pte_offset_map(pmd, addr);
if (pte) {
err = walk_pte_range_inner(pte, addr, end, walk);
- if (!mm_is_kernel(walk->mm) && addr < TASK_SIZE)
+ if (!mm_is_kernel(walk->mm))
pte_unmap(pte);
}
} else {
--
2.51.2
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 18/22] arm64: mm: drop explicit mm_is_efi() check in contpte
2026-07-14 14:03 ` Kevin Brodsky
@ 2026-07-14 14:04 ` Kevin Brodsky
-1 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:04 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
efi_mm is now marked as a kernel mm, like init_mm. mm_is_kernel()
therefore gives the right answer for efi_mm and mm_is_user() is now
equivalent to !mm_is_kernel().
Remove mm_is_user() and directly use mm_is_kernel() instead.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/arm64/mm/contpte.c | 26 +++++++++-----------------
1 file changed, 9 insertions(+), 17 deletions(-)
diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
index ad5c04cf66ff..e21e279101ca 100644
--- a/arch/arm64/mm/contpte.c
+++ b/arch/arm64/mm/contpte.c
@@ -4,23 +4,9 @@
*/
#include <linux/mm.h>
-#include <linux/efi.h>
#include <linux/export.h>
#include <asm/tlbflush.h>
-static inline bool mm_is_user(struct mm_struct *mm)
-{
- /*
- * Don't attempt to apply the contig bit to kernel mappings, because
- * dynamically adding/removing the contig bit can cause page faults.
- * These racing faults are ok for user space, since they get serialized
- * on the PTL. But kernel mappings can't tolerate faults.
- */
- if (unlikely(mm_is_efi(mm)))
- return false;
- return !mm_is_kernel(mm);
-}
-
static inline pte_t *contpte_align_down(pte_t *ptep)
{
return PTR_ALIGN_DOWN(ptep, sizeof(*ptep) * CONT_PTES);
@@ -263,7 +249,13 @@ void __contpte_try_fold(struct mm_struct *mm, unsigned long addr,
int i;
- if (!mm_is_user(mm))
+ /*
+ * Don't attempt to apply the contig bit to kernel mappings, because
+ * dynamically adding/removing the contig bit can cause page faults.
+ * These racing faults are ok for user space, since they get serialized
+ * on the PTL. But kernel mappings can't tolerate faults.
+ */
+ if (mm_is_kernel(mm))
return;
page = pte_page(pte);
@@ -302,7 +294,7 @@ void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
* We have already checked that the ptes are contiguous in
* contpte_try_unfold(), so just check that the mm is user space.
*/
- if (!mm_is_user(mm))
+ if (mm_is_kernel(mm))
return;
pte = pte_mknoncont(pte);
@@ -465,7 +457,7 @@ void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
*/
VM_WARN_ON(nr == 1);
- if (!mm_is_user(mm))
+ if (mm_is_kernel(mm))
return __set_ptes(mm, addr, ptep, pte, nr);
end = addr + (nr << PAGE_SHIFT);
--
2.51.2
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 18/22] arm64: mm: drop explicit mm_is_efi() check in contpte
@ 2026-07-14 14:04 ` Kevin Brodsky
0 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:04 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
efi_mm is now marked as a kernel mm, like init_mm. mm_is_kernel()
therefore gives the right answer for efi_mm and mm_is_user() is now
equivalent to !mm_is_kernel().
Remove mm_is_user() and directly use mm_is_kernel() instead.
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/arm64/mm/contpte.c | 26 +++++++++-----------------
1 file changed, 9 insertions(+), 17 deletions(-)
diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
index ad5c04cf66ff..e21e279101ca 100644
--- a/arch/arm64/mm/contpte.c
+++ b/arch/arm64/mm/contpte.c
@@ -4,23 +4,9 @@
*/
#include <linux/mm.h>
-#include <linux/efi.h>
#include <linux/export.h>
#include <asm/tlbflush.h>
-static inline bool mm_is_user(struct mm_struct *mm)
-{
- /*
- * Don't attempt to apply the contig bit to kernel mappings, because
- * dynamically adding/removing the contig bit can cause page faults.
- * These racing faults are ok for user space, since they get serialized
- * on the PTL. But kernel mappings can't tolerate faults.
- */
- if (unlikely(mm_is_efi(mm)))
- return false;
- return !mm_is_kernel(mm);
-}
-
static inline pte_t *contpte_align_down(pte_t *ptep)
{
return PTR_ALIGN_DOWN(ptep, sizeof(*ptep) * CONT_PTES);
@@ -263,7 +249,13 @@ void __contpte_try_fold(struct mm_struct *mm, unsigned long addr,
int i;
- if (!mm_is_user(mm))
+ /*
+ * Don't attempt to apply the contig bit to kernel mappings, because
+ * dynamically adding/removing the contig bit can cause page faults.
+ * These racing faults are ok for user space, since they get serialized
+ * on the PTL. But kernel mappings can't tolerate faults.
+ */
+ if (mm_is_kernel(mm))
return;
page = pte_page(pte);
@@ -302,7 +294,7 @@ void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
* We have already checked that the ptes are contiguous in
* contpte_try_unfold(), so just check that the mm is user space.
*/
- if (!mm_is_user(mm))
+ if (mm_is_kernel(mm))
return;
pte = pte_mknoncont(pte);
@@ -465,7 +457,7 @@ void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
*/
VM_WARN_ON(nr == 1);
- if (!mm_is_user(mm))
+ if (mm_is_kernel(mm))
return __set_ptes(mm, addr, ptep, pte, nr);
end = addr + (nr << PAGE_SHIFT);
--
2.51.2
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 19/22] x86/tboot: mark tboot_mm as a kernel mm
2026-07-14 14:03 ` Kevin Brodsky
@ 2026-07-14 14:04 ` Kevin Brodsky
-1 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:04 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
tboot_mm is a kernel-owned address space used to build the
identity map for tboot shutdown. Mark it with MMF_KERNEL so
page table allocation and initialisation code treats its page tables
as kernel page tables.
Having marked tboot_mm as a kernel mm, we also need to convert
pte_alloc_map() (user PTE) to pte_alloc_kernel() (kernel PTE), and
drop the matching pte_unmap().
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/x86/kernel/tboot.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c
index 46b8f1f16676..08c899f88e41 100644
--- a/arch/x86/kernel/tboot.c
+++ b/arch/x86/kernel/tboot.c
@@ -99,6 +99,7 @@ static struct mm_struct tboot_mm = {
.pgd = swapper_pg_dir,
.mm_users = ATOMIC_INIT(2),
.mm_count = ATOMIC_INIT(1),
+ .flags = MM_FLAGS_INIT(MMF_KERNEL_MASK),
.write_protect_seq = SEQCNT_ZERO(tboot_mm.write_protect_seq),
MMAP_LOCK_INITIALIZER(init_mm)
.page_table_lock = __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock),
@@ -129,11 +130,10 @@ static int map_tboot_page(unsigned long vaddr, unsigned long pfn,
pmd = pmd_alloc(&tboot_mm, pud, vaddr);
if (!pmd)
return -1;
- pte = pte_alloc_map(&tboot_mm, pmd, vaddr);
+ pte = pte_alloc_kernel(pmd, vaddr);
if (!pte)
return -1;
set_pte_at(&tboot_mm, vaddr, pte, pfn_pte(pfn, prot));
- pte_unmap(pte);
/*
* PTI poisons low addresses in the kernel page tables in the
--
2.51.2
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 19/22] x86/tboot: mark tboot_mm as a kernel mm
@ 2026-07-14 14:04 ` Kevin Brodsky
0 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:04 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
tboot_mm is a kernel-owned address space used to build the
identity map for tboot shutdown. Mark it with MMF_KERNEL so
page table allocation and initialisation code treats its page tables
as kernel page tables.
Having marked tboot_mm as a kernel mm, we also need to convert
pte_alloc_map() (user PTE) to pte_alloc_kernel() (kernel PTE), and
drop the matching pte_unmap().
Assisted-by: Codex:GPT-5.5
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/x86/kernel/tboot.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c
index 46b8f1f16676..08c899f88e41 100644
--- a/arch/x86/kernel/tboot.c
+++ b/arch/x86/kernel/tboot.c
@@ -99,6 +99,7 @@ static struct mm_struct tboot_mm = {
.pgd = swapper_pg_dir,
.mm_users = ATOMIC_INIT(2),
.mm_count = ATOMIC_INIT(1),
+ .flags = MM_FLAGS_INIT(MMF_KERNEL_MASK),
.write_protect_seq = SEQCNT_ZERO(tboot_mm.write_protect_seq),
MMAP_LOCK_INITIALIZER(init_mm)
.page_table_lock = __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock),
@@ -129,11 +130,10 @@ static int map_tboot_page(unsigned long vaddr, unsigned long pfn,
pmd = pmd_alloc(&tboot_mm, pud, vaddr);
if (!pmd)
return -1;
- pte = pte_alloc_map(&tboot_mm, pmd, vaddr);
+ pte = pte_alloc_kernel(pmd, vaddr);
if (!pte)
return -1;
set_pte_at(&tboot_mm, vaddr, pte, pfn_pte(pfn, prot));
- pte_unmap(pte);
/*
* PTI poisons low addresses in the kernel page tables in the
--
2.51.2
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 20/22] arm64: mm: drop ctor/dtor calls for kernel page tables
2026-07-14 14:03 ` Kevin Brodsky
@ 2026-07-14 14:04 ` Kevin Brodsky
-1 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:04 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
Thanks to recent changes:
* pagetable_*_ctor() and pagetable_dtor() do nothing for kernel page
tables.
* efi_mm is also treated like a kernel mm by the page table logic,
including ctors.
We can therefore drop the calls to ctors when allocating special
kernel page tables in mmu.c, as well as the dtor call when freeing
hotplug page tables.
Since we no longer need the owning mm or page table level when
allocating them, we can also remove both the init_mm/special_mm
wrappers and the pgtable_level callback argument.
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/arm64/mm/mmu.c | 82 +++++++++++++++--------------------------------------
1 file changed, 23 insertions(+), 59 deletions(-)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index f723bcf68174..f1400c6f68ba 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -103,7 +103,7 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
}
EXPORT_SYMBOL(phys_mem_access_prot);
-static phys_addr_t __init early_pgtable_alloc(enum pgtable_level pgtable_level)
+static phys_addr_t __init early_pgtable_alloc(void)
{
phys_addr_t phys;
@@ -195,7 +195,7 @@ static bool pte_range_has_valid_noncont(pte_t *ptep)
static int alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
unsigned long end, phys_addr_t phys,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(enum pgtable_level),
+ phys_addr_t (*pgtable_alloc)(void),
int flags)
{
unsigned long next;
@@ -210,7 +210,7 @@ static int alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
if (flags & NO_EXEC_MAPPINGS)
pmdval |= PMD_TABLE_PXN;
BUG_ON(!pgtable_alloc);
- pte_phys = pgtable_alloc(PGTABLE_LEVEL_PTE);
+ pte_phys = pgtable_alloc();
if (pte_phys == INVALID_PHYS_ADDR)
return -ENOMEM;
ptep = pte_set_fixmap(pte_phys);
@@ -251,7 +251,7 @@ static int alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
static int init_pmd(pmd_t *pmdp, unsigned long addr, unsigned long end,
phys_addr_t phys, pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(enum pgtable_level), int flags)
+ phys_addr_t (*pgtable_alloc)(void), int flags)
{
unsigned long next;
@@ -303,7 +303,7 @@ static bool pmd_range_has_valid_noncont(pmd_t *pmdp)
static int alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
unsigned long end, phys_addr_t phys,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(enum pgtable_level),
+ phys_addr_t (*pgtable_alloc)(void),
int flags)
{
int ret;
@@ -322,7 +322,7 @@ static int alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
if (flags & NO_EXEC_MAPPINGS)
pudval |= PUD_TABLE_PXN;
BUG_ON(!pgtable_alloc);
- pmd_phys = pgtable_alloc(PGTABLE_LEVEL_PMD);
+ pmd_phys = pgtable_alloc();
if (pmd_phys == INVALID_PHYS_ADDR)
return -ENOMEM;
pmdp = pmd_set_fixmap(pmd_phys);
@@ -361,7 +361,7 @@ static int alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
static int alloc_init_pud(p4d_t *p4dp, unsigned long addr, unsigned long end,
phys_addr_t phys, pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(enum pgtable_level),
+ phys_addr_t (*pgtable_alloc)(void),
int flags)
{
int ret = 0;
@@ -376,7 +376,7 @@ static int alloc_init_pud(p4d_t *p4dp, unsigned long addr, unsigned long end,
if (flags & NO_EXEC_MAPPINGS)
p4dval |= P4D_TABLE_PXN;
BUG_ON(!pgtable_alloc);
- pud_phys = pgtable_alloc(PGTABLE_LEVEL_PUD);
+ pud_phys = pgtable_alloc();
if (pud_phys == INVALID_PHYS_ADDR)
return -ENOMEM;
pudp = pud_set_fixmap(pud_phys);
@@ -428,7 +428,7 @@ static int alloc_init_pud(p4d_t *p4dp, unsigned long addr, unsigned long end,
static int alloc_init_p4d(pgd_t *pgdp, unsigned long addr, unsigned long end,
phys_addr_t phys, pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(enum pgtable_level),
+ phys_addr_t (*pgtable_alloc)(void),
int flags)
{
int ret;
@@ -443,7 +443,7 @@ static int alloc_init_p4d(pgd_t *pgdp, unsigned long addr, unsigned long end,
if (flags & NO_EXEC_MAPPINGS)
pgdval |= PGD_TABLE_PXN;
BUG_ON(!pgtable_alloc);
- p4d_phys = pgtable_alloc(PGTABLE_LEVEL_P4D);
+ p4d_phys = pgtable_alloc();
if (p4d_phys == INVALID_PHYS_ADDR)
return -ENOMEM;
p4dp = p4d_set_fixmap(p4d_phys);
@@ -480,7 +480,7 @@ static int alloc_init_p4d(pgd_t *pgdp, unsigned long addr, unsigned long end,
static int __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys,
unsigned long virt, phys_addr_t size,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(enum pgtable_level),
+ phys_addr_t (*pgtable_alloc)(void),
int flags)
{
int ret;
@@ -513,7 +513,7 @@ static int __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys,
static int __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
unsigned long virt, phys_addr_t size,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(enum pgtable_level),
+ phys_addr_t (*pgtable_alloc)(void),
int flags)
{
int ret;
@@ -529,7 +529,7 @@ static int __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
static void early_create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
unsigned long virt, phys_addr_t size,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(enum pgtable_level),
+ phys_addr_t (*pgtable_alloc)(void),
int flags)
{
int ret;
@@ -540,55 +540,20 @@ static void early_create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
panic("Failed to create page tables\n");
}
-static phys_addr_t __pgd_pgtable_alloc(struct mm_struct *mm, gfp_t gfp,
- enum pgtable_level pgtable_level)
+static phys_addr_t pgd_pgtable_alloc_gfp(gfp_t gfp)
{
/* Page is zeroed by init_clear_pgtable() so don't duplicate effort. */
struct ptdesc *ptdesc = pagetable_alloc(gfp & ~__GFP_ZERO, 0);
- phys_addr_t pa;
if (!ptdesc)
return INVALID_PHYS_ADDR;
- pa = page_to_phys(ptdesc_page(ptdesc));
-
- switch (pgtable_level) {
- case PGTABLE_LEVEL_PTE:
- BUG_ON(!pagetable_pte_ctor(mm, ptdesc));
- break;
- case PGTABLE_LEVEL_PMD:
- BUG_ON(!pagetable_pmd_ctor(mm, ptdesc));
- break;
- case PGTABLE_LEVEL_PUD:
- pagetable_pud_ctor(ptdesc);
- break;
- case PGTABLE_LEVEL_P4D:
- pagetable_p4d_ctor(ptdesc);
- break;
- case PGTABLE_LEVEL_PGD:
- VM_WARN_ON(1);
- break;
- }
-
- return pa;
-}
-
-static phys_addr_t
-pgd_pgtable_alloc_init_mm_gfp(enum pgtable_level pgtable_level, gfp_t gfp)
-{
- return __pgd_pgtable_alloc(&init_mm, gfp, pgtable_level);
-}
-
-static phys_addr_t __maybe_unused
-pgd_pgtable_alloc_init_mm(enum pgtable_level pgtable_level)
-{
- return pgd_pgtable_alloc_init_mm_gfp(pgtable_level, GFP_PGTABLE_KERNEL);
+ return page_to_phys(ptdesc_page(ptdesc));
}
-static phys_addr_t
-pgd_pgtable_alloc_special_mm(enum pgtable_level pgtable_level)
+static phys_addr_t pgd_pgtable_alloc(void)
{
- return __pgd_pgtable_alloc(NULL, GFP_PGTABLE_KERNEL, pgtable_level);
+ return pgd_pgtable_alloc_gfp(GFP_PGTABLE_KERNEL);
}
static void split_contpte(pte_t *ptep)
@@ -609,7 +574,7 @@ static int split_pmd(pmd_t *pmdp, pmd_t pmd, gfp_t gfp, bool to_cont)
pte_t *ptep;
int i;
- pte_phys = pgd_pgtable_alloc_init_mm_gfp(PGTABLE_LEVEL_PTE, gfp);
+ pte_phys = pgd_pgtable_alloc_gfp(gfp);
if (pte_phys == INVALID_PHYS_ADDR)
return -ENOMEM;
ptep = (pte_t *)phys_to_virt(pte_phys);
@@ -656,7 +621,7 @@ static int split_pud(pud_t *pudp, pud_t pud, gfp_t gfp, bool to_cont)
pmd_t *pmdp;
int i;
- pmd_phys = pgd_pgtable_alloc_init_mm_gfp(PGTABLE_LEVEL_PMD, gfp);
+ pmd_phys = pgd_pgtable_alloc_gfp(gfp);
if (pmd_phys == INVALID_PHYS_ADDR)
return -ENOMEM;
pmdp = (pmd_t *)phys_to_virt(pmd_phys);
@@ -1035,7 +1000,7 @@ void __init create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
early_create_pgd_mapping(mm->pgd, phys, virt, size, prot,
- pgd_pgtable_alloc_special_mm, flags);
+ pgd_pgtable_alloc, flags);
}
static void update_mapping_prot(phys_addr_t phys, unsigned long virt,
@@ -1249,7 +1214,7 @@ static void __init declare_vma(struct vm_struct *vma,
static phys_addr_t kpti_ng_temp_alloc __initdata;
-static phys_addr_t __init kpti_ng_pgd_alloc(enum pgtable_level pgtable_level)
+static phys_addr_t __init kpti_ng_pgd_alloc(void)
{
kpti_ng_temp_alloc -= PAGE_SIZE;
return kpti_ng_temp_alloc;
@@ -1357,7 +1322,7 @@ static int __init map_entry_trampoline(void)
memset(tramp_pg_dir, 0, PGD_SIZE);
early_create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS,
entry_tramp_text_size(), prot,
- pgd_pgtable_alloc_init_mm, NO_BLOCK_MAPPINGS);
+ pgd_pgtable_alloc, NO_BLOCK_MAPPINGS);
/* Map both the text and data into the kernel page table */
for (i = 0; i < DIV_ROUND_UP(entry_tramp_text_size(), PAGE_SIZE); i++)
@@ -1445,7 +1410,6 @@ static void free_hotplug_page_range(struct page *page, size_t size,
static void free_hotplug_pgtable_page(struct page *page)
{
- pagetable_dtor(page_ptdesc(page));
free_hotplug_page_range(page, PAGE_SIZE, NULL);
}
@@ -1958,7 +1922,7 @@ int arch_add_memory(int nid, u64 start, u64 size,
flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
ret = __create_pgd_mapping(swapper_pg_dir, start, __phys_to_virt(start),
- size, params->pgprot, pgd_pgtable_alloc_init_mm,
+ size, params->pgprot, pgd_pgtable_alloc,
flags);
if (ret)
goto err;
--
2.51.2
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 20/22] arm64: mm: drop ctor/dtor calls for kernel page tables
@ 2026-07-14 14:04 ` Kevin Brodsky
0 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:04 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
Thanks to recent changes:
* pagetable_*_ctor() and pagetable_dtor() do nothing for kernel page
tables.
* efi_mm is also treated like a kernel mm by the page table logic,
including ctors.
We can therefore drop the calls to ctors when allocating special
kernel page tables in mmu.c, as well as the dtor call when freeing
hotplug page tables.
Since we no longer need the owning mm or page table level when
allocating them, we can also remove both the init_mm/special_mm
wrappers and the pgtable_level callback argument.
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/arm64/mm/mmu.c | 82 +++++++++++++++--------------------------------------
1 file changed, 23 insertions(+), 59 deletions(-)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index f723bcf68174..f1400c6f68ba 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -103,7 +103,7 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
}
EXPORT_SYMBOL(phys_mem_access_prot);
-static phys_addr_t __init early_pgtable_alloc(enum pgtable_level pgtable_level)
+static phys_addr_t __init early_pgtable_alloc(void)
{
phys_addr_t phys;
@@ -195,7 +195,7 @@ static bool pte_range_has_valid_noncont(pte_t *ptep)
static int alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
unsigned long end, phys_addr_t phys,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(enum pgtable_level),
+ phys_addr_t (*pgtable_alloc)(void),
int flags)
{
unsigned long next;
@@ -210,7 +210,7 @@ static int alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
if (flags & NO_EXEC_MAPPINGS)
pmdval |= PMD_TABLE_PXN;
BUG_ON(!pgtable_alloc);
- pte_phys = pgtable_alloc(PGTABLE_LEVEL_PTE);
+ pte_phys = pgtable_alloc();
if (pte_phys == INVALID_PHYS_ADDR)
return -ENOMEM;
ptep = pte_set_fixmap(pte_phys);
@@ -251,7 +251,7 @@ static int alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
static int init_pmd(pmd_t *pmdp, unsigned long addr, unsigned long end,
phys_addr_t phys, pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(enum pgtable_level), int flags)
+ phys_addr_t (*pgtable_alloc)(void), int flags)
{
unsigned long next;
@@ -303,7 +303,7 @@ static bool pmd_range_has_valid_noncont(pmd_t *pmdp)
static int alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
unsigned long end, phys_addr_t phys,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(enum pgtable_level),
+ phys_addr_t (*pgtable_alloc)(void),
int flags)
{
int ret;
@@ -322,7 +322,7 @@ static int alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
if (flags & NO_EXEC_MAPPINGS)
pudval |= PUD_TABLE_PXN;
BUG_ON(!pgtable_alloc);
- pmd_phys = pgtable_alloc(PGTABLE_LEVEL_PMD);
+ pmd_phys = pgtable_alloc();
if (pmd_phys == INVALID_PHYS_ADDR)
return -ENOMEM;
pmdp = pmd_set_fixmap(pmd_phys);
@@ -361,7 +361,7 @@ static int alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
static int alloc_init_pud(p4d_t *p4dp, unsigned long addr, unsigned long end,
phys_addr_t phys, pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(enum pgtable_level),
+ phys_addr_t (*pgtable_alloc)(void),
int flags)
{
int ret = 0;
@@ -376,7 +376,7 @@ static int alloc_init_pud(p4d_t *p4dp, unsigned long addr, unsigned long end,
if (flags & NO_EXEC_MAPPINGS)
p4dval |= P4D_TABLE_PXN;
BUG_ON(!pgtable_alloc);
- pud_phys = pgtable_alloc(PGTABLE_LEVEL_PUD);
+ pud_phys = pgtable_alloc();
if (pud_phys == INVALID_PHYS_ADDR)
return -ENOMEM;
pudp = pud_set_fixmap(pud_phys);
@@ -428,7 +428,7 @@ static int alloc_init_pud(p4d_t *p4dp, unsigned long addr, unsigned long end,
static int alloc_init_p4d(pgd_t *pgdp, unsigned long addr, unsigned long end,
phys_addr_t phys, pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(enum pgtable_level),
+ phys_addr_t (*pgtable_alloc)(void),
int flags)
{
int ret;
@@ -443,7 +443,7 @@ static int alloc_init_p4d(pgd_t *pgdp, unsigned long addr, unsigned long end,
if (flags & NO_EXEC_MAPPINGS)
pgdval |= PGD_TABLE_PXN;
BUG_ON(!pgtable_alloc);
- p4d_phys = pgtable_alloc(PGTABLE_LEVEL_P4D);
+ p4d_phys = pgtable_alloc();
if (p4d_phys == INVALID_PHYS_ADDR)
return -ENOMEM;
p4dp = p4d_set_fixmap(p4d_phys);
@@ -480,7 +480,7 @@ static int alloc_init_p4d(pgd_t *pgdp, unsigned long addr, unsigned long end,
static int __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys,
unsigned long virt, phys_addr_t size,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(enum pgtable_level),
+ phys_addr_t (*pgtable_alloc)(void),
int flags)
{
int ret;
@@ -513,7 +513,7 @@ static int __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys,
static int __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
unsigned long virt, phys_addr_t size,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(enum pgtable_level),
+ phys_addr_t (*pgtable_alloc)(void),
int flags)
{
int ret;
@@ -529,7 +529,7 @@ static int __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
static void early_create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
unsigned long virt, phys_addr_t size,
pgprot_t prot,
- phys_addr_t (*pgtable_alloc)(enum pgtable_level),
+ phys_addr_t (*pgtable_alloc)(void),
int flags)
{
int ret;
@@ -540,55 +540,20 @@ static void early_create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
panic("Failed to create page tables\n");
}
-static phys_addr_t __pgd_pgtable_alloc(struct mm_struct *mm, gfp_t gfp,
- enum pgtable_level pgtable_level)
+static phys_addr_t pgd_pgtable_alloc_gfp(gfp_t gfp)
{
/* Page is zeroed by init_clear_pgtable() so don't duplicate effort. */
struct ptdesc *ptdesc = pagetable_alloc(gfp & ~__GFP_ZERO, 0);
- phys_addr_t pa;
if (!ptdesc)
return INVALID_PHYS_ADDR;
- pa = page_to_phys(ptdesc_page(ptdesc));
-
- switch (pgtable_level) {
- case PGTABLE_LEVEL_PTE:
- BUG_ON(!pagetable_pte_ctor(mm, ptdesc));
- break;
- case PGTABLE_LEVEL_PMD:
- BUG_ON(!pagetable_pmd_ctor(mm, ptdesc));
- break;
- case PGTABLE_LEVEL_PUD:
- pagetable_pud_ctor(ptdesc);
- break;
- case PGTABLE_LEVEL_P4D:
- pagetable_p4d_ctor(ptdesc);
- break;
- case PGTABLE_LEVEL_PGD:
- VM_WARN_ON(1);
- break;
- }
-
- return pa;
-}
-
-static phys_addr_t
-pgd_pgtable_alloc_init_mm_gfp(enum pgtable_level pgtable_level, gfp_t gfp)
-{
- return __pgd_pgtable_alloc(&init_mm, gfp, pgtable_level);
-}
-
-static phys_addr_t __maybe_unused
-pgd_pgtable_alloc_init_mm(enum pgtable_level pgtable_level)
-{
- return pgd_pgtable_alloc_init_mm_gfp(pgtable_level, GFP_PGTABLE_KERNEL);
+ return page_to_phys(ptdesc_page(ptdesc));
}
-static phys_addr_t
-pgd_pgtable_alloc_special_mm(enum pgtable_level pgtable_level)
+static phys_addr_t pgd_pgtable_alloc(void)
{
- return __pgd_pgtable_alloc(NULL, GFP_PGTABLE_KERNEL, pgtable_level);
+ return pgd_pgtable_alloc_gfp(GFP_PGTABLE_KERNEL);
}
static void split_contpte(pte_t *ptep)
@@ -609,7 +574,7 @@ static int split_pmd(pmd_t *pmdp, pmd_t pmd, gfp_t gfp, bool to_cont)
pte_t *ptep;
int i;
- pte_phys = pgd_pgtable_alloc_init_mm_gfp(PGTABLE_LEVEL_PTE, gfp);
+ pte_phys = pgd_pgtable_alloc_gfp(gfp);
if (pte_phys == INVALID_PHYS_ADDR)
return -ENOMEM;
ptep = (pte_t *)phys_to_virt(pte_phys);
@@ -656,7 +621,7 @@ static int split_pud(pud_t *pudp, pud_t pud, gfp_t gfp, bool to_cont)
pmd_t *pmdp;
int i;
- pmd_phys = pgd_pgtable_alloc_init_mm_gfp(PGTABLE_LEVEL_PMD, gfp);
+ pmd_phys = pgd_pgtable_alloc_gfp(gfp);
if (pmd_phys == INVALID_PHYS_ADDR)
return -ENOMEM;
pmdp = (pmd_t *)phys_to_virt(pmd_phys);
@@ -1035,7 +1000,7 @@ void __init create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
early_create_pgd_mapping(mm->pgd, phys, virt, size, prot,
- pgd_pgtable_alloc_special_mm, flags);
+ pgd_pgtable_alloc, flags);
}
static void update_mapping_prot(phys_addr_t phys, unsigned long virt,
@@ -1249,7 +1214,7 @@ static void __init declare_vma(struct vm_struct *vma,
static phys_addr_t kpti_ng_temp_alloc __initdata;
-static phys_addr_t __init kpti_ng_pgd_alloc(enum pgtable_level pgtable_level)
+static phys_addr_t __init kpti_ng_pgd_alloc(void)
{
kpti_ng_temp_alloc -= PAGE_SIZE;
return kpti_ng_temp_alloc;
@@ -1357,7 +1322,7 @@ static int __init map_entry_trampoline(void)
memset(tramp_pg_dir, 0, PGD_SIZE);
early_create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS,
entry_tramp_text_size(), prot,
- pgd_pgtable_alloc_init_mm, NO_BLOCK_MAPPINGS);
+ pgd_pgtable_alloc, NO_BLOCK_MAPPINGS);
/* Map both the text and data into the kernel page table */
for (i = 0; i < DIV_ROUND_UP(entry_tramp_text_size(), PAGE_SIZE); i++)
@@ -1445,7 +1410,6 @@ static void free_hotplug_page_range(struct page *page, size_t size,
static void free_hotplug_pgtable_page(struct page *page)
{
- pagetable_dtor(page_ptdesc(page));
free_hotplug_page_range(page, PAGE_SIZE, NULL);
}
@@ -1958,7 +1922,7 @@ int arch_add_memory(int nid, u64 start, u64 size,
flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
ret = __create_pgd_mapping(swapper_pg_dir, start, __phys_to_virt(start),
- size, params->pgprot, pgd_pgtable_alloc_init_mm,
+ size, params->pgprot, pgd_pgtable_alloc,
flags);
if (ret)
goto err;
--
2.51.2
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 21/22] arm: mm: drop ctor call for kernel page tables
2026-07-14 14:03 ` Kevin Brodsky
@ 2026-07-14 14:04 ` Kevin Brodsky
-1 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:04 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
Thanks to recent changes:
* pagetable_pte_ctor() does nothing for kernel page tables.
* efi_mm is also treated like a kernel mm by the page table logic,
including ctors.
We can therefore drop the ctor call when allocating special kernel
page tables in mmu.c.
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/arm/mm/mmu.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 23b87b5ef7f1..c8de77a6f01e 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -728,8 +728,7 @@ static void *__init late_alloc(unsigned long sz)
void *ptdesc = pagetable_alloc(GFP_PGTABLE_KERNEL & ~__GFP_HIGHMEM,
get_order(sz));
- if (!ptdesc || !pagetable_pte_ctor(NULL, ptdesc))
- BUG();
+ BUG_ON(!ptdesc);
return ptdesc_address(ptdesc);
}
--
2.51.2
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 21/22] arm: mm: drop ctor call for kernel page tables
@ 2026-07-14 14:04 ` Kevin Brodsky
0 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:04 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
Thanks to recent changes:
* pagetable_pte_ctor() does nothing for kernel page tables.
* efi_mm is also treated like a kernel mm by the page table logic,
including ctors.
We can therefore drop the ctor call when allocating special kernel
page tables in mmu.c.
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/arm/mm/mmu.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 23b87b5ef7f1..c8de77a6f01e 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -728,8 +728,7 @@ static void *__init late_alloc(unsigned long sz)
void *ptdesc = pagetable_alloc(GFP_PGTABLE_KERNEL & ~__GFP_HIGHMEM,
get_order(sz));
- if (!ptdesc || !pagetable_pte_ctor(NULL, ptdesc))
- BUG();
+ BUG_ON(!ptdesc);
return ptdesc_address(ptdesc);
}
--
2.51.2
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 22/22] riscv: mm: drop ctor/dtor calls for kernel page tables
2026-07-14 14:03 ` Kevin Brodsky
@ 2026-07-14 14:04 ` Kevin Brodsky
-1 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:04 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
Thanks to recent changes:
* pagetable_*_ctor() and pagetable_dtor() do nothing for kernel page
tables.
* efi_mm is also treated like a kernel mm by the page table logic,
including ctors.
We can therefore drop the calls to ctors when allocating special
kernel page tables in mmu.c, as well as the dtor call when freeing
hotplug page tables.
The alloc_*_late() helpers are all identical after removing the ctor
calls, so replace them with alloc_pgtable_late().
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/riscv/mm/init.c | 63 ++++++++++++----------------------------------------
1 file changed, 14 insertions(+), 49 deletions(-)
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 5b1b3c88b4d1..e823662be256 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -382,6 +382,14 @@ void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot)
local_flush_tlb_page(addr);
}
+static phys_addr_t __meminit alloc_pgtable_late(uintptr_t va)
+{
+ struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL, 0);
+
+ BUG_ON(!ptdesc);
+ return __pa(ptdesc_address(ptdesc));
+}
+
static inline pte_t *__init get_pte_virt_early(phys_addr_t pa)
{
return (pte_t *)((uintptr_t)pa);
@@ -412,19 +420,6 @@ static inline phys_addr_t __init alloc_pte_fixmap(uintptr_t va)
return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE);
}
-static phys_addr_t __meminit alloc_pte_late(uintptr_t va)
-{
- struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL, 0);
-
- /*
- * We do not know which mm the PTE page is associated to at this point.
- * Passing NULL to the ctor is the safe option, though it may result
- * in unnecessary work (e.g. initialising the ptlock for init_mm).
- */
- BUG_ON(!ptdesc || !pagetable_pte_ctor(NULL, ptdesc));
- return __pa((pte_t *)ptdesc_address(ptdesc));
-}
-
static void __meminit create_pte_mapping(pte_t *ptep, uintptr_t va, phys_addr_t pa, phys_addr_t sz,
pgprot_t prot)
{
@@ -479,15 +474,6 @@ static phys_addr_t __init alloc_pmd_fixmap(uintptr_t va)
return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE);
}
-static phys_addr_t __meminit alloc_pmd_late(uintptr_t va)
-{
- struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL, 0);
-
- /* See comment in alloc_pte_late() regarding NULL passed the ctor */
- BUG_ON(!ptdesc || !pagetable_pmd_ctor(NULL, ptdesc));
- return __pa((pmd_t *)ptdesc_address(ptdesc));
-}
-
static void __meminit create_pmd_mapping(pmd_t *pmdp,
uintptr_t va, phys_addr_t pa,
phys_addr_t sz, pgprot_t prot)
@@ -544,15 +530,6 @@ static phys_addr_t __init alloc_pud_fixmap(uintptr_t va)
return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE);
}
-static phys_addr_t __meminit alloc_pud_late(uintptr_t va)
-{
- struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL, 0);
-
- BUG_ON(!ptdesc);
- pagetable_pud_ctor(ptdesc);
- return __pa((pud_t *)ptdesc_address(ptdesc));
-}
-
static p4d_t *__init get_p4d_virt_early(phys_addr_t pa)
{
return (p4d_t *)((uintptr_t)pa);
@@ -582,15 +559,6 @@ static phys_addr_t __init alloc_p4d_fixmap(uintptr_t va)
return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE);
}
-static phys_addr_t __meminit alloc_p4d_late(uintptr_t va)
-{
- struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL, 0);
-
- BUG_ON(!ptdesc);
- pagetable_p4d_ctor(ptdesc);
- return __pa((p4d_t *)ptdesc_address(ptdesc));
-}
-
static void __meminit create_pud_mapping(pud_t *pudp, uintptr_t va, phys_addr_t pa, phys_addr_t sz,
pgprot_t prot)
{
@@ -1003,14 +971,14 @@ static void __init pt_ops_set_fixmap(void)
*/
static void __init pt_ops_set_late(void)
{
- pt_ops.alloc_pte = alloc_pte_late;
+ pt_ops.alloc_pte = alloc_pgtable_late;
pt_ops.get_pte_virt = get_pte_virt_late;
#ifndef __PAGETABLE_PMD_FOLDED
- pt_ops.alloc_pmd = alloc_pmd_late;
+ pt_ops.alloc_pmd = alloc_pgtable_late;
pt_ops.get_pmd_virt = get_pmd_virt_late;
- pt_ops.alloc_pud = alloc_pud_late;
+ pt_ops.alloc_pud = alloc_pgtable_late;
pt_ops.get_pud_virt = get_pud_virt_late;
- pt_ops.alloc_p4d = alloc_p4d_late;
+ pt_ops.alloc_p4d = alloc_pgtable_late;
pt_ops.get_p4d_virt = get_p4d_virt_late;
#endif
}
@@ -1488,7 +1456,6 @@ static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd)
return;
}
- pagetable_dtor(ptdesc);
if (PageReserved(page))
free_reserved_page(page);
else
@@ -1496,7 +1463,7 @@ static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd)
pmd_clear(pmd);
}
-static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud, bool is_vmemmap)
+static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud)
{
struct page *page = pud_page(*pud);
struct ptdesc *ptdesc = page_ptdesc(page);
@@ -1509,8 +1476,6 @@ static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud, bool is_vmemm
return;
}
- if (!is_vmemmap)
- pagetable_dtor(ptdesc);
if (PageReserved(page))
free_reserved_page(page);
else
@@ -1634,7 +1599,7 @@ static void __meminit remove_pud_mapping(pud_t *pud_base, unsigned long addr, un
remove_pmd_mapping(pmd_base, addr, next, is_vmemmap, altmap);
if (pgtable_l4_enabled)
- free_pmd_table(pmd_base, pudp, is_vmemmap);
+ free_pmd_table(pmd_base, pudp);
}
}
--
2.51.2
^ permalink raw reply related [flat|nested] 62+ messages in thread
* [PATCH 22/22] riscv: mm: drop ctor/dtor calls for kernel page tables
@ 2026-07-14 14:04 ` Kevin Brodsky
0 siblings, 0 replies; 62+ messages in thread
From: Kevin Brodsky @ 2026-07-14 14:04 UTC (permalink / raw)
To: linux-mm
Cc: Kevin Brodsky, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
Thanks to recent changes:
* pagetable_*_ctor() and pagetable_dtor() do nothing for kernel page
tables.
* efi_mm is also treated like a kernel mm by the page table logic,
including ctors.
We can therefore drop the calls to ctors when allocating special
kernel page tables in mmu.c, as well as the dtor call when freeing
hotplug page tables.
The alloc_*_late() helpers are all identical after removing the ctor
calls, so replace them with alloc_pgtable_late().
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
arch/riscv/mm/init.c | 63 ++++++++++++----------------------------------------
1 file changed, 14 insertions(+), 49 deletions(-)
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 5b1b3c88b4d1..e823662be256 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -382,6 +382,14 @@ void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot)
local_flush_tlb_page(addr);
}
+static phys_addr_t __meminit alloc_pgtable_late(uintptr_t va)
+{
+ struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL, 0);
+
+ BUG_ON(!ptdesc);
+ return __pa(ptdesc_address(ptdesc));
+}
+
static inline pte_t *__init get_pte_virt_early(phys_addr_t pa)
{
return (pte_t *)((uintptr_t)pa);
@@ -412,19 +420,6 @@ static inline phys_addr_t __init alloc_pte_fixmap(uintptr_t va)
return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE);
}
-static phys_addr_t __meminit alloc_pte_late(uintptr_t va)
-{
- struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL, 0);
-
- /*
- * We do not know which mm the PTE page is associated to at this point.
- * Passing NULL to the ctor is the safe option, though it may result
- * in unnecessary work (e.g. initialising the ptlock for init_mm).
- */
- BUG_ON(!ptdesc || !pagetable_pte_ctor(NULL, ptdesc));
- return __pa((pte_t *)ptdesc_address(ptdesc));
-}
-
static void __meminit create_pte_mapping(pte_t *ptep, uintptr_t va, phys_addr_t pa, phys_addr_t sz,
pgprot_t prot)
{
@@ -479,15 +474,6 @@ static phys_addr_t __init alloc_pmd_fixmap(uintptr_t va)
return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE);
}
-static phys_addr_t __meminit alloc_pmd_late(uintptr_t va)
-{
- struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL, 0);
-
- /* See comment in alloc_pte_late() regarding NULL passed the ctor */
- BUG_ON(!ptdesc || !pagetable_pmd_ctor(NULL, ptdesc));
- return __pa((pmd_t *)ptdesc_address(ptdesc));
-}
-
static void __meminit create_pmd_mapping(pmd_t *pmdp,
uintptr_t va, phys_addr_t pa,
phys_addr_t sz, pgprot_t prot)
@@ -544,15 +530,6 @@ static phys_addr_t __init alloc_pud_fixmap(uintptr_t va)
return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE);
}
-static phys_addr_t __meminit alloc_pud_late(uintptr_t va)
-{
- struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL, 0);
-
- BUG_ON(!ptdesc);
- pagetable_pud_ctor(ptdesc);
- return __pa((pud_t *)ptdesc_address(ptdesc));
-}
-
static p4d_t *__init get_p4d_virt_early(phys_addr_t pa)
{
return (p4d_t *)((uintptr_t)pa);
@@ -582,15 +559,6 @@ static phys_addr_t __init alloc_p4d_fixmap(uintptr_t va)
return memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE);
}
-static phys_addr_t __meminit alloc_p4d_late(uintptr_t va)
-{
- struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL, 0);
-
- BUG_ON(!ptdesc);
- pagetable_p4d_ctor(ptdesc);
- return __pa((p4d_t *)ptdesc_address(ptdesc));
-}
-
static void __meminit create_pud_mapping(pud_t *pudp, uintptr_t va, phys_addr_t pa, phys_addr_t sz,
pgprot_t prot)
{
@@ -1003,14 +971,14 @@ static void __init pt_ops_set_fixmap(void)
*/
static void __init pt_ops_set_late(void)
{
- pt_ops.alloc_pte = alloc_pte_late;
+ pt_ops.alloc_pte = alloc_pgtable_late;
pt_ops.get_pte_virt = get_pte_virt_late;
#ifndef __PAGETABLE_PMD_FOLDED
- pt_ops.alloc_pmd = alloc_pmd_late;
+ pt_ops.alloc_pmd = alloc_pgtable_late;
pt_ops.get_pmd_virt = get_pmd_virt_late;
- pt_ops.alloc_pud = alloc_pud_late;
+ pt_ops.alloc_pud = alloc_pgtable_late;
pt_ops.get_pud_virt = get_pud_virt_late;
- pt_ops.alloc_p4d = alloc_p4d_late;
+ pt_ops.alloc_p4d = alloc_pgtable_late;
pt_ops.get_p4d_virt = get_p4d_virt_late;
#endif
}
@@ -1488,7 +1456,6 @@ static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd)
return;
}
- pagetable_dtor(ptdesc);
if (PageReserved(page))
free_reserved_page(page);
else
@@ -1496,7 +1463,7 @@ static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd)
pmd_clear(pmd);
}
-static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud, bool is_vmemmap)
+static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud)
{
struct page *page = pud_page(*pud);
struct ptdesc *ptdesc = page_ptdesc(page);
@@ -1509,8 +1476,6 @@ static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud, bool is_vmemm
return;
}
- if (!is_vmemmap)
- pagetable_dtor(ptdesc);
if (PageReserved(page))
free_reserved_page(page);
else
@@ -1634,7 +1599,7 @@ static void __meminit remove_pud_mapping(pud_t *pud_base, unsigned long addr, un
remove_pmd_mapping(pmd_base, addr, next, is_vmemmap, altmap);
if (pgtable_l4_enabled)
- free_pmd_table(pmd_base, pudp, is_vmemmap);
+ free_pmd_table(pmd_base, pudp);
}
}
--
2.51.2
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [PATCH 04/22] mm: use mm_is_kernel() in generic page table code
2026-07-14 14:03 ` Kevin Brodsky
(?)
@ 2026-07-14 14:28 ` sashiko-bot
-1 siblings, 0 replies; 62+ messages in thread
From: sashiko-bot @ 2026-07-14 14:28 UTC (permalink / raw)
To: Kevin Brodsky
Cc: linux-s390, Vasily Gorbik, Alexander Gordeev, Heiko Carstens
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] apply_to_pte_range() routes all kernel MMs to pte_alloc_kernel_track(), which explicitly hardcodes &init_mm, leading to incorrect locking and mm attribution.
--
--- Patch [4]: [PATCH 04/22] mm: use mm_is_kernel() in generic page table code ---
commit 94fec0def7956a4362140e84c87769a3c5a046b2
Author: Kevin Brodsky <kevin.brodsky@arm.com>
mm: use mm_is_kernel() in generic page table code
Generic page-table allocation, constructor and walker code uses
init_mm comparisons to select kernel page table handling. Use
mm_is_kernel() instead so kernel-owned mm's can share that handling
once they are marked with MMF_KERNEL.
> diff --git a/mm/memory.c b/mm/memory.c
> index d5e87624f6920..c0244c0b07567 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
[ ... ]
> @@ -3394,13 +3394,13 @@ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
> spinlock_t *ptl;
>
> if (create) {
> - mapped_pte = pte = (mm == &init_mm) ?
> + mapped_pte = pte = mm_is_kernel(mm) ?
> pte_alloc_kernel_track(pmd, addr, mask) :
[Severity: Medium]
If a non-init_mm kernel MM (like efi_mm) has MMF_KERNEL set in the future,
will this route it to pte_alloc_kernel_track() which hardcodes init_mm?
Looking at __pte_alloc_kernel() in mm/memory.c, which
pte_alloc_kernel_track() calls:
int __pte_alloc_kernel(pmd_t *pmd)
{
pte_t *new = pte_alloc_one_kernel(&init_mm);
if (!new)
return -ENOMEM;
spin_lock(&init_mm.page_table_lock);
...
Since __pte_alloc_kernel() drops the mm context and explicitly locks
init_mm.page_table_lock instead of the target MM's lock, would this
lead to data races during concurrent page table modifications for other
kernel MMs?
> pte_alloc_map_lock(mm, pmd, addr, &ptl);
> if (!pte)
> return -ENOMEM;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260714-remove_pgtable_cdtor-v1-0-44be8a7685d7@arm.com?part=4
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 17/22] mm: pagewalk: drop redundant address check for kernel mm walks
2026-07-14 14:04 ` Kevin Brodsky
(?)
@ 2026-07-14 14:42 ` sashiko-bot
-1 siblings, 0 replies; 62+ messages in thread
From: sashiko-bot @ 2026-07-14 14:42 UTC (permalink / raw)
To: Kevin Brodsky
Cc: linux-s390, Heiko Carstens, Vasily Gorbik, Alexander Gordeev
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Removing the `addr >= TASK_SIZE` check in `walk_pte_range()` causes `ptdump` to clear valid kernel PMDs, leading to memory corruption and a kernel panic.
--
--- Patch [17]: [PATCH 17/22] mm: pagewalk: drop redundant address check for kernel mm walks ---
commit 85b512e55cb35ec57a18d00b67fbf62a68320627
Author: Kevin Brodsky <kevin.brodsky@arm.com>
mm: pagewalk: drop redundant address check for kernel mm walks
This commit removes the addr >= TASK_SIZE check from walk_pte_range() for
no-VMA walks. It relies entirely on mm_is_kernel() to determine whether
to use pte_offset_kernel() or pte_offset_map().
> diff --git a/mm/pagewalk.c b/mm/pagewalk.c
> index a3f47d1de3c5a..0dd9d4ad9b689 100644
> --- a/mm/pagewalk.c
> +++ b/mm/pagewalk.c
> @@ -68,17 +68,14 @@ static int walk_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
> if (walk->no_vma) {
> /*
> * pte_offset_map() might apply user-specific validation.
> - * Indeed, on x86_64 the pmd entries set up by init_espfix_ap()
> - * fit its pmd_bad() check (_PAGE_NX set and _PAGE_RW clear),
> - * and CONFIG_EFI_PGT_DUMP efi_mm goes so far as to walk them.
> */
> - if (mm_is_kernel(walk->mm) || addr >= TASK_SIZE)
> + if (mm_is_kernel(walk->mm))
> pte = pte_offset_kernel(pmd, addr);
> else
> pte = pte_offset_map(pmd, addr);
[Severity: High]
Does removing the addr >= TASK_SIZE check here cause ptdump to clear valid
kernel PMDs?
When tools like ptdump walk the address space (e.g. via
/sys/kernel/debug/page_tables/current_kernel), they may walk kernel addresses
using current->mm, which is a user mm. In this case, mm_is_kernel() returns
false, causing walk_pte_range() to use pte_offset_map() for kernel addresses.
On x86, pte_offset_map() eventually calls __pte_offset_map(), which validates
the PMD using pmd_bad(). If a kernel PMD (such as the espfix mapping) fails
this check because it intentionally lacks _PAGE_RW and sets _PAGE_NX,
__pte_offset_map() unconditionally clears it via pmd_clear_bad().
Since kernel page tables are shared via init_mm, clearing the PMD permanently
destroys the global espfix mapping. The next IRET to a 16-bit userspace
segment would then encounter a missing page table, triggering a Double Fault
kernel panic.
Should we keep the addr >= TASK_SIZE check to ensure kernel addresses always
use pte_offset_kernel(), even when walked via a user mm?
> if (pte) {
> err = walk_pte_range_inner(pte, addr, end, walk);
> - if (!mm_is_kernel(walk->mm) && addr < TASK_SIZE)
> + if (!mm_is_kernel(walk->mm))
> pte_unmap(pte);
> }
> } else {
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260714-remove_pgtable_cdtor-v1-0-44be8a7685d7@arm.com?part=17
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 03/22] mm: introduce MMF_KERNEL flag and set it for init_mm
2026-07-14 14:03 ` Kevin Brodsky
@ 2026-07-14 14:47 ` Dave Hansen
-1 siblings, 0 replies; 62+ messages in thread
From: Dave Hansen @ 2026-07-14 14:47 UTC (permalink / raw)
To: Kevin Brodsky, linux-mm
Cc: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
On 7/14/26 07:03, Kevin Brodsky wrote:
> +static inline bool mm_is_kernel(const struct mm_struct *mm)
> +{
> + return mm && mm_flags_test(MMF_KERNEL, mm);
> +}
Could we give this some nice comments explaining what a kernel mm is,
please? Part of the problem with the init_mm checks is that they're
magic and it's not always clear what's special about init_mm.
Maybe start with this list?
1. There's only one of them.
2. All kernel threads share it. tsk->mm is the same for all kernel
threads.
3. It holds the reference copy of the kernel page tables
4. Userspace can't be entered when it is the current mm
5. It has different TLB flushing rules than userspace mms
I _think_ those are universal across all architectures.
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 03/22] mm: introduce MMF_KERNEL flag and set it for init_mm
@ 2026-07-14 14:47 ` Dave Hansen
0 siblings, 0 replies; 62+ messages in thread
From: Dave Hansen @ 2026-07-14 14:47 UTC (permalink / raw)
To: Kevin Brodsky, linux-mm
Cc: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
On 7/14/26 07:03, Kevin Brodsky wrote:
> +static inline bool mm_is_kernel(const struct mm_struct *mm)
> +{
> + return mm && mm_flags_test(MMF_KERNEL, mm);
> +}
Could we give this some nice comments explaining what a kernel mm is,
please? Part of the problem with the init_mm checks is that they're
magic and it's not always clear what's special about init_mm.
Maybe start with this list?
1. There's only one of them.
2. All kernel threads share it. tsk->mm is the same for all kernel
threads.
3. It holds the reference copy of the kernel page tables
4. Userspace can't be entered when it is the current mm
5. It has different TLB flushing rules than userspace mms
I _think_ those are universal across all architectures.
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 14/22] mm: set page table page type when allocated
2026-07-14 14:04 ` Kevin Brodsky
(?)
@ 2026-07-14 14:54 ` sashiko-bot
-1 siblings, 0 replies; 62+ messages in thread
From: sashiko-bot @ 2026-07-14 14:54 UTC (permalink / raw)
To: Kevin Brodsky
Cc: Heiko Carstens, Alexander Gordeev, linux-s390, Vasily Gorbik
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] Missing PG_table page type initialization for custom allocators that bypass pagetable_alloc_noprof().
- [Medium] Bypassing pagetable_free() causes leaked PG_table state and permanent NR_PAGETABLE accounting leaks.
--
--- Patch [14]: [PATCH 14/22] mm: set page table page type when allocated ---
commit ec9e373da7e406797591704d23e05fdbf402dfe3
Author: Kevin Brodsky <kevin.brodsky@arm.com>
mm: set page table page type when allocated
This commit moves page table page type updates from the constructors and
destructors directly into pagetable_alloc_noprof() and __pagetable_free().
It leaves __pagetable_ctor() empty and removes it.
Link: https://lore.kernel.org/r/20251113140448.1814860-4-willy@infradead.org
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 361a0d7b74c51..94f0fb1c662ae 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
[ ... ]
> @@ -3799,19 +3801,9 @@ static inline bool ptlock_init(struct ptdesc *ptdesc) { return true; }
> static inline void ptlock_free(struct ptdesc *ptdesc) {}
> #endif /* defined(CONFIG_SPLIT_PTE_PTLOCKS) */
>
> -static inline void __pagetable_ctor(struct ptdesc *ptdesc)
> -{
> - struct folio *folio = ptdesc_folio(ptdesc);
> -
> - __folio_set_pgtable(folio);
> -}
> -
> static inline void pagetable_dtor(struct ptdesc *ptdesc)
> {
> - struct folio *folio = ptdesc_folio(ptdesc);
> -
> ptlock_free(ptdesc);
> - __folio_clear_pgtable(folio);
> }
[Severity: Medium]
Since __folio_clear_pgtable() was moved to __pagetable_free(), what happens to
architectures that bypass __pagetable_free() entirely?
For example, without CONFIG_MMU_GATHER_TABLE_FREE, tlb_remove_table() calls
pagetable_dtor() and frees the page directly via the batcher:
include/asm-generic/tlb.h:tlb_remove_table() {
...
pagetable_dtor(ptdesc);
tlb_remove_page(tlb, ptdesc_page(ptdesc));
}
Similarly, arm64 memory hot-remove frees pages directly:
arch/arm64/mm/mmu.c:free_hotplug_pgtable_page() {
pagetable_dtor(page_ptdesc(page));
free_hotplug_page_range(page, PAGE_SIZE, NULL);
}
Will this bypass cause a permanent leak in the NR_PAGETABLE counter and leave
the PG_table flag set on the page as it enters the buddy allocator?
> static inline void pagetable_dtor_free(struct ptdesc *ptdesc)
> @@ -3825,7 +3817,6 @@ static inline bool pagetable_pte_ctor(struct mm_struct *mm,
> {
> if (!mm_is_kernel(mm) && !ptlock_init(ptdesc))
> return false;
> - __pagetable_ctor(ptdesc);
> return true;
> }
[Severity: Medium]
Are there custom allocators that rely on pagetable_pte_ctor() to initialize
the page type?
For instance, on SPARC32, user PTE tables are allocated via a custom pool
using srmmu_get_nocache() which bypasses pagetable_alloc_noprof(). They
rely on pagetable_pte_ctor() to set the page type:
arch/sparc/mm/srmmu.c:pte_alloc_one() {
...
if (page_ref_inc_return(page) == 2 &&
!pagetable_pte_ctor(mm, page_ptdesc(page))) {
...
}
By removing __pagetable_ctor() here, it seems these pages will no longer
have the PG_table flag set. Is this the intended behavior?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260714-remove_pgtable_cdtor-v1-0-44be8a7685d7@arm.com?part=14
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 13/22] mm: account page table pages when allocated
2026-07-14 14:04 ` Kevin Brodsky
(?)
@ 2026-07-14 14:54 ` sashiko-bot
-1 siblings, 0 replies; 62+ messages in thread
From: sashiko-bot @ 2026-07-14 14:54 UTC (permalink / raw)
To: Kevin Brodsky
Cc: Vasily Gorbik, Heiko Carstens, linux-s390, Alexander Gordeev
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [Medium] NR_PAGETABLE statistic leak on architectures that do not define CONFIG_MMU_GATHER_TABLE_FREE.
- [Medium] Direct calls to pagetable_dtor() followed by generic page freeing functions bypass the NR_PAGETABLE decrement, causing stat leaks on ARM64 memory hot-remove.
- [Medium] SPARC32 SRMMU page tables completely lose NR_PAGETABLE accounting.
- [Medium] Memory hot-remove and vmemmap teardown on x86 will underflow the NR_PAGETABLE counter.
--
--- Patch [13]: [PATCH 13/22] mm: account page table pages when allocated ---
commit 5c303720c0cd77f50e7b180d025a9a9869aab6a2
Author: Kevin Brodsky <kevin.brodsky@arm.com>
mm: account page table pages when allocated
This commit moves memory accounting of pagetable pages from the ctor/dtor
functions to pagetable_alloc() and pagetable_free() in order to improve
accounting where ctor/dtor calls might be missing.
Link: https://lore.kernel.org/r/20251113140448.1814860-3-willy@infradead.org
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index b336eb32faa05..361a0d7b74c51 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -3681,6 +3681,11 @@ static inline struct ptdesc *pagetable_alloc_noprof(gfp_t gfp, unsigned int orde
> {
> struct page *page = alloc_pages_noprof(gfp | __GFP_COMP, order);
>
> + if (!page)
> + return NULL;
> +
> + lruvec_stat_add_folio(page_folio(page), NR_PAGETABLE);
> +
> return page_ptdesc(page);
> }
[Severity: Medium]
For architectures or code paths that allocate page tables without using
pagetable_alloc_noprof(), will we now lose the NR_PAGETABLE accounting?
For example, on SPARC32, pte_alloc_one() in arch/sparc/mm/srmmu.c allocates
from a pre-allocated pool via srmmu_get_nocache() and previously relied on
pagetable_pte_ctor() to increment the stat:
arch/sparc/mm/srmmu.c:pte_alloc_one() {
...
if (page_ref_inc_return(page) == 2 &&
!pagetable_pte_ctor(mm, page_ptdesc(page))) {
...
}
Similarly, the freeing path mirrors this bypass, using srmmu_free_nocache()
instead of pagetable_free(). Does this change cause SPARC32 to completely
lose user PTE accounting?
> @@ -3689,6 +3694,8 @@ static inline void __pagetable_free(struct ptdesc *pt)
> {
> struct page *page = ptdesc_page(pt);
>
> + lruvec_stat_sub_folio(page_folio(page), NR_PAGETABLE);
> +
> __free_pages(page, compound_order(page));
> }
[Severity: Medium]
Will this cause an underflow on x86 during memory hot-remove?
In arch/x86/mm/init_64.c, free_pagetable() calls pagetable_free() (which
now decrements the stat) during hot-remove:
arch/x86/mm/init_64.c:free_pagetable() {
...
if (PageReserved(page))
free_reserved_page(page);
else
pagetable_free(page_ptdesc(page));
}
However, these kernel page tables were originally allocated during hot-add
with spp_getpage() or vmemmap_alloc_block_buf(). Both of these use base
allocators and bypass pagetable_alloc_noprof().
Because the stat is never incremented on allocation but is now decremented
on free, does this cause an underflow?
[ ... ]
> @@ -3797,7 +3804,6 @@ static inline void __pagetable_ctor(struct ptdesc *ptdesc)
> struct folio *folio = ptdesc_folio(ptdesc);
>
> __folio_set_pgtable(folio);
> - lruvec_stat_add_folio(folio, NR_PAGETABLE);
> }
>
> static inline void pagetable_dtor(struct ptdesc *ptdesc)
> @@ -3806,7 +3812,6 @@ static inline void pagetable_dtor(struct ptdesc *ptdesc)
>
> ptlock_free(ptdesc);
> __folio_clear_pgtable(folio);
> - lruvec_stat_sub_folio(folio, NR_PAGETABLE);
> }
[Severity: Medium]
Will this leak the NR_PAGETABLE counter on architectures that bypass
__pagetable_free() and only call pagetable_dtor()?
On architectures lacking CONFIG_MMU_GATHER_TABLE_FREE (like m68k or xtensa),
the fallback tlb_remove_table() implementation explicitly calls
pagetable_dtor() and then enqueues the page for generic batch freeing:
include/asm-generic/tlb.h:tlb_remove_table() {
struct ptdesc *ptdesc = (struct ptdesc *)table;
pagetable_dtor(ptdesc);
tlb_remove_page(tlb, ptdesc_page(ptdesc));
}
Since the decrement was moved from pagetable_dtor() to __pagetable_free(),
which is bypassed here, will this leak the counter when userspace unmaps
memory?
A similar bypass appears to occur on ARM64 during memory hot-remove:
arch/arm64/mm/mmu.c:free_hotplug_pgtable_page() {
pagetable_dtor(page_ptdesc(page));
free_hotplug_page_range(page, PAGE_SIZE, NULL);
}
Since this directly calls pagetable_dtor() and skips __pagetable_free(),
will this also leave the stat un-decremented?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260714-remove_pgtable_cdtor-v1-0-44be8a7685d7@arm.com?part=13
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 20/22] arm64: mm: drop ctor/dtor calls for kernel page tables
2026-07-14 14:04 ` Kevin Brodsky
(?)
@ 2026-07-14 14:56 ` sashiko-bot
-1 siblings, 0 replies; 62+ messages in thread
From: sashiko-bot @ 2026-07-14 14:56 UTC (permalink / raw)
To: Kevin Brodsky
Cc: Vasily Gorbik, linux-s390, Alexander Gordeev, Heiko Carstens
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Kernel page tables allocated during memory hotplug leak the NR_PAGETABLE stat and retain the PG_pgtable flag when freed, causing a buddy allocator BUG on reallocation.
--
--- Patch [20]: [PATCH 20/22] arm64: mm: drop ctor/dtor calls for kernel page tables ---
commit eb398eca88012b977463df47eaf81e1fcd66213d
Author: Kevin Brodsky <kevin.brodsky@arm.com>
arm64: mm: drop ctor/dtor calls for kernel page tables
This patch removes pagetable constructor and destructor calls for kernel
page tables, under the assumption that they no longer perform necessary work.
It also removes the pgtable level callback arguments from the early
allocation wrappers.
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index f723bcf68174f..f1400c6f68ba7 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
[ ... ]
> @@ -1445,7 +1410,6 @@ static void free_hotplug_page_range(struct page *page, size_t size,
>
> static void free_hotplug_pgtable_page(struct page *page)
> {
> - pagetable_dtor(page_ptdesc(page));
> free_hotplug_page_range(page, PAGE_SIZE, NULL);
> }
[Severity: High]
Does this cause the buddy allocator to reject the physical page and leak the
NR_PAGETABLE statistic during memory hot-remove?
By dropping the destructor call here, the PG_pgtable flag is no longer
cleared. Since free_hotplug_page_range() eventually calls __free_pages()
directly rather than using pagetable_free(), the required cleanup is entirely
skipped.
If the buddy allocator later reallocates this page, check_new_page_bad()
will detect the leftover PG_pgtable flag, trigger a bad_page() warning,
and permanently leak the page.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260714-remove_pgtable_cdtor-v1-0-44be8a7685d7@arm.com?part=20
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 03/22] mm: introduce MMF_KERNEL flag and set it for init_mm
2026-07-14 14:47 ` Dave Hansen
@ 2026-07-14 15:04 ` Lorenzo Stoakes (ARM)
-1 siblings, 0 replies; 62+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-07-14 15:04 UTC (permalink / raw)
To: Dave Hansen
Cc: Kevin Brodsky, linux-mm, Andrew Morton, David Hildenbrand,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
On Tue, Jul 14, 2026 at 07:47:43AM -0700, Dave Hansen wrote:
> On 7/14/26 07:03, Kevin Brodsky wrote:
> > +static inline bool mm_is_kernel(const struct mm_struct *mm)
> > +{
> > + return mm && mm_flags_test(MMF_KERNEL, mm);
> > +}
>
> Could we give this some nice comments explaining what a kernel mm is,
> please? Part of the problem with the init_mm checks is that they're
> magic and it's not always clear what's special about init_mm.
>
> Maybe start with this list?
>
> 1. There's only one of them.
> 2. All kernel threads share it. tsk->mm is the same for all kernel
> threads.
> 3. It holds the reference copy of the kernel page tables
> 4. Userspace can't be entered when it is the current mm
> 5. It has different TLB flushing rules than userspace mms
>
> I _think_ those are universal across all architectures.
Well point 1 isn't true of efimm or tboot_mm so we possibly need a better
name :)
"Special" is overloaded too much already. I quite like "eternal" so:
static inline bool mm_is_eternal(const struct mm_struct *mm)
{
return mm && mm_flags_test(MMF_ETERNAL, mm);
}
:)
Cheers, Lorenzo
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 03/22] mm: introduce MMF_KERNEL flag and set it for init_mm
@ 2026-07-14 15:04 ` Lorenzo Stoakes (ARM)
0 siblings, 0 replies; 62+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-07-14 15:04 UTC (permalink / raw)
To: Dave Hansen
Cc: Kevin Brodsky, linux-mm, Andrew Morton, David Hildenbrand,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
On Tue, Jul 14, 2026 at 07:47:43AM -0700, Dave Hansen wrote:
> On 7/14/26 07:03, Kevin Brodsky wrote:
> > +static inline bool mm_is_kernel(const struct mm_struct *mm)
> > +{
> > + return mm && mm_flags_test(MMF_KERNEL, mm);
> > +}
>
> Could we give this some nice comments explaining what a kernel mm is,
> please? Part of the problem with the init_mm checks is that they're
> magic and it's not always clear what's special about init_mm.
>
> Maybe start with this list?
>
> 1. There's only one of them.
> 2. All kernel threads share it. tsk->mm is the same for all kernel
> threads.
> 3. It holds the reference copy of the kernel page tables
> 4. Userspace can't be entered when it is the current mm
> 5. It has different TLB flushing rules than userspace mms
>
> I _think_ those are universal across all architectures.
Well point 1 isn't true of efimm or tboot_mm so we possibly need a better
name :)
"Special" is overloaded too much already. I quite like "eternal" so:
static inline bool mm_is_eternal(const struct mm_struct *mm)
{
return mm && mm_flags_test(MMF_ETERNAL, mm);
}
:)
Cheers, Lorenzo
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 12/22] x86/mm: use mm_is_kernel() for kernel mm checks
2026-07-14 14:04 ` Kevin Brodsky
@ 2026-07-14 15:09 ` Dave Hansen
-1 siblings, 0 replies; 62+ messages in thread
From: Dave Hansen @ 2026-07-14 15:09 UTC (permalink / raw)
To: Kevin Brodsky, linux-mm
Cc: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
On 7/14/26 07:04, Kevin Brodsky wrote:
...
> @@ -188,7 +188,7 @@ DECLARE_PER_CPU_SHARED_ALIGNED(struct tlb_state_shared, cpu_tlbstate_shared);
> #define enter_lazy_tlb enter_lazy_tlb
> static __always_inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
> {
> - if (this_cpu_read(cpu_tlbstate.loaded_mm) == &init_mm)
> + if (mm_is_kernel(this_cpu_read(cpu_tlbstate.loaded_mm)))
> return;
>
> this_cpu_write(cpu_tlbstate_shared.is_lazy, true);
This one makes me nervous, especially combined with the efi_mm changes
later in the series. init_mm really is special. Before this patch,
running on init_mm qualifies as being in lazy tlb mode. After this
patch, efi_mm qualifies too.
Is that OK?
> diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
> index f32facdb3035..91d2a6f2ac5a 100644
> --- a/arch/x86/mm/pgtable.c
> +++ b/arch/x86/mm/pgtable.c
> @@ -168,7 +168,7 @@ static int preallocate_pmds(struct mm_struct *mm, pmd_t *pmds[], int count)
> bool failed = false;
> gfp_t gfp = GFP_PGTABLE_USER;
>
> - if (mm == &init_mm)
> + if (mm_is_kernel(mm))
> gfp &= ~__GFP_ACCOUNT;
> gfp &= ~__GFP_HIGHMEM;
This hunk is probably fine.
> diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
> index 1023acadd8f8..5517cab8ad00 100644
> --- a/arch/x86/mm/tlb.c
> +++ b/arch/x86/mm/tlb.c
> @@ -594,7 +594,7 @@ void leave_mm(void)
> * This needs to happen before any other sanity checks due to
> * intel_idle's shenanigans.
> */
> - if (loaded_mm == &init_mm)
> + if (mm_is_kernel(loaded_mm))
> return;
This one is almost *certainly* buggy.
The efi_mm stuff uses leave_mm(). In fact, I think it's what's
responsible for switching the hardware back over to use the init_mm page
tables. If this check trips for init_mm, then the kernel will stay
running on efi_mm when it's not intended to.
Remember when I asked about whether there was going to be *a* kernel mm
or lots? This is where it starts to matter. It's outside the diff
context but the code here is basically:
if (loaded_mm == &init_mm)
return;
switch_mm(NULL, &init_mm, NULL);
So either all kernel mm's are equivalent or this code doesn't quite work.
> /* Warn if we're not lazy. */
> @@ -855,7 +855,7 @@ void switch_mm_irqs_off(struct mm_struct *unused, struct mm_struct *next,
> * cpu_tlbstate_shared.is_lazy whether or not to send an IPI.
> */
> if (IS_ENABLED(CONFIG_DEBUG_VM) &&
> - WARN_ON_ONCE(prev != &init_mm && !is_notrack_mm(prev) &&
> + WARN_ON_ONCE(!mm_is_kernel(prev) && !is_notrack_mm(prev) &&
> !cpumask_test_cpu(cpu, mm_cpumask(next))))
> cpumask_set_cpu(cpu, mm_cpumask(next));
>
> @@ -932,7 +932,8 @@ void switch_mm_irqs_off(struct mm_struct *unused, struct mm_struct *next,
> * This way switch_mm() must see the new tlb_gen or
> * flush_tlb_mm_range() must see the new loaded_mm, or both.
> */
> - if (next != &init_mm && !cpumask_test_cpu(cpu, mm_cpumask(next)))
> + if (!mm_is_kernel(next) &&
> + !cpumask_test_cpu(cpu, mm_cpumask(next)))
> cpumask_set_cpu(cpu, mm_cpumask(next));
> else
> smp_mb();
This one is interesting. It's basically saying that init_mm doesn't get
mm_cpumask() updates. That makes sense since it has special TLB flushing
rules. But what does this mean for efi_mm? Does it needs mm_cpumask()
updates?
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 12/22] x86/mm: use mm_is_kernel() for kernel mm checks
@ 2026-07-14 15:09 ` Dave Hansen
0 siblings, 0 replies; 62+ messages in thread
From: Dave Hansen @ 2026-07-14 15:09 UTC (permalink / raw)
To: Kevin Brodsky, linux-mm
Cc: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
On 7/14/26 07:04, Kevin Brodsky wrote:
...
> @@ -188,7 +188,7 @@ DECLARE_PER_CPU_SHARED_ALIGNED(struct tlb_state_shared, cpu_tlbstate_shared);
> #define enter_lazy_tlb enter_lazy_tlb
> static __always_inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
> {
> - if (this_cpu_read(cpu_tlbstate.loaded_mm) == &init_mm)
> + if (mm_is_kernel(this_cpu_read(cpu_tlbstate.loaded_mm)))
> return;
>
> this_cpu_write(cpu_tlbstate_shared.is_lazy, true);
This one makes me nervous, especially combined with the efi_mm changes
later in the series. init_mm really is special. Before this patch,
running on init_mm qualifies as being in lazy tlb mode. After this
patch, efi_mm qualifies too.
Is that OK?
> diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
> index f32facdb3035..91d2a6f2ac5a 100644
> --- a/arch/x86/mm/pgtable.c
> +++ b/arch/x86/mm/pgtable.c
> @@ -168,7 +168,7 @@ static int preallocate_pmds(struct mm_struct *mm, pmd_t *pmds[], int count)
> bool failed = false;
> gfp_t gfp = GFP_PGTABLE_USER;
>
> - if (mm == &init_mm)
> + if (mm_is_kernel(mm))
> gfp &= ~__GFP_ACCOUNT;
> gfp &= ~__GFP_HIGHMEM;
This hunk is probably fine.
> diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
> index 1023acadd8f8..5517cab8ad00 100644
> --- a/arch/x86/mm/tlb.c
> +++ b/arch/x86/mm/tlb.c
> @@ -594,7 +594,7 @@ void leave_mm(void)
> * This needs to happen before any other sanity checks due to
> * intel_idle's shenanigans.
> */
> - if (loaded_mm == &init_mm)
> + if (mm_is_kernel(loaded_mm))
> return;
This one is almost *certainly* buggy.
The efi_mm stuff uses leave_mm(). In fact, I think it's what's
responsible for switching the hardware back over to use the init_mm page
tables. If this check trips for init_mm, then the kernel will stay
running on efi_mm when it's not intended to.
Remember when I asked about whether there was going to be *a* kernel mm
or lots? This is where it starts to matter. It's outside the diff
context but the code here is basically:
if (loaded_mm == &init_mm)
return;
switch_mm(NULL, &init_mm, NULL);
So either all kernel mm's are equivalent or this code doesn't quite work.
> /* Warn if we're not lazy. */
> @@ -855,7 +855,7 @@ void switch_mm_irqs_off(struct mm_struct *unused, struct mm_struct *next,
> * cpu_tlbstate_shared.is_lazy whether or not to send an IPI.
> */
> if (IS_ENABLED(CONFIG_DEBUG_VM) &&
> - WARN_ON_ONCE(prev != &init_mm && !is_notrack_mm(prev) &&
> + WARN_ON_ONCE(!mm_is_kernel(prev) && !is_notrack_mm(prev) &&
> !cpumask_test_cpu(cpu, mm_cpumask(next))))
> cpumask_set_cpu(cpu, mm_cpumask(next));
>
> @@ -932,7 +932,8 @@ void switch_mm_irqs_off(struct mm_struct *unused, struct mm_struct *next,
> * This way switch_mm() must see the new tlb_gen or
> * flush_tlb_mm_range() must see the new loaded_mm, or both.
> */
> - if (next != &init_mm && !cpumask_test_cpu(cpu, mm_cpumask(next)))
> + if (!mm_is_kernel(next) &&
> + !cpumask_test_cpu(cpu, mm_cpumask(next)))
> cpumask_set_cpu(cpu, mm_cpumask(next));
> else
> smp_mb();
This one is interesting. It's basically saying that init_mm doesn't get
mm_cpumask() updates. That makes sense since it has special TLB flushing
rules. But what does this mean for efi_mm? Does it needs mm_cpumask()
updates?
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 14/22] mm: set page table page type when allocated
2026-07-14 14:04 ` Kevin Brodsky
@ 2026-07-14 15:16 ` Vishal Moola
-1 siblings, 0 replies; 62+ messages in thread
From: Vishal Moola @ 2026-07-14 15:16 UTC (permalink / raw)
To: Kevin Brodsky
Cc: linux-mm, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Alistair Popple, Matthew Wilcox (Oracle), linux-kernel,
linux-arch
On Tue, Jul 14, 2026 at 03:04:03PM +0100, Kevin Brodsky wrote:
> As a step towards removing pagetable ctor/dtor calls for kernel
> mm's, move the page type updates from the ctor/dtor to
> pagetable_{alloc,free}.
Thanks for doing this patchset.
We should switch over from __folio_set_pgtable() to __SetPagePgtable()
in this patch. Ptdescs and folios should be treated as distinctly
independent of each other.
Eventually, we want to replace the memcg accounting as well, but
there's no existing API for that right now. Lets leave that as is for
now; this patchset is big enough already ;)
> __pagetable_ctor() is now empty so remove it;
> pagetable_{pud,p4d,pgd}_ctor() will be removed at a later stage.
>
> The ctor is normally called after pagetable_alloc() (and dtor before
> pagetable_free()) so this patch should have no functional effect in
> most cases. Where calls to ctor/dtor are currently missing (e.g.
> x86's split_large_page()), this patch will ensure the page type is
> set correctly.
>
> This patch is based on Matthew's earlier implementation linked
> below, with the difference that when freeing the page type is
> cleared in __pagetable_free(), meaning that the update is delayed
> until the pages are actually freed in the
> CONFIG_ASYNC_KERNEL_PGTABLE_FREE case. This shouldn't matter in
> practice.
>
> Suggested-by: "Matthew Wilcox (Oracle)" <willy@infradead.org>
> Link: https://lore.kernel.org/r/20251113140448.1814860-4-willy@infradead.org
> Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
> ---
> include/linux/mm.h | 17 ++---------------
> 1 file changed, 2 insertions(+), 15 deletions(-)
>
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 361a0d7b74c5..94f0fb1c662a 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -3684,6 +3684,7 @@ static inline struct ptdesc *pagetable_alloc_noprof(gfp_t gfp, unsigned int orde
> if (!page)
> return NULL;
>
> + __folio_set_pgtable(page_folio(page));
> lruvec_stat_add_folio(page_folio(page), NR_PAGETABLE);
>
> return page_ptdesc(page);
> @@ -3694,6 +3695,7 @@ static inline void __pagetable_free(struct ptdesc *pt)
> {
> struct page *page = ptdesc_page(pt);
>
> + __folio_clear_pgtable(page_folio(page));
> lruvec_stat_sub_folio(page_folio(page), NR_PAGETABLE);
>
> __free_pages(page, compound_order(page));
> @@ -3799,19 +3801,9 @@ static inline bool ptlock_init(struct ptdesc *ptdesc) { return true; }
> static inline void ptlock_free(struct ptdesc *ptdesc) {}
> #endif /* defined(CONFIG_SPLIT_PTE_PTLOCKS) */
>
> -static inline void __pagetable_ctor(struct ptdesc *ptdesc)
> -{
> - struct folio *folio = ptdesc_folio(ptdesc);
> -
> - __folio_set_pgtable(folio);
> -}
> -
> static inline void pagetable_dtor(struct ptdesc *ptdesc)
> {
> - struct folio *folio = ptdesc_folio(ptdesc);
> -
> ptlock_free(ptdesc);
> - __folio_clear_pgtable(folio);
> }
>
> static inline void pagetable_dtor_free(struct ptdesc *ptdesc)
> @@ -3825,7 +3817,6 @@ static inline bool pagetable_pte_ctor(struct mm_struct *mm,
> {
> if (!mm_is_kernel(mm) && !ptlock_init(ptdesc))
> return false;
> - __pagetable_ctor(ptdesc);
> return true;
> }
>
> @@ -3917,7 +3908,6 @@ static inline bool pagetable_pmd_ctor(struct mm_struct *mm,
> if (!mm_is_kernel(mm) && !pmd_ptlock_init(ptdesc))
> return false;
> ptdesc_pmd_pts_init(ptdesc);
> - __pagetable_ctor(ptdesc);
> return true;
> }
>
> @@ -3942,17 +3932,14 @@ static inline spinlock_t *pud_lock(struct mm_struct *mm, pud_t *pud)
>
> static inline void pagetable_pud_ctor(struct ptdesc *ptdesc)
> {
> - __pagetable_ctor(ptdesc);
> }
>
> static inline void pagetable_p4d_ctor(struct ptdesc *ptdesc)
> {
> - __pagetable_ctor(ptdesc);
> }
>
> static inline void pagetable_pgd_ctor(struct ptdesc *ptdesc)
> {
> - __pagetable_ctor(ptdesc);
> }
>
> extern void __init pagecache_init(void);
>
> --
> 2.51.2
>
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 14/22] mm: set page table page type when allocated
@ 2026-07-14 15:16 ` Vishal Moola
0 siblings, 0 replies; 62+ messages in thread
From: Vishal Moola @ 2026-07-14 15:16 UTC (permalink / raw)
To: Kevin Brodsky
Cc: linux-mm, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Alistair Popple, Matthew Wilcox (Oracle), linux-kernel,
linux-arch
On Tue, Jul 14, 2026 at 03:04:03PM +0100, Kevin Brodsky wrote:
> As a step towards removing pagetable ctor/dtor calls for kernel
> mm's, move the page type updates from the ctor/dtor to
> pagetable_{alloc,free}.
Thanks for doing this patchset.
We should switch over from __folio_set_pgtable() to __SetPagePgtable()
in this patch. Ptdescs and folios should be treated as distinctly
independent of each other.
Eventually, we want to replace the memcg accounting as well, but
there's no existing API for that right now. Lets leave that as is for
now; this patchset is big enough already ;)
> __pagetable_ctor() is now empty so remove it;
> pagetable_{pud,p4d,pgd}_ctor() will be removed at a later stage.
>
> The ctor is normally called after pagetable_alloc() (and dtor before
> pagetable_free()) so this patch should have no functional effect in
> most cases. Where calls to ctor/dtor are currently missing (e.g.
> x86's split_large_page()), this patch will ensure the page type is
> set correctly.
>
> This patch is based on Matthew's earlier implementation linked
> below, with the difference that when freeing the page type is
> cleared in __pagetable_free(), meaning that the update is delayed
> until the pages are actually freed in the
> CONFIG_ASYNC_KERNEL_PGTABLE_FREE case. This shouldn't matter in
> practice.
>
> Suggested-by: "Matthew Wilcox (Oracle)" <willy@infradead.org>
> Link: https://lore.kernel.org/r/20251113140448.1814860-4-willy@infradead.org
> Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
> ---
> include/linux/mm.h | 17 ++---------------
> 1 file changed, 2 insertions(+), 15 deletions(-)
>
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 361a0d7b74c5..94f0fb1c662a 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -3684,6 +3684,7 @@ static inline struct ptdesc *pagetable_alloc_noprof(gfp_t gfp, unsigned int orde
> if (!page)
> return NULL;
>
> + __folio_set_pgtable(page_folio(page));
> lruvec_stat_add_folio(page_folio(page), NR_PAGETABLE);
>
> return page_ptdesc(page);
> @@ -3694,6 +3695,7 @@ static inline void __pagetable_free(struct ptdesc *pt)
> {
> struct page *page = ptdesc_page(pt);
>
> + __folio_clear_pgtable(page_folio(page));
> lruvec_stat_sub_folio(page_folio(page), NR_PAGETABLE);
>
> __free_pages(page, compound_order(page));
> @@ -3799,19 +3801,9 @@ static inline bool ptlock_init(struct ptdesc *ptdesc) { return true; }
> static inline void ptlock_free(struct ptdesc *ptdesc) {}
> #endif /* defined(CONFIG_SPLIT_PTE_PTLOCKS) */
>
> -static inline void __pagetable_ctor(struct ptdesc *ptdesc)
> -{
> - struct folio *folio = ptdesc_folio(ptdesc);
> -
> - __folio_set_pgtable(folio);
> -}
> -
> static inline void pagetable_dtor(struct ptdesc *ptdesc)
> {
> - struct folio *folio = ptdesc_folio(ptdesc);
> -
> ptlock_free(ptdesc);
> - __folio_clear_pgtable(folio);
> }
>
> static inline void pagetable_dtor_free(struct ptdesc *ptdesc)
> @@ -3825,7 +3817,6 @@ static inline bool pagetable_pte_ctor(struct mm_struct *mm,
> {
> if (!mm_is_kernel(mm) && !ptlock_init(ptdesc))
> return false;
> - __pagetable_ctor(ptdesc);
> return true;
> }
>
> @@ -3917,7 +3908,6 @@ static inline bool pagetable_pmd_ctor(struct mm_struct *mm,
> if (!mm_is_kernel(mm) && !pmd_ptlock_init(ptdesc))
> return false;
> ptdesc_pmd_pts_init(ptdesc);
> - __pagetable_ctor(ptdesc);
> return true;
> }
>
> @@ -3942,17 +3932,14 @@ static inline spinlock_t *pud_lock(struct mm_struct *mm, pud_t *pud)
>
> static inline void pagetable_pud_ctor(struct ptdesc *ptdesc)
> {
> - __pagetable_ctor(ptdesc);
> }
>
> static inline void pagetable_p4d_ctor(struct ptdesc *ptdesc)
> {
> - __pagetable_ctor(ptdesc);
> }
>
> static inline void pagetable_pgd_ctor(struct ptdesc *ptdesc)
> {
> - __pagetable_ctor(ptdesc);
> }
>
> extern void __init pagecache_init(void);
>
> --
> 2.51.2
>
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 16/22] efi: mark efi_mm as a kernel mm
2026-07-14 14:04 ` Kevin Brodsky
(?)
@ 2026-07-14 15:16 ` sashiko-bot
-1 siblings, 0 replies; 62+ messages in thread
From: sashiko-bot @ 2026-07-14 15:16 UTC (permalink / raw)
To: Kevin Brodsky
Cc: Alexander Gordeev, Vasily Gorbik, linux-s390, Heiko Carstens
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Incomplete implementation: split page table locks are still initialized for efi_mm on ARM64 and RISC-V.
--
--- Patch [16]: [PATCH 16/22] efi: mark efi_mm as a kernel mm ---
commit ebd104815a1ccc8b9a1160dde0da2bdd7e88ce96
Author: Kevin Brodsky <kevin.brodsky@arm.com>
efi: mark efi_mm as a kernel mm
This commit marks efi_mm with the MMF_KERNEL flag, treating it as a
kernel-owned address space. This avoids unnecessary complications by skipping
split page table lock initialization and constructor/destructor calls.
> diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
> index 0327a39d31fa5..e5ca45bdc890c 100644
> --- a/drivers/firmware/efi/efi.c
> +++ b/drivers/firmware/efi/efi.c
> @@ -69,6 +69,7 @@ struct mm_struct efi_mm = {
> .mm_mt = MTREE_INIT_EXT(mm_mt, MM_MT_FLAGS, efi_mm.mmap_lock),
> .mm_users = ATOMIC_INIT(2),
> .mm_count = ATOMIC_INIT(1),
> + .flags = MM_FLAGS_INIT(MMF_KERNEL_MASK),
[Severity: Medium]
The commit message notes that split page table locks are no longer initialized
for efi_mm's page tables. Is this accurate for all architectures?
On ARM64 and RISC-V, the EFI page table allocation paths pass NULL instead of
the mm_struct to the generic page table constructors:
arch/arm64/mm/mmu.c:pgd_pgtable_alloc_special_mm() {
...
return __pgd_pgtable_alloc(NULL, GFP_PGTABLE_KERNEL, pgtable_level);
}
arch/riscv/mm/init.c:alloc_pte_late() {
...
BUG_ON(!ptdesc || !pagetable_pte_ctor(NULL, ptdesc));
...
}
Because NULL is passed instead of &efi_mm, the constructors cannot check the
MMF_KERNEL flag, meaning the split page table locks will still be
unconditionally initialized.
Does this optimization require updating the architecture-specific EFI allocation
paths to pass the mm_struct instead of NULL?
> .write_protect_seq = SEQCNT_ZERO(efi_mm.write_protect_seq),
> MMAP_LOCK_INITIALIZER(efi_mm)
> .page_table_lock = __SPIN_LOCK_UNLOCKED(efi_mm.page_table_lock),
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260714-remove_pgtable_cdtor-v1-0-44be8a7685d7@arm.com?part=16
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 19/22] x86/tboot: mark tboot_mm as a kernel mm
2026-07-14 14:04 ` Kevin Brodsky
@ 2026-07-14 15:19 ` Dave Hansen
-1 siblings, 0 replies; 62+ messages in thread
From: Dave Hansen @ 2026-07-14 15:19 UTC (permalink / raw)
To: Kevin Brodsky, linux-mm
Cc: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
On 7/14/26 07:04, Kevin Brodsky wrote:
> tboot_mm is a kernel-owned address space used to build the
> identity map for tboot shutdown. Mark it with MMF_KERNEL so
> page table allocation and initialisation code treats its page tables
> as kernel page tables.
>
> Having marked tboot_mm as a kernel mm, we also need to convert
> pte_alloc_map() (user PTE) to pte_alloc_kernel() (kernel PTE), and
> drop the matching pte_unmap().
This makes me wonder whether MMF_KERNEL is the right way to mark these mms.
I think this series tries to cram too much into that one bit.
Using MMF_KERNEL to drive the page table accounting seems like a good
idea. It also seems like a good thing to make sure that those mm's don't
ever exit to userspace, for instance.
But I think it goes a step too far to say that all the special 'init_mm'
TLB flushing should also be common among all MMF_KERNEL mms.
My suggestion for now would be to just go after the page table
accounting alone. Don't mechanically replace mm==&mm_init checks.
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [PATCH 19/22] x86/tboot: mark tboot_mm as a kernel mm
@ 2026-07-14 15:19 ` Dave Hansen
0 siblings, 0 replies; 62+ messages in thread
From: Dave Hansen @ 2026-07-14 15:19 UTC (permalink / raw)
To: Kevin Brodsky, linux-mm
Cc: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Pasha Tatashin, Russell King,
Catalin Marinas, Will Deacon, Ryan Roberts, linux-arm-kernel,
Huacai Chen, loongarch, James E.J. Bottomley, Helge Deller,
linux-parisc, Madhavan Srinivasan, Michael Ellerman, linuxppc-dev,
Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv,
Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Gerald Schaefer,
linux-s390, David S. Miller, Andreas Larsson, sparclinux,
Richard Weinberger, Anton Ivanov, Johannes Berg, linux-um,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Ning Sun, x86,
tboot-devel, Ard Biesheuvel, Ilias Apalodimas, linux-efi,
Vishal Moola, Alistair Popple, Matthew Wilcox (Oracle),
linux-kernel, linux-arch
On 7/14/26 07:04, Kevin Brodsky wrote:
> tboot_mm is a kernel-owned address space used to build the
> identity map for tboot shutdown. Mark it with MMF_KERNEL so
> page table allocation and initialisation code treats its page tables
> as kernel page tables.
>
> Having marked tboot_mm as a kernel mm, we also need to convert
> pte_alloc_map() (user PTE) to pte_alloc_kernel() (kernel PTE), and
> drop the matching pte_unmap().
This makes me wonder whether MMF_KERNEL is the right way to mark these mms.
I think this series tries to cram too much into that one bit.
Using MMF_KERNEL to drive the page table accounting seems like a good
idea. It also seems like a good thing to make sure that those mm's don't
ever exit to userspace, for instance.
But I think it goes a step too far to say that all the special 'init_mm'
TLB flushing should also be common among all MMF_KERNEL mms.
My suggestion for now would be to just go after the page table
accounting alone. Don't mechanically replace mm==&mm_init checks.
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 62+ messages in thread
end of thread, other threads:[~2026-07-14 15:20 UTC | newest]
Thread overview: 62+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-14 14:03 [PATCH 00/22] Simplify special kernel page table handling Kevin Brodsky
2026-07-14 14:03 ` Kevin Brodsky
2026-07-14 14:03 ` [PATCH 01/22] mm: drop unused __mm_flags_set_mask_bits_word() Kevin Brodsky
2026-07-14 14:03 ` Kevin Brodsky
2026-07-14 14:03 ` [PATCH 02/22] mm: move mm_flags helpers to mm_types.h Kevin Brodsky
2026-07-14 14:03 ` Kevin Brodsky
2026-07-14 14:03 ` [PATCH 03/22] mm: introduce MMF_KERNEL flag and set it for init_mm Kevin Brodsky
2026-07-14 14:03 ` Kevin Brodsky
2026-07-14 14:47 ` Dave Hansen
2026-07-14 14:47 ` Dave Hansen
2026-07-14 15:04 ` Lorenzo Stoakes (ARM)
2026-07-14 15:04 ` Lorenzo Stoakes (ARM)
2026-07-14 14:03 ` [PATCH 04/22] mm: use mm_is_kernel() in generic page table code Kevin Brodsky
2026-07-14 14:03 ` Kevin Brodsky
2026-07-14 14:28 ` sashiko-bot
2026-07-14 14:03 ` [PATCH 05/22] arm64: mm: use mm_is_kernel() for kernel mm checks Kevin Brodsky
2026-07-14 14:03 ` Kevin Brodsky
2026-07-14 14:03 ` [PATCH 06/22] loongarch: mm: use mm_is_kernel() in switch_mm_irqs_off() Kevin Brodsky
2026-07-14 14:03 ` Kevin Brodsky
2026-07-14 14:03 ` [PATCH 07/22] parisc: mm: use mm_is_kernel() for kernel mm checks Kevin Brodsky
2026-07-14 14:03 ` Kevin Brodsky
2026-07-14 14:03 ` [PATCH 08/22] powerpc: " Kevin Brodsky
2026-07-14 14:03 ` Kevin Brodsky
2026-07-14 14:03 ` [PATCH 09/22] s390: " Kevin Brodsky
2026-07-14 14:03 ` Kevin Brodsky
2026-07-14 14:03 ` [PATCH 10/22] sparc: " Kevin Brodsky
2026-07-14 14:03 ` Kevin Brodsky
2026-07-14 14:04 ` [PATCH 11/22] um: mm: use mm_is_kernel() in TLB sync Kevin Brodsky
2026-07-14 14:04 ` Kevin Brodsky
2026-07-14 14:04 ` [PATCH 12/22] x86/mm: use mm_is_kernel() for kernel mm checks Kevin Brodsky
2026-07-14 14:04 ` Kevin Brodsky
2026-07-14 15:09 ` Dave Hansen
2026-07-14 15:09 ` Dave Hansen
2026-07-14 14:04 ` [PATCH 13/22] mm: account page table pages when allocated Kevin Brodsky
2026-07-14 14:04 ` Kevin Brodsky
2026-07-14 14:54 ` sashiko-bot
2026-07-14 14:04 ` [PATCH 14/22] mm: set page table page type " Kevin Brodsky
2026-07-14 14:04 ` Kevin Brodsky
2026-07-14 14:54 ` sashiko-bot
2026-07-14 15:16 ` Vishal Moola
2026-07-14 15:16 ` Vishal Moola
2026-07-14 14:04 ` [PATCH 15/22] mm: only initialise pt_share_count for user pgtables Kevin Brodsky
2026-07-14 14:04 ` Kevin Brodsky
2026-07-14 14:04 ` [PATCH 16/22] efi: mark efi_mm as a kernel mm Kevin Brodsky
2026-07-14 14:04 ` Kevin Brodsky
2026-07-14 15:16 ` sashiko-bot
2026-07-14 14:04 ` [PATCH 17/22] mm: pagewalk: drop redundant address check for kernel mm walks Kevin Brodsky
2026-07-14 14:04 ` Kevin Brodsky
2026-07-14 14:42 ` sashiko-bot
2026-07-14 14:04 ` [PATCH 18/22] arm64: mm: drop explicit mm_is_efi() check in contpte Kevin Brodsky
2026-07-14 14:04 ` Kevin Brodsky
2026-07-14 14:04 ` [PATCH 19/22] x86/tboot: mark tboot_mm as a kernel mm Kevin Brodsky
2026-07-14 14:04 ` Kevin Brodsky
2026-07-14 15:19 ` Dave Hansen
2026-07-14 15:19 ` Dave Hansen
2026-07-14 14:04 ` [PATCH 20/22] arm64: mm: drop ctor/dtor calls for kernel page tables Kevin Brodsky
2026-07-14 14:04 ` Kevin Brodsky
2026-07-14 14:56 ` sashiko-bot
2026-07-14 14:04 ` [PATCH 21/22] arm: mm: drop ctor call " Kevin Brodsky
2026-07-14 14:04 ` Kevin Brodsky
2026-07-14 14:04 ` [PATCH 22/22] riscv: mm: drop ctor/dtor calls " Kevin Brodsky
2026-07-14 14:04 ` Kevin Brodsky
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.