From: sashiko-bot@kernel.org
To: "Kevin Brodsky" <kevin.brodsky@arm.com>
Cc: "Andrew Morton" <akpm@linux-foundation.org>,
"Ard Biesheuvel" <ardb+git@google.com>,
"Andy Lutomirski" <luto@kernel.org>,
"Catalin Marinas" <catalin.marinas@arm.com>,
"Dave Hansen" <dave.hansen@linux.intel.com>,
"David Hildenbrand (Arm)" <david@kernel.org>,
"Jann Horn" <jannh@google.com>, "Jeff Xu" <jeffxu@chromium.org>,
"Joey Gouly" <joey.gouly@arm.com>, "Kees Cook" <kees@kernel.org>,
"Linu Cherian" <linu.cherian@arm.com>,
"Linus Walleij" <linusw@kernel.org>,
"Marc Zyngier" <maz@kernel.org>,
"Mark Brown" <broonie@kernel.org>,
"Matthew Wilcox" <willy@infradead.org>,
"Maxwell Bland" <mbland@motorola.com>,
"Mike Rapoport (IBM)" <rppt@kernel.org>,
"Peter Zijlstra" <peterz@infradead.org>,
"Pierre Langlois" <pierre.langlois@arm.com>,
"Pierre-Clément Tosi" <ptosi@google.com>,
"Quentin Perret" <qperret@google.com>,
"Rick Edgecombe" <rick.p.edgecombe@intel.com>,
"Ryan Roberts" <ryan.roberts@arm.com>,
"Vlastimil Babka" <vbabka@kernel.org>,
"Will Deacon" <will@kernel.org>,
"Yang Shi" <yang@os.amperecomputing.com>,
"Yeoreum Yun" <yeoreum.yun@arm.com>,
linux-mm@kvack.org, x86@kernel.org,
"Ira Weiny" <iweiny@kernel.org>,
"Lorenzo Stoakes" <ljs@kernel.org>,
"Thomas Gleixner" <tglx@kernel.org>
Subject: Re: [PATCH RFC v10 13/22] mm: kpkeys: Protect early kernel page tables
Date: Tue, 10 Nov 2026 16:02:53 +0000 [thread overview]
Message-ID: <sashiko-outbox-207327@kernel.org> (raw)
In-Reply-To: <20261109-kpkeys-v10-13-aa6c4d9603bc@arm.com>
Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [Medium] mm: kpkeys: redundant KASAN shadow walks in
protect_early_kernel_pgtables()
- [Medium] mm: kpkeys: repeated swapper_pg_dir walks in
protect_early_kernel_pgtables()
--
commit 9b67b4dcc54e06a0681d8d0ff9c11cb3015125f0
Author: Kevin Brodsky <kevin.brodsky@arm.com>
mm: kpkeys: Protect early kernel page tables
This commit walks the installed kernel page tables during boot and sets the
direct-map pkey of their backing pages to KPKEYS_PKEY_PGTABLES when
kpkeys_hardened_pgtables is enabled.
> diff --git a/mm/kpkeys_hardened_pgtables.c b/mm/kpkeys_hardened_pgtables.c
> index 2311fd8da6bbb..f6825a0e0689d 100644
> --- a/mm/kpkeys_hardened_pgtables.c
> +++ b/mm/kpkeys_hardened_pgtables.c
> @@ -54,10 +56,130 @@ void kpkeys_pgtable_free(struct page *page, unsigned int order)
> __free_pages(page, order);
> }
>
> +static void __init protect_pgtable_page(void *page)
> +{
> + int ret;
> +
> + ret = set_direct_map_pkey((unsigned long)page, 1, KPKEYS_PKEY_PGTABLES);
> + WARN_ON_ONCE(ret);
> +}
> +
> +static int __init protect_pte_table(pmd_t *pmd, unsigned long addr,
> + unsigned long next, struct mm_walk *walk)
> +{
> + pmd_t entry = pmdp_get(pmd);
> +
> + if (!pmd_present(entry) || pmd_leaf(entry))
> + return 0;
> +
> + protect_pgtable_page(pte_offset_kernel(pmd, 0));
> +
> + return 0;
> +}
> +
> +static int __init protect_pmd_table(pud_t *pud, unsigned long addr,
> + unsigned long next, struct mm_walk *walk)
> +{
> + pud_t entry;
> +
> + if (mm_pmd_folded(walk->mm))
> + return 0;
> +
> + entry = pudp_get(pud);
> + if (!pud_present(entry) || pud_leaf(entry))
> + return 0;
> +
> + protect_pgtable_page(pmd_offset(pud, 0));
> +
> + return 0;
> +}
> +
> +static int __init protect_pud_table(p4d_t *p4d, unsigned long addr,
> + unsigned long next, struct mm_walk *walk)
> +{
> + p4d_t entry;
> +
> + if (mm_pud_folded(walk->mm))
> + return 0;
> +
> + entry = p4dp_get(p4d);
> + if (!p4d_present(entry) || p4d_leaf(entry))
> + return 0;
> +
> + protect_pgtable_page(pud_offset(p4d, 0));
> +
> + return 0;
> +}
> +
> +static int __init protect_p4d_table(pgd_t *pgd, unsigned long addr,
> + unsigned long next, struct mm_walk *walk)
> +{
> + pgd_t entry;
> +
> + if (mm_p4d_folded(walk->mm))
> + return 0;
> +
> + entry = pgdp_get(pgd);
> + if (!pgd_present(entry) || pgd_leaf(entry))
> + return 0;
> +
> + protect_pgtable_page(p4d_offset(pgd, 0));
> +
> + return 0;
> +}
[Severity: Medium]
When CONFIG_KASAN_GENERIC or CONFIG_KASAN_SW_TAGS is enabled, does this walk
and call set_direct_map_pkey() millions of times on the shared
kasan_early_shadow_{p4d,pud,pmd,pte} tables?
kasan_init() runs in setup_arch() before mm_core_init() calls
kpkeys_hardened_pgtables_init(), populating unbacked shadow ranges in
[PAGE_OFFSET, ULONG_MAX) with shared static tables where all 512 entries at
each level point to the same next-level kasan_early_shadow_* page. Unlike
mm/ptdump.c, which detects those tables and sets walk->action =
ACTION_CONTINUE, the callbacks here descend through every entry and invoke
set_direct_map_pkey() (including a direct-map page table walk and broadcast
TLB flush) for every 2 MiB PMD slot across the multi-terabyte shadow range,
stalling boot.
[ ... ]
> +static void __init protect_early_kernel_pgtables(void)
> +{
> + int ret;
> +
> + mmap_write_lock(&init_mm);
> + /*
> + * [PAGE_OFFSET, ULONG_MAX) covers all early kernel mappings on arm64
> + * and x86 (at least).
> + */
> + ret = walk_kernel_page_table_range(PAGE_OFFSET, ULONG_MAX,
> + &protect_pgtable_ops, NULL, NULL);
> + mmap_write_unlock(&init_mm);
> + WARN_ON_ONCE(ret);
> +}
[Severity: Medium]
On arm64 with CONFIG_ARM64_LPA2=y running on hardware where the top page
table level is dynamically folded (vabits_actual < VA_BITS), does starting
at PAGE_OFFSET walk and re-protect swapper_pg_dir 16 or 32 times?
On arm64, PAGE_OFFSET is the compile-time _PAGE_OFFSET(VA_BITS) rather than
_PAGE_OFFSET(vabits_actual). When !pgtable_l5_enabled() on 4K pages (or
!pgtable_l4_enabled() on 16K pages), pgd_none() is always false and
pgd_to_folded_p4d() (or p4d_to_folded_pud()) wraps each top-level step in
[PAGE_OFFSET, ULONG_MAX) back to the start of swapper_pg_dir:
arch/arm64/include/asm/pgtable.h:pgd_to_folded_p4d() {
return (p4d_t *)PTR_ALIGN_DOWN(pgdp, PAGE_SIZE) + p4d_index(addr);
}
As a result, walk_kernel_page_table_range() traverses the entire kernel page
table hierarchy and flushes TLBs across all page table pages 16 times on 4K
pages (or 32 times on 16K pages) during boot.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261109-kpkeys-v10-0-aa6c4d9603bc@arm.com?part=13
next prev parent reply other threads:[~2026-11-10 16:03 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-09 15:58 [PATCH RFC v10 00/22] pkeys-based page table hardening Kevin Brodsky
2026-11-09 15:58 ` [PATCH RFC v10 01/22] mm: Introduce kpkeys Kevin Brodsky
2026-11-10 16:02 ` sashiko-bot
2026-11-11 10:24 ` Kevin Brodsky
2026-11-09 15:58 ` [PATCH RFC v10 02/22] set_memory: Introduce set_direct_map_pkey() stub Kevin Brodsky
2026-11-09 15:58 ` [PATCH RFC v10 03/22] arm64: Introduce por_elx_set_pkey_perms() helper Kevin Brodsky
2026-11-09 15:58 ` [PATCH RFC v10 04/22] arm64: Implement asm/kpkeys.h using POE Kevin Brodsky
2026-11-10 14:19 ` Mark Brown
2026-11-11 10:26 ` Kevin Brodsky
2026-11-10 16:02 ` sashiko-bot
2026-11-11 15:18 ` Kevin Brodsky
2026-11-09 15:58 ` [PATCH RFC v10 05/22] arm64: set_memory: Implement set_direct_map_pkey() Kevin Brodsky
2026-11-09 15:58 ` [PATCH RFC v10 06/22] arm64: Disable EL2 trapping of POR_EL1 Kevin Brodsky
2026-11-10 15:29 ` Mark Brown
2026-11-11 15:22 ` Kevin Brodsky
2026-11-09 15:58 ` [PATCH RFC v10 07/22] arm64: Initialize POR_EL1 register on cpu_resume() Kevin Brodsky
2026-11-10 15:53 ` Mark Brown
2026-11-10 16:36 ` Yeoreum Yun
2026-11-12 12:38 ` Kevin Brodsky
2026-11-12 13:02 ` Mark Brown
2026-11-12 13:14 ` Yeoreum Yun
2026-11-12 14:09 ` Mark Brown
2026-11-12 13:16 ` Kevin Brodsky
2026-11-10 16:02 ` sashiko-bot
2026-11-09 15:58 ` [PATCH RFC v10 08/22] arm64: Context-switch POR_EL1 Kevin Brodsky
2026-11-09 15:58 ` [PATCH RFC v10 09/22] arm64: mm: Enable overlays for all EL1 indirect permissions Kevin Brodsky
2026-11-09 15:58 ` [PATCH RFC v10 10/22] arm64: Enable kpkeys Kevin Brodsky
2026-11-10 16:02 ` sashiko-bot
2026-11-09 15:58 ` [PATCH RFC v10 11/22] mm: kpkeys: Introduce kpkeys_hardened_pgtables feature Kevin Brodsky
2026-11-09 15:58 ` [PATCH RFC v10 12/22] mm: kpkeys: Protect regular page tables Kevin Brodsky
2026-11-09 15:58 ` [PATCH RFC v10 13/22] mm: kpkeys: Protect early kernel " Kevin Brodsky
2026-11-10 16:02 ` sashiko-bot [this message]
2026-11-12 11:28 ` Kevin Brodsky
2026-11-09 15:58 ` [PATCH RFC v10 14/22] mm: kpkeys: Protect vmemmap " Kevin Brodsky
2026-11-09 15:58 ` [PATCH RFC v10 15/22] arm64: kpkeys: Implement arch_supports_kpkeys_early() Kevin Brodsky
2026-11-09 15:58 ` [PATCH RFC v10 16/22] arm64: kpkeys: Support KPKEYS_CTX_PGTABLES Kevin Brodsky
2026-11-09 15:58 ` [PATCH RFC v10 17/22] arm64: kpkeys: Ensure the linear map can be modified Kevin Brodsky
2026-11-09 15:58 ` [PATCH RFC v10 18/22] arm64: kpkeys: Guard page table writes Kevin Brodsky
2026-11-09 15:58 ` [PATCH RFC v10 19/22] arm64: kpkeys: Batch KPKEYS_CTX_PGTABLES switches Kevin Brodsky
2026-11-10 16:02 ` sashiko-bot
2026-11-12 13:21 ` Kevin Brodsky
2026-11-09 15:58 ` [PATCH RFC v10 20/22] arm64: kpkeys: Enable kpkeys_hardened_pgtables support Kevin Brodsky
2026-11-10 16:02 ` sashiko-bot
2026-11-09 15:58 ` [PATCH RFC v10 21/22] arm64: mm: Map kernel image alias of init_pg_dir read-only Kevin Brodsky
2026-11-10 16:02 ` sashiko-bot
2026-11-09 15:58 ` [PATCH RFC v10 22/22] mm: Add basic tests for kpkeys_hardened_pgtables Kevin Brodsky
2026-11-09 19:28 ` Mark Brown
2026-11-10 9:01 ` Kevin Brodsky
2026-11-10 11:24 ` Mark Brown
2026-11-11 15:29 ` Kevin Brodsky
2026-11-11 16:15 ` Mark Brown
2026-11-12 11:39 ` Kevin Brodsky
2026-11-10 16:03 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-207327@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=ardb+git@google.com \
--cc=broonie@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=dave.hansen@linux.intel.com \
--cc=david@kernel.org \
--cc=iweiny@kernel.org \
--cc=jannh@google.com \
--cc=jeffxu@chromium.org \
--cc=joey.gouly@arm.com \
--cc=kees@kernel.org \
--cc=kevin.brodsky@arm.com \
--cc=linu.cherian@arm.com \
--cc=linusw@kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=luto@kernel.org \
--cc=maz@kernel.org \
--cc=mbland@motorola.com \
--cc=peterz@infradead.org \
--cc=pierre.langlois@arm.com \
--cc=ptosi@google.com \
--cc=qperret@google.com \
--cc=rick.p.edgecombe@intel.com \
--cc=rppt@kernel.org \
--cc=ryan.roberts@arm.com \
--cc=sashiko-reviews@lists.linux.dev \
--cc=tglx@kernel.org \
--cc=vbabka@kernel.org \
--cc=will@kernel.org \
--cc=willy@infradead.org \
--cc=x86@kernel.org \
--cc=yang@os.amperecomputing.com \
--cc=yeoreum.yun@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.