Index: sys/amd64/amd64/pmap.c =================================================================== --- sys/amd64/amd64/pmap.c +++ sys/amd64/amd64/pmap.c @@ -11448,7 +11448,7 @@ static bool pmap_pkru_same(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) { - struct pmap_pkru_range *ppr, *prev_ppr; + struct pmap_pkru_range *next_ppr, *ppr; vm_offset_t va; PMAP_LOCK_ASSERT(pmap, MA_OWNED); @@ -11457,19 +11457,19 @@ sva >= VM_MAXUSER_ADDRESS) return (true); MPASS(eva <= VM_MAXUSER_ADDRESS); - for (va = sva; va < eva; prev_ppr = ppr) { - ppr = rangeset_lookup(&pmap->pm_pkru, va); - if (va == sva) - prev_ppr = ppr; - else if ((ppr == NULL) ^ (prev_ppr == NULL)) + ppr = rangeset_lookup(&pmap->pm_pkru, sva); + if (ppr == NULL) { + ppr = rangeset_next(&pmap->pm_pkru, sva); + return (ppr == NULL || + ppr->pkru_rs_el.re_start >= eva); + } + while ((va = ppr->pkru_rs_el.re_end) < eva) { + next_ppr = rangeset_next(&pmap->pm_pkru, va); + if (next_ppr == NULL || + va != next_ppr->pkru_rs_el.re_start || + ppr->pkru_keyidx != next_ppr->pkru_keyidx) return (false); - if (ppr == NULL) { - va += PAGE_SIZE; - continue; - } - if (prev_ppr->pkru_keyidx != ppr->pkru_keyidx) - return (false); - va = ppr->pkru_rs_el.re_end; + ppr = next_ppr; } return (true); } Index: sys/arm64/arm64/pmap.c =================================================================== --- sys/arm64/arm64/pmap.c +++ sys/arm64/arm64/pmap.c @@ -9274,7 +9274,7 @@ static bool pmap_bti_same(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) { - struct rs_el *prev_rs, *rs; + struct rs_el *next_rs, *rs; vm_offset_t va; PMAP_LOCK_ASSERT(pmap, MA_OWNED); @@ -9286,17 +9286,18 @@ if (pmap->pm_bti == NULL || ADDR_IS_KERNEL(sva)) return (true); MPASS(!ADDR_IS_KERNEL(eva)); - for (va = sva; va < eva; prev_rs = rs) { - rs = rangeset_lookup(pmap->pm_bti, va); - if (va == sva) - prev_rs = rs; - else if ((rs == NULL) ^ (prev_rs == NULL)) + rs = rangeset_lookup(pmap->pm_bti, sva); + if (rs == NULL) { + rs = rangeset_next(pmap->pm_bti, sva); + return (rs == NULL || + rs->re_start >= eva); + } + while ((va = rs->re_end) < eva) { + next_rs = rangeset_next(pmap->pm_bti, sva); + if (next_rs == NULL || + va != next_rs->re_start) return (false); - if (rs == NULL) { - va += PAGE_SIZE; - continue; - } - va = rs->re_end; + rs = next_rs; } return (true); } Index: sys/kern/subr_rangeset.c =================================================================== --- sys/kern/subr_rangeset.c +++ sys/kern/subr_rangeset.c @@ -260,6 +260,14 @@ return (r); } +void * +rangeset_next(struct rangeset *rs, uint64_t place) +{ + + rangeset_check(rs); + return (RANGESET_PCTRIE_LOOKUP_GE(&rs->rs_trie, place)); +} + int rangeset_copy(struct rangeset *dst_rs, struct rangeset *src_rs) { Index: sys/sys/rangeset.h =================================================================== --- sys/sys/rangeset.h +++ sys/sys/rangeset.h @@ -74,6 +74,11 @@ */ void *rangeset_lookup(struct rangeset *rs, uint64_t place); +/* + * Finds the first range that begins at or after place. + */ +void *rangeset_next(struct rangeset *rs, uint64_t place); + /* * Copies src_rs entries into dst_rs. dst_rs must be empty. * Leaves dst_rs empty on failure.