[PATCH] arm64: mm: Fix pfn_is_map_memory() misreporting mapped memory

Ard Biesheuvel ardb at kernel.org
Thu Sep 17 08:17:45 PDT 2026



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 at 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. So all flag manipulation
occurring beforehand should be rounded outward (not just NOMAP, although I'm
not sure if there are others that may get set on non-page granular regions)







More information about the linux-arm-kernel mailing list