Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] mm: page_ext: validate section in for_each_page_ext iterator
@ 2026-06-17 15:09 Ketan
  2026-06-17 15:52 ` Zi Yan
  2026-06-18  9:04 ` David Hildenbrand (Arm)
  0 siblings, 2 replies; 10+ messages in thread
From: Ketan @ 2026-06-17 15:09 UTC (permalink / raw)
  To: Andrew Morton, Vlastimil Babka, Suren Baghdasaryan, Michal Hocko,
	Brendan Jackman, Johannes Weiner, Zi Yan, Luiz Capitulino,
	David Hildenbrand
  Cc: kernel, linux-mm, linux-kernel, Ketan Kishore

The page_ext iteration API do not validate if the PFN still
belongs to a valid section while advancing the iterator.

When dynamically adding memory in hotplug path, it can lead
to a NULL pointer dereference during page_ext_lookup at the
boundary of the last valid section.

[   14.555124][  T846] Call trace:
[   14.555125][  T846]  lookup_page_ext+0x6c/0x108 (P)
[   14.555127][  T846]  page_ext_lookup+0x30/0x3c
[   14.555129][  T846]  __reset_page_owner+0x11c/0x260
[   14.571201][  T846]  __free_pages_ok+0x5e8/0x8e0
[   14.571204][  T846]  __free_pages_core+0x78/0xf0
[   14.571206][  T846]  generic_online_page+0x14/0x24
[   14.597782][  T846]  online_pages+0x178/0x30c
[   14.597784][  T846]  memory_block_change_state+0x284/0x32c
[   14.597787][  T846]  memory_subsys_online+0x4c/0x64
[   14.597789][  T846]  device_online+0x88/0xb0
[   14.597791][  T846]  online_memory_block+0x30/0x40
[   14.597793][  T846]  walk_memory_blocks+0xac/0xe8
[   14.597794][  T846]  add_memory_resource+0x280/0x298
[   14.656161][  T846]  add_memory+0x60/0x98

Add a valid-section check before looking up the next page_ext
so the iterator stops cleanly at section boundaries.

Fixes: 9039b9096ea2 ("mm: page_owner: use new iteration API")
Signed-off-by: Ketan Kishore <ketan.kishore@oss.qualcomm.com>
---
 mm/page_ext.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/mm/page_ext.c b/mm/page_ext.c
index e2e92bd27ebd..74067ea740fe 100644
--- a/mm/page_ext.c
+++ b/mm/page_ext.c
@@ -253,6 +253,18 @@ static struct page_ext *lookup_page_ext(const struct page *page)
 {
 	unsigned long pfn = page_to_pfn(page);
 	struct mem_section *section = __pfn_to_section(pfn);
+
+	/*
+	 * section can be NULL when the page_ext iterator's for-loop increment
+	 * computes a PFN one step beyond the last registered section. This
+	 * occurs because pfn_to_page() uses __nr_to_section() which succeeds
+	 * for unregistered sections that share a root array with registered
+	 * sections,while __pfn_to_section() returns NULL for them.
+	 *
+	 */
+	if (!section)
+		return NULL;
+
 	struct page_ext *page_ext = READ_ONCE(section->page_ext);
 
 	WARN_ON_ONCE(!rcu_read_lock_held());

---
base-commit: c425609d6ac4012c8bbf01ec2e10e801b1923a7b
change-id: 20260616-page_ext-31ef555456fc

Best regards,
--  
Ketan Kishore <ketan.kishore@oss.qualcomm.com>



^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-06-19 20:44 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-17 15:09 [PATCH] mm: page_ext: validate section in for_each_page_ext iterator Ketan
2026-06-17 15:52 ` Zi Yan
2026-06-18  9:04 ` David Hildenbrand (Arm)
2026-06-19  2:38   ` Luiz Capitulino
2026-06-19  8:00     ` David Hildenbrand (Arm)
2026-06-19 13:38       ` Matthew Wilcox
2026-06-19 13:45         ` David Hildenbrand (Arm)
2026-06-19 20:44         ` Ketan Kishore
2026-06-19 20:36       ` Ketan Kishore
2026-06-19 20:31     ` Ketan Kishore

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox