* [PATCH] arm64: mm: Fix pfn_is_map_memory() misreporting mapped memory
@ 2026-09-08 16:20 Vladimir Murzin
2026-09-09 13:31 ` Will Deacon
2026-09-16 10:13 ` Ard Biesheuvel
0 siblings, 2 replies; 14+ messages in thread
From: Vladimir Murzin @ 2026-09-08 16:20 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: catalin.marinas, will, liulhong617
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);
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH] arm64: mm: Fix pfn_is_map_memory() misreporting mapped memory 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-16 10:13 ` Ard Biesheuvel 1 sibling, 1 reply; 14+ messages in thread From: Will Deacon @ 2026-09-09 13:31 UTC (permalink / raw) To: Vladimir Murzin; +Cc: linux-arm-kernel, catalin.marinas, liulhong617, ardb On Tue, Sep 08, 2026 at 05:20:33PM +0100, 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); > } Yuck, this is really grotty :( Can we at least predicate the extra memblock_is_region_memory() check on having a page-size > 4k? Will ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] arm64: mm: Fix pfn_is_map_memory() misreporting mapped memory 2026-09-09 13:31 ` Will Deacon @ 2026-09-10 13:57 ` Vladimir Murzin 2026-09-11 12:35 ` Will Deacon 0 siblings, 1 reply; 14+ messages in thread From: Vladimir Murzin @ 2026-09-10 13:57 UTC (permalink / raw) To: Will Deacon; +Cc: linux-arm-kernel, catalin.marinas, liulhong617, ardb On 9/9/26 14:31, Will Deacon wrote: > On Tue, Sep 08, 2026 at 05:20:33PM +0100, 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); >> } > Yuck, this is really grotty :( > > Can we at least predicate the extra memblock_is_region_memory() check on > having a page-size > 4k? > The same can happen with 4K page size and subpage no-map and I have not seen anything prohibiting subpage no-map ... Cheers Vladimir > Will > ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] arm64: mm: Fix pfn_is_map_memory() misreporting mapped memory 2026-09-10 13:57 ` Vladimir Murzin @ 2026-09-11 12:35 ` Will Deacon 0 siblings, 0 replies; 14+ messages in thread From: Will Deacon @ 2026-09-11 12:35 UTC (permalink / raw) To: Vladimir Murzin; +Cc: linux-arm-kernel, catalin.marinas, liulhong617, ardb On Thu, Sep 10, 2026 at 02:57:25PM +0100, Vladimir Murzin wrote: > On 9/9/26 14:31, Will Deacon wrote: > > On Tue, Sep 08, 2026 at 05:20:33PM +0100, 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); > >> } > > Yuck, this is really grotty :( > > > > Can we at least predicate the extra memblock_is_region_memory() check on > > having a page-size > 4k? > > > > The same can happen with 4K page size and subpage no-map and I have not seen > anything prohibiting subpage no-map ... Ah yes, I made a similar observation during the review of the offending commit. Oh well. Let's see what others think before we merge this. Will ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] arm64: mm: Fix pfn_is_map_memory() misreporting mapped memory 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-16 10:13 ` Ard Biesheuvel 2026-09-17 9:42 ` Mike Rapoport 2026-09-17 12:26 ` Vladimir Murzin 1 sibling, 2 replies; 14+ messages in thread From: Ard Biesheuvel @ 2026-09-16 10:13 UTC (permalink / raw) To: Vladimir Murzin, linux-arm-kernel Cc: Catalin Marinas, Will Deacon, liulhong617, Mike Rapoport (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. 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); } Note that I recently removed the frivolous use of MEMBLOCK_NOMAP in __map_mem() so the remaining calls should mostly be true reservations originating from the boot environment. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] arm64: mm: Fix pfn_is_map_memory() misreporting mapped memory 2026-09-16 10:13 ` Ard Biesheuvel @ 2026-09-17 9:42 ` Mike Rapoport 2026-09-17 12:26 ` Vladimir Murzin 1 sibling, 0 replies; 14+ messages in thread From: Mike Rapoport @ 2026-09-17 9:42 UTC (permalink / raw) To: Ard Biesheuvel Cc: Vladimir Murzin, linux-arm-kernel, Catalin Marinas, Will Deacon, liulhong617 On Wed, Sep 16, 2026 at 12:13:21PM +0200, 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. > > 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); > } Makes sense to me, just lacks kernel-doc update ;-) > Note that I recently removed the frivolous use of MEMBLOCK_NOMAP in > __map_mem() so the remaining calls should mostly be true reservations > originating from the boot environment. There is still riscv :) -- Sincerely yours, Mike. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] arm64: mm: Fix pfn_is_map_memory() misreporting mapped memory 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 1 sibling, 1 reply; 14+ messages in thread From: Vladimir Murzin @ 2026-09-17 12:26 UTC (permalink / raw) To: Ard Biesheuvel, linux-arm-kernel Cc: Catalin Marinas, Will Deacon, liulhong617, Mike Rapoport 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()? This is indeed much nicer way to fix the problem! Now, when no-map is rounded outwards, do we still need 7ace06a01efa? Thanks Vladimir > Note that I recently removed the frivolous use of MEMBLOCK_NOMAP in > __map_mem() so the remaining calls should mostly be true reservations > originating from the boot environment. > > > > > ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] arm64: mm: Fix pfn_is_map_memory() misreporting mapped memory 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 0 siblings, 2 replies; 14+ messages in thread From: Ard Biesheuvel @ 2026-09-17 12:34 UTC (permalink / raw) To: Vladimir Murzin, linux-arm-kernel Cc: Catalin Marinas, Will Deacon, liulhong617, Mike Rapoport 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? ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] arm64: mm: Fix pfn_is_map_memory() misreporting mapped memory 2026-09-17 12:34 ` Ard Biesheuvel @ 2026-09-17 13:13 ` Mike Rapoport 2026-09-17 14:29 ` Mike Rapoport 1 sibling, 0 replies; 14+ messages in thread From: Mike Rapoport @ 2026-09-17 13:13 UTC (permalink / raw) To: Ard Biesheuvel Cc: Vladimir Murzin, linux-arm-kernel, Catalin Marinas, Will Deacon, liulhong617 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? AFAIR it's fine, memblock_isolate will clamp the update. Didn't check the code though. > - what happens when removing a non-page aligned region from memblock > that intersects with a (page aligned) no-map region? It will make the nomap region non-page aligned. -- Sincerely yours, Mike. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] arm64: mm: Fix pfn_is_map_memory() misreporting mapped memory 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 1 sibling, 1 reply; 14+ messages in thread From: Mike Rapoport @ 2026-09-17 14:29 UTC (permalink / raw) To: Ard Biesheuvel Cc: Vladimir Murzin, linux-arm-kernel, Catalin Marinas, Will Deacon, liulhong617 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. -- Sincerely yours, Mike. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] arm64: mm: Fix pfn_is_map_memory() misreporting mapped memory 2026-09-17 14:29 ` Mike Rapoport @ 2026-09-17 15:17 ` Ard Biesheuvel 2026-09-22 5:50 ` Mike Rapoport 0 siblings, 1 reply; 14+ messages in thread From: Ard Biesheuvel @ 2026-09-17 15:17 UTC (permalink / raw) To: Mike Rapoport Cc: Vladimir Murzin, linux-arm-kernel, Catalin Marinas, Will Deacon, liulhong617 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. 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) ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] arm64: mm: Fix pfn_is_map_memory() misreporting mapped memory 2026-09-17 15:17 ` Ard Biesheuvel @ 2026-09-22 5:50 ` Mike Rapoport 2026-09-24 10:59 ` Ard Biesheuvel 0 siblings, 1 reply; 14+ messages in thread From: Mike Rapoport @ 2026-09-22 5:50 UTC (permalink / raw) To: Ard Biesheuvel Cc: Vladimir Murzin, linux-arm-kernel, Catalin Marinas, Will Deacon, liulhong617 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. 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. 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. > 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) Virtually anything, but I don't think any existing caller does that. -- Sincerely yours, Mike. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] arm64: mm: Fix pfn_is_map_memory() misreporting mapped memory 2026-09-22 5:50 ` Mike Rapoport @ 2026-09-24 10:59 ` Ard Biesheuvel 2026-09-24 17:06 ` Mike Rapoport 0 siblings, 1 reply; 14+ messages in thread From: Ard Biesheuvel @ 2026-09-24 10:59 UTC (permalink / raw) To: Mike Rapoport Cc: Vladimir Murzin, linux-arm-kernel, Catalin Marinas, Will Deacon, liulhong617 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. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] arm64: mm: Fix pfn_is_map_memory() misreporting mapped memory 2026-09-24 10:59 ` Ard Biesheuvel @ 2026-09-24 17:06 ` Mike Rapoport 0 siblings, 0 replies; 14+ messages in thread From: Mike Rapoport @ 2026-09-24 17:06 UTC (permalink / raw) To: Ard Biesheuvel Cc: Vladimir Murzin, linux-arm-kernel, Catalin Marinas, Will Deacon, liulhong617 On Thu, Sep 24, 2026 at 12:59:15PM +0200, Ard Biesheuvel wrote: > 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. I keep forgetting about 64k pages :) > 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. I agree that the strict requirement should be for 4k. Or without loss of generality "minimal supported base page size" :) > > 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. I afraid this will create weird edge cases where firmware mixes parts of a 64k pages for no-map and other things at 4k granularity. -- Sincerely yours, Mike. ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2026-09-24 17:06 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 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 2026-09-24 17:06 ` Mike Rapoport
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox