[LTP] [PATCH] mm: extpand queue_pages_range() to find and lock the vma range

Edward AD eadavis@sina.com
Thu Sep 14 07:53:13 CEST 2023


Using for_each_vma_range to find vmas, and not only inside locking, but also 
outside locking to ensure that vma_start_write are performed.

Reported-and-tested-by: syzbot+b591856e0f0139f83023@syzkaller.appspotmail.com
Signed-off-by: Edward AD <eadavis@sina.com>
---
 mm/pagewalk.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/mm/pagewalk.c b/mm/pagewalk.c
index b7d7e4fcfad7..b31d59a27f57 100644
--- a/mm/pagewalk.c
+++ b/mm/pagewalk.c
@@ -479,6 +479,7 @@ int walk_page_range(struct mm_struct *mm, unsigned long start,
 		.mm		= mm,
 		.private	= private,
 	};
+	struct vma_iterator vmi;
 
 	if (start >= end)
 		return -EINVAL;
@@ -488,8 +489,9 @@ int walk_page_range(struct mm_struct *mm, unsigned long start,
 
 	process_mm_walk_lock(walk.mm, ops->walk_lock);
 
-	vma = find_vma(walk.mm, start);
-	do {
+	vma_iter_init(&vmi, walk.mm, start);
+	for_each_vma_range(vmi, vma, end) {
+		process_vma_walk_lock(vma, ops->walk_lock);
 		if (!vma) { /* after the last vma */
 			walk.vma = NULL;
 			next = end;
@@ -501,10 +503,8 @@ int walk_page_range(struct mm_struct *mm, unsigned long start,
 			if (ops->pte_hole)
 				err = ops->pte_hole(start, next, -1, &walk);
 		} else { /* inside vma */
-			process_vma_walk_lock(vma, ops->walk_lock);
 			walk.vma = vma;
 			next = min(end, vma->vm_end);
-			vma = find_vma(mm, vma->vm_end);
 
 			err = walk_page_test(start, next, &walk);
 			if (err > 0) {
@@ -522,7 +522,7 @@ int walk_page_range(struct mm_struct *mm, unsigned long start,
 		}
 		if (err)
 			break;
-	} while (start = next, start < end);
+	};
 	return err;
 }
 
-- 
2.25.1



More information about the ltp mailing list