* [PATCH v2] arm64/mm: Check the requested PFN range during memory removal
@ 2026-07-21 10:00 Richard Cheng
2026-07-21 10:15 ` sashiko-bot
2026-07-21 17:18 ` Will Deacon
0 siblings, 2 replies; 3+ messages in thread
From: Richard Cheng @ 2026-07-21 10:00 UTC (permalink / raw)
To: catalin.marinas, will, jic23
Cc: ryan.roberts, ardb, kevin.brodsky, anshuman.khandual, yang,
chaitanyas.prakash, linux-arm-kernel, linux-kernel, linux-cxl,
newtonl, kristinc, mochs, kaihengf, kobak, Richard Cheng
prevent_memory_remove_notifier() advances pfn while scanning the requested
range for early memory. When the loop completes, pfn is at or beyond
end_pfn. Passing it to can_unmap_without_split() therefore checks a range
after the one being offlined.
Consequently, a valid request can be rejected based on the following
range, while a request that would split a leaf mapping can be accepted if
the shifted range can be unmapped without a split. This was observed with
CXL DAX memory, where the final memory block was incorrectly allowed to
be offlined.
Pass arg->start_pfn into can_unmap_without_split() so it checks the
requested range.
Fixes: 95a58852b0e5 ("arm64/mm: Reject memory removal that splits a kernel leaf mapping")
Signed-off-by: Richard Cheng <icheng@nvidia.com>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
Changelog:
V1->v2:
- Fix the typo in the subject
- Clarify how pfn advances and which range was incorrectly checked
The bug occurred on a machine with CXL Type-3 device.
Branch: cxl-next
Before 95a58852b0e5:
"""
$ sudo echo offline > memory557056/state
write error: Operation not permitted
$ sudo dmesg
---[snip]---
[440008000000 440010000000] splits a leaf entry in linear map
$ sudo echo offline > memory558079/state
$ cat memory558079/state
offline
"""
After:
"""
$ sudo echo offline > memory557056/state
write error: Operation not permitted
[440000000000 440008000000] splits a leaf entry in linear map
$ sudo echo offline > memory558079/state
write error: Operation not permitted
[441ff8000000 442000000000] splits a leaf entry in linear map
"""
My fix corrects the checked range and prevents the false acceptance.
Best regards,
Richard Cheng.
---
arch/arm64/mm/mmu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index a25d8beacc83..18a8b0d3714e 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -2194,7 +2194,7 @@ static int prevent_memory_remove_notifier(struct notifier_block *nb,
}
}
- if (!can_unmap_without_split(pfn, arg->nr_pages))
+ if (!can_unmap_without_split(arg->start_pfn, arg->nr_pages))
return NOTIFY_BAD;
return NOTIFY_OK;
base-commit: 5ca04f3ba91f1773bbd5da6d9c654ccc1ba7831d
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v2] arm64/mm: Check the requested PFN range during memory removal
2026-07-21 10:00 [PATCH v2] arm64/mm: Check the requested PFN range during memory removal Richard Cheng
@ 2026-07-21 10:15 ` sashiko-bot
2026-07-21 17:18 ` Will Deacon
1 sibling, 0 replies; 3+ messages in thread
From: sashiko-bot @ 2026-07-21 10:15 UTC (permalink / raw)
To: Richard Cheng; +Cc: linux-cxl
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] The lockless page table walk in `addr_splits_kernel_leaf` dereferences shared PUD and PMD pointers without `READ_ONCE()`, violating ARM64 subsystem rules.
--
--- Patch [1]: [PATCH v2] arm64/mm: Check the requested PFN range during memory removal ---
commit bacbc9fb9b238d0e34546abe25a64655eea1704f
Author: Richard Cheng <icheng@nvidia.com>
arm64/mm: Check the requested PFN range during memory removal
This commit fixes the memory removal notifier to check the correct
requested PFN range rather than the range following it. It does this
by passing arg->start_pfn into can_unmap_without_split() instead of
the already advanced pfn variable.
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index a25d8beacc831..18a8b0d3714ee 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
[ ... ]
> @@ -2194,7 +2194,7 @@ static int prevent_memory_remove_notifier(struct notifier_block *nb,
> }
> }
>
> - if (!can_unmap_without_split(pfn, arg->nr_pages))
> + if (!can_unmap_without_split(arg->start_pfn, arg->nr_pages))
[Severity: High]
This is a pre-existing issue, but does the page table walk in
addr_splits_kernel_leaf() (called by can_unmap_without_split() here) need
to use READ_ONCE() for its shared pointer dereferences?
Looking at addr_splits_kernel_leaf(), it performs a lockless walk of the
kernel page tables. It passes pudp to pmd_offset() and pmdp to
pte_offset_kernel():
arch/arm64/mm/mmu.c:addr_splits_kernel_leaf() {
...
pmdp = pmd_offset(pudp, addr);
pmd = pmdp_get(pmdp);
...
ptep = pte_offset_kernel(pmdp, addr);
pte = __ptep_get(ptep);
...
}
On arm64, the generic implementations of pmd_offset() and
pte_offset_kernel() perform plain loads instead of using READ_ONCE().
If there is a concurrent modification of the kernel page tables (such as a
split of a linear map huge page triggered by secretmem), could the compiler
observe a torn or stale pointer here?
Dereferencing this through pmdp_get() or __ptep_get() might result in
accessing a bogus physical address and causing a kernel panic.
> return NOTIFY_BAD;
>
> return NOTIFY_OK;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260721100026.10408-1-icheng@nvidia.com?part=1
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v2] arm64/mm: Check the requested PFN range during memory removal
2026-07-21 10:00 [PATCH v2] arm64/mm: Check the requested PFN range during memory removal Richard Cheng
2026-07-21 10:15 ` sashiko-bot
@ 2026-07-21 17:18 ` Will Deacon
1 sibling, 0 replies; 3+ messages in thread
From: Will Deacon @ 2026-07-21 17:18 UTC (permalink / raw)
To: catalin.marinas, jic23, Richard Cheng
Cc: kernel-team, Will Deacon, ryan.roberts, ardb, kevin.brodsky,
anshuman.khandual, yang, chaitanyas.prakash, linux-arm-kernel,
linux-kernel, linux-cxl, newtonl, kristinc, mochs, kaihengf,
kobak
On Tue, 21 Jul 2026 18:00:26 +0800, Richard Cheng wrote:
> prevent_memory_remove_notifier() advances pfn while scanning the requested
> range for early memory. When the loop completes, pfn is at or beyond
> end_pfn. Passing it to can_unmap_without_split() therefore checks a range
> after the one being offlined.
>
> Consequently, a valid request can be rejected based on the following
> range, while a request that would split a leaf mapping can be accepted if
> the shifted range can be unmapped without a split. This was observed with
> CXL DAX memory, where the final memory block was incorrectly allowed to
> be offlined.
>
> [...]
Applied to arm64 (for-next/fixes), thanks!
[1/1] arm64/mm: Check the requested PFN range during memory removal
https://git.kernel.org/arm64/c/285f90a4d1141
Cheers,
--
Will
https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-07-21 17:19 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-21 10:00 [PATCH v2] arm64/mm: Check the requested PFN range during memory removal Richard Cheng
2026-07-21 10:15 ` sashiko-bot
2026-07-21 17:18 ` Will Deacon
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.