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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxxxxxxxxxxxxxxx
Signed-off-by: Edward AD <eadavis@xxxxxxxx>
---
 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





[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux