linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 6.1] mm/hugetlb: fix assertion splat in hugetlb_split()
@ 2025-07-08 12:47 Fedor Pchelkin
  0 siblings, 0 replies; only message in thread
From: Fedor Pchelkin @ 2025-07-08 12:47 UTC (permalink / raw)
  To: stable
  Cc: Fedor Pchelkin, Greg Kroah-Hartman, Andrew Morton,
	Oscar Salvador, Lorenzo Stoakes, Jann Horn, linux-mm,
	lvc-project, Muchun Song, Liam R. Howlett, Vlastimil Babka,
	Pedro Falcato

No upstream commit exists for this patch.

The following assertion is firing on 5.10 to 6.1 stable kernels after
backport of upstream commit 081056dc00a2 ("mm/hugetlb: unshare page tables
during VMA split, not before"):

  WARNING: CPU: 0 PID: 11489 at include/linux/fs.h:503 i_mmap_assert_write_locked include/linux/fs.h:503 [inline]
  WARNING: CPU: 0 PID: 11489 at include/linux/fs.h:503 hugetlb_split+0x267/0x300 mm/hugetlb.c:4917
  Modules linked in:
  CPU: 0 PID: 11489 Comm: syz-executor.4 Not tainted 6.1.142-syzkaller-00296-gfd0df5221577 #0
  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
  RIP: 0010:i_mmap_assert_write_locked include/linux/fs.h:503 [inline]
  RIP: 0010:hugetlb_split+0x267/0x300 mm/hugetlb.c:4917
  Call Trace:
   <TASK>
   __vma_adjust+0xd73/0x1c10 mm/mmap.c:736
   vma_adjust include/linux/mm.h:2745 [inline]
   __split_vma+0x459/0x540 mm/mmap.c:2385
   do_mas_align_munmap+0x5f2/0xf10 mm/mmap.c:2497
   do_mas_munmap+0x26c/0x2c0 mm/mmap.c:2646
   __mmap_region mm/mmap.c:2694 [inline]
   mmap_region+0x19f/0x1770 mm/mmap.c:2912
   do_mmap+0x84b/0xf20 mm/mmap.c:1432
   vm_mmap_pgoff+0x1af/0x280 mm/util.c:520
   ksys_mmap_pgoff+0x41f/0x5a0 mm/mmap.c:1478
   do_syscall_x64 arch/x86/entry/common.c:51 [inline]
   do_syscall_64+0x35/0x80 arch/x86/entry/common.c:81
   entry_SYSCALL_64_after_hwframe+0x6e/0xd8
  RIP: 0033:0x46a269
   </TASK>

Those branches lack commit ccf1d78d8b86 ("mm/mmap: move vma_prepare before
vma_adjust_trans_huge") so the needed locks are taken just after the newly
added hugetlb_split().

Adjust the position of vma_adjust_trans_huge() blocks with the lock-taking
code.

Found by Linux Verification Center (linuxtesting.org) with Syzkaller.

Fixes: 081056dc00a2 ("mm/hugetlb: unshare page tables during VMA split, not before")
Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
---

Tested with testcases/kernel/mem/hugetlb/hugemmap suite provided by LTP.

For the report see:
https://lore.kernel.org/stable/CAG48ez3LqUwXxhRY56tqQCpfGJsJ-GeXFG9FCcTZEBo2bWOK8Q@mail.gmail.com/T/#u

 mm/mmap.c | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/mm/mmap.c b/mm/mmap.c
index 0f303dc8425a..941880ed62d7 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -543,8 +543,6 @@ inline int vma_expand(struct ma_state *mas, struct vm_area_struct *vma,
 	if (mas_preallocate(mas, vma, GFP_KERNEL))
 		goto nomem;
 
-	vma_adjust_trans_huge(vma, start, end, 0);
-
 	if (file) {
 		mapping = file->f_mapping;
 		root = &mapping->i_mmap;
@@ -562,6 +560,8 @@ inline int vma_expand(struct ma_state *mas, struct vm_area_struct *vma,
 		vma_interval_tree_remove(vma, root);
 	}
 
+	vma_adjust_trans_huge(vma, start, end, 0);
+
 	vma->vm_start = start;
 	vma->vm_end = end;
 	vma->vm_pgoff = pgoff;
@@ -727,15 +727,6 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
 		return -ENOMEM;
 	}
 
-	/*
-	 * Get rid of huge pages and shared page tables straddling the split
-	 * boundary.
-	 */
-	vma_adjust_trans_huge(orig_vma, start, end, adjust_next);
-	if (is_vm_hugetlb_page(orig_vma)) {
-		hugetlb_split(orig_vma, start);
-		hugetlb_split(orig_vma, end);
-	}
 	if (file) {
 		mapping = file->f_mapping;
 		root = &mapping->i_mmap;
@@ -775,6 +766,16 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
 			vma_interval_tree_remove(next, root);
 	}
 
+	/*
+	 * Get rid of huge pages and shared page tables straddling the split
+	 * boundary.
+	 */
+	vma_adjust_trans_huge(orig_vma, start, end, adjust_next);
+	if (is_vm_hugetlb_page(orig_vma)) {
+		hugetlb_split(orig_vma, start);
+		hugetlb_split(orig_vma, end);
+	}
+
 	if (start != vma->vm_start) {
 		if ((vma->vm_start < start) &&
 		    (!insert || (insert->vm_end != start))) {
-- 
2.50.0



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2025-07-08 12:48 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-07-08 12:47 [PATCH 6.1] mm/hugetlb: fix assertion splat in hugetlb_split() Fedor Pchelkin

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