[PATCH] arm64: mm: fix accidental linear mapping of no-map reserved memory
Will Deacon
will at kernel.org
Tue Aug 4 06:41:44 PDT 2026
On Mon, Jul 27, 2026 at 09:55:58AM +0800, Lianghong Liu wrote:
> Thanks for the review. Quick answers to the two open questions.
>
> ## What I'm seeing on my system
>
> 64K pages (PAGE_SHIFT=16). A no-map reserved region at 0xA2000000 with
> size 0x8000 (32 KiB, sub-page). The linear map should skip that hole and
> start at 0xA2008000; instead it starts at 0xA2000000 — the whole no-map
> region is mapped with PAGE_KERNEL. Debug print in
> __create_pgd_mapping_locked():
>
> create_pgd_mapping: phys 0xa2008000 ...
> after PAGE_MASK align: phys 0xa2000000 - 0xab000000 <- start rounded DOWN into no-map
>
> Cause: for_each_mem_range skips MEMBLOCK_NOMAP regions via
> should_skip_region(), but memblock_mark_nomap() splits at byte
> boundaries in memblock_isolate_range() (rgn->base = base), so the
> *adjacent* region is returned with a sub-page-aligned start/end. That
> value then hits
> phys &= PAGE_MASK;
> in __create_pgd_mapping_locked(), which rounds the start DOWN and pulls
> the mapping back into the no-map page.
>
> So this is a real isolation break, not cosmetic: no-map memory the
> firmware asked to leave untouched ends up read/writable in the linear
> region.
>
> ## On "we might fail to map legitimately mappable pages"
>
> The inward rounding can't lose any page the allocator owns. The buddy
> release path uses the exact same inward PFN rounding in
> __free_memory_core():
> start_pfn = PFN_UP(start);
> end_pfn = min(PFN_DOWN(end), max_low_pfn);
> if (start_pfn >= end_pfn) return 0;
Sorry, but I don't understand how this has anything to do with the
question I asked. It looks like you just fed my reply to an LLVM and
pasted the response here.
I'm not convinced your patch is correct and I don't understand your
reply.
Will
More information about the linux-arm-kernel
mailing list