git: 1cce7d86c86a - main - vm_map: fix iterator jump size

From: Doug Moore <dougm_at_FreeBSD.org>
Date: Thu, 24 Apr 2025 15:49:40 UTC
The branch main has been updated by dougm:

URL: https://cgit.FreeBSD.org/src/commit/?id=1cce7d86c86ae690d6f1d8120811792bb65e95cc

commit 1cce7d86c86ae690d6f1d8120811792bb65e95cc
Author:     Doug Moore <dougm@FreeBSD.org>
AuthorDate: 2025-04-24 15:47:41 +0000
Commit:     Doug Moore <dougm@FreeBSD.org>
CommitDate: 2025-04-24 15:47:41 +0000

    vm_map: fix iterator jump size
    
    The index value in the loop in vm_map_pmap_enter jumps by 1, or some
    superpage size, in each iteration. Jump by the superpage size only
    when the entire superpage is being mapped.
    
    Reported by:    pho
    Reported-by: syzbot+1cc9ede76727d2ea2e8d@syzkaller.appspotmail.com
    Reviewed by:    alc, kib, markj
    Tested by:      pho
    Fixes:  Fixes: b3d89a0cde94 ("vm_map: use page iterators in pmap_enter")
    Differential Revision:  https://reviews.freebsd.org/D49987
---
 sys/vm/vm_map.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 0371680f6df5..c6182f9ce30f 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -2678,7 +2678,7 @@ vm_map_pmap_enter(vm_map_t map, vm_offset_t addr, vm_prot_t prot,
 	struct pctrie_iter pages;
 	vm_offset_t start;
 	vm_page_t p, p_start;
-	vm_pindex_t mask, psize, threshold, tmpidx;
+	vm_pindex_t jump, mask, psize, threshold, tmpidx;
 	int psind;
 
 	if ((prot & (VM_PROT_READ | VM_PROT_EXECUTE)) == 0 || object == NULL)
@@ -2710,7 +2710,7 @@ vm_map_pmap_enter(vm_map_t map, vm_offset_t addr, vm_prot_t prot,
 
 	vm_page_iter_limit_init(&pages, object, pindex + psize);
 	for (p = vm_radix_iter_lookup_ge(&pages, pindex); p != NULL;
-	    p = vm_radix_iter_jump(&pages, mask + 1)) {
+	    p = vm_radix_iter_jump(&pages, jump)) {
 		/*
 		 * don't allow an madvise to blow away our really
 		 * free pages allocating pv entries.
@@ -2723,7 +2723,7 @@ vm_map_pmap_enter(vm_map_t map, vm_offset_t addr, vm_prot_t prot,
 			psize = tmpidx;
 			break;
 		}
-		mask = 0;
+		jump = 1;
 		if (vm_page_all_valid(p)) {
 			if (p_start == NULL) {
 				start = addr + ptoa(tmpidx);
@@ -2737,6 +2737,7 @@ vm_map_pmap_enter(vm_map_t map, vm_offset_t addr, vm_prot_t prot,
 					if (tmpidx + mask < psize &&
 					    vm_page_ps_test(p, psind,
 					    PS_ALL_VALID, NULL)) {
+						jump += mask;
 						threshold += mask;
 						break;
 					}