From: "Ard Biesheuvel" <ardb@kernel.org>
To: "Mike Rapoport" <rppt@kernel.org>
Cc: "Vladimir Murzin" <vladimir.murzin@arm.com>,
linux-arm-kernel@lists.infradead.org,
"Catalin Marinas" <catalin.marinas@arm.com>,
"Will Deacon" <will@kernel.org>,
liulhong617 <liulhong617@gmail.com>
Subject: Re: [PATCH] arm64: mm: Fix pfn_is_map_memory() misreporting mapped memory
Date: Thu, 24 Sep 2026 12:59:15 +0200 [thread overview]
Message-ID: <7a6793e4-b2ef-46e0-a068-9166d3f10ea3@app.fastmail.com> (raw)
In-Reply-To: <arIXL3CeIvE5HdoF@kernel.org>
On Tue, 22 Sep 2026, at 07:50, Mike Rapoport wrote:
> On Thu, Sep 17, 2026 at 05:17:45PM +0200, Ard Biesheuvel wrote:
>> On Thu, 17 Sep 2026, at 16:29, Mike Rapoport wrote:
>> > On Thu, Sep 17, 2026 at 02:34:57PM +0200, Ard Biesheuvel wrote:
>> >>
>> >>
>> >> On Thu, 17 Sep 2026, at 14:26, Vladimir Murzin wrote:
>> >> > On 9/16/26 11:13, Ard Biesheuvel wrote:
>> >> >> (cc Mike)
>> >> >>
>> >> >> On Tue, 8 Sep 2026, at 18:20, Vladimir Murzin wrote:
>> >> >>> Commit 7ace06a01efa ("arm64: mm: fix accidental linear mapping of
>> >> >>> no-map reserved memory") removed sub-page no-map regions from the
>> >> >>> linear mapping. However, pfn_is_map_memory() can still report that
>> >> >>> such a region is mapped.
>> >> >>>
>> >> >>> For instance, with 64K pages, say we have
>> >> >>>
>> >> >>> normal: ...–0xa2007fff
>> >> >>> no-map: 0xa2008000–0xa200ffff
>> >> >>> normal: 0xa2010000–...
>> >> >>>
>> >> >>> The range 0xa2000000–0xa200ffff is not linearly mapped, but
>> >> >>> pfn_is_map_memory(__phys_to_pfn(0xa2008000)) aligns the address to
>> >> >>> page granularity and passes 0xa2000000 to memblock_is_map_memory().
>> >> >>> That address belongs to the preceding normal memblock region, so the
>> >> >>> no-map region is ignored and the function returns true.
>> >> >>>
>> >> >>> Fix that by checking if entire page is subset of memory block.
>> >> >>>
>> >> >>> Fixes: 7ace06a01efa ("arm64: mm: fix accidental linear mapping of
>> >> >>> no-map reserved memory")
>> >> >>> Assisted-by: LLM
>> >> >>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
>> >> >>> ---
>> >> >>> arch/arm64/mm/init.c | 3 ++-
>> >> >>> 1 file changed, 2 insertions(+), 1 deletion(-)
>> >> >>>
>> >> >>> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
>> >> >>> index fbf215ecc7d0..5da80e1e1727 100644
>> >> >>> --- a/arch/arm64/mm/init.c
>> >> >>> +++ b/arch/arm64/mm/init.c
>> >> >>> @@ -172,7 +172,8 @@ int pfn_is_map_memory(unsigned long pfn)
>> >> >>> if (PHYS_PFN(addr) != pfn)
>> >> >>> return 0;
>> >> >>>
>> >> >>> - return memblock_is_map_memory(addr);
>> >> >>> + return memblock_is_region_memory(addr, PAGE_SIZE) &&
>> >> >>> + memblock_is_map_memory(addr);
>> >> >>> }
>> >> >>> EXPORT_SYMBOL(pfn_is_map_memory);
>> >> >>>
>> >> >> memblock_is_region_memory() only tells you whether the range in
>> >> >> question is covered by a single entry in memblock.memory.regions[].
>> >> >>
>> >> >> memblock has other flags, which may or may not be set on sub-page
>> >> >> regions too. So I don't think this is the right solution in the
>> >> >> general case, even if it fixes your example.
>> >> >>
>> >> >
>> >> > Ack.
>> >> >
>> >> >> Given that the no-map attribute fundamentally only applies to page
>> >> >> granular regions, it would make sense to round those outwards
>> >> >> whenever they are created.
>> >> >>
>> >> >> --- a/mm/memblock.c
>> >> >> +++ b/mm/memblock.c
>> >> >> @@ -1119,6 +1119,10 @@
>> >> >> int __init_memblock memblock_mark_nomap(phys_addr_t base, phys_addr_t size)
>> >> >> {
>> >> >> + phys_addr_t end = PAGE_ALIGN(base + size);
>> >> >> +
>> >> >> + base &= PAGE_MASK;
>> >> >> + size = end - base;
>> >> >> return memblock_setclr_flag(&memblock.memory, base, size, 1, MEMBLOCK_NOMAP);
>> >> >> }
>> >> >>
>> >> >>
>> >> >
>> >> > Should the same be applied to memblock_clear_nomap()?
>> >> >
>> >>
>> >> Yes.
>> >>
>> >> > This is indeed much nicer way to fix the problem! Now, when no-map is
>> >> > rounded outwards, do we still need 7ace06a01efa?
>> >> >
>> >>
>> >> Probably not, but there are some corner cases to consider before we
>> >> go down this route:
>> >> - what happens when marking a range no-map where the outward rounding
>> >> would exceed the limits of the existing memblock memory range?
>> >> - what happens when removing a non-page aligned region from memblock
>> >> that intersects with a (page aligned) no-map region?
>> >
>> > Another thing is that maybe we should force memblock.memory only to page
>> > aligned ranges. x86 uses memblock_trim_memory() for that since, like,
>> > forever.
>> >
>>
>> Interesting. It would make sense to do the same on arm64.
>>
>> But if a NOMAP region ends in the middle of a page, that code will trim on
>> both sides, and throw away the shared page entirely.
>
> Honestly, I think the whole sub-page NOMAP is firmware's problem.
Not entirely. The firmware does not know whether the OS will use 4k pages
or 64k pages, and rounding up all reservations to 64k just in case might
be wasteful.
So I think it is reasonable to require 4k alignment for NOMAP regions,
and the OS should decide whether to round outward or not. It does mean
that the firmware should avoid treating the misaligned pieces at the
edges as memory where it can place things like initrd etc.
> While
> rounding up in _mark_nomap() makes sense because we cannot "not map" a
> sub-page range, I would add a big fat WARN_ON("FIX YOUR FIRMWARE") if the
> rounding actually happens.
>
I don't think that is very productive for 4k -> 64k rounding.
> As for the trimming on arm64, I believe that's relevant, because again, we
> cannot really work with sub-page ranges in memblock.memory and they are
> anyway discarded by for_each_mem_pfn_range() that's used all over mm
> initialization.
>
Yeah I think the rounding is needed in any case, but I don't think it is
the firmware's job to mark unrelated adjacent memory as no-map only because
the OS might decide to use a coarser granule.
next prev parent reply other threads:[~2026-09-24 10:59 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-08 16:20 [PATCH] arm64: mm: Fix pfn_is_map_memory() misreporting mapped memory Vladimir Murzin
2026-09-09 13:31 ` Will Deacon
2026-09-10 13:57 ` Vladimir Murzin
2026-09-11 12:35 ` Will Deacon
2026-09-16 10:13 ` Ard Biesheuvel
2026-09-17 9:42 ` Mike Rapoport
2026-09-17 12:26 ` Vladimir Murzin
2026-09-17 12:34 ` Ard Biesheuvel
2026-09-17 13:13 ` Mike Rapoport
2026-09-17 14:29 ` Mike Rapoport
2026-09-17 15:17 ` Ard Biesheuvel
2026-09-22 5:50 ` Mike Rapoport
2026-09-24 10:59 ` Ard Biesheuvel [this message]
2026-09-24 17:06 ` Mike Rapoport
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=7a6793e4-b2ef-46e0-a068-9166d3f10ea3@app.fastmail.com \
--to=ardb@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=liulhong617@gmail.com \
--cc=rppt@kernel.org \
--cc=vladimir.murzin@arm.com \
--cc=will@kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox