Index: sys/security/mac/mac_process.c =================================================================== --- sys/security/mac/mac_process.c +++ sys/security/mac/mac_process.c @@ -252,7 +252,7 @@ mac_proc_vm_revoke_recurse(struct thread *td, struct ucred *cred, struct vm_map *map) { - vm_map_entry_t vme; + vm_map_entry_t prev, vme; int result; vm_prot_t revokeperms; vm_object_t backing_object, object; @@ -263,8 +263,10 @@ if (!mac_mmap_revocation) return; + prev = &map->header; vm_map_lock(map); - VM_MAP_ENTRY_FOREACH(vme, map) { + for (vme = vm_map_entry_first(map); vme != &map->header; + prev = vme, vme = vm_map_entry_succ(prev)) { if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { mac_proc_vm_revoke_recurse(td, cred, vme->object.sub_map); @@ -363,8 +365,7 @@ } pmap_protect(map->pmap, vme->start, vme->end, vme->protection & ~revokeperms); - vm_map_try_merge_entries(map, vm_map_entry_pred(vme), - vme); + vm_map_try_merge_entries(map, prev, vme); } } vm_map_unlock(map); Index: sys/vm/vm_map.h =================================================================== --- sys/vm/vm_map.h +++ sys/vm/vm_map.h @@ -421,21 +421,20 @@ boolean_t vm_map_lookup_entry (vm_map_t, vm_offset_t, vm_map_entry_t *); static inline vm_map_entry_t -vm_map_entry_succ(vm_map_entry_t entry) +vm_map_entry_first(vm_map_t map) { - - return (entry->next); + return map->header.next; } static inline vm_map_entry_t -vm_map_entry_pred(vm_map_entry_t entry) +vm_map_entry_succ(vm_map_entry_t entry) { - return (entry->prev); + return (entry->next); } -#define VM_MAP_ENTRY_FOREACH(it, map) \ - for ((it) = (map)->header.next; \ +#define VM_MAP_ENTRY_FOREACH(it, map) \ + for ((it) = vm_map_entry_first(map); \ (it) != &(map)->header; \ (it) = vm_map_entry_succ(it)) int vm_map_protect (vm_map_t, vm_offset_t, vm_offset_t, vm_prot_t, boolean_t); Index: sys/vm/vm_map.c =================================================================== --- sys/vm/vm_map.c +++ sys/vm/vm_map.c @@ -977,6 +977,22 @@ root->right->max_free : right_ancestor->start - root->end); } +/* + * vm_map_entry_{pred,succ}: + * + * Find the {predecessor, successor} of the entry by taking one step + * in the appropriate direction and backtracking as much as necessary. + */ + +/* vm_map_entry_succ is defined in vm_map.h. */ + +static inline vm_map_entry_t +vm_map_entry_pred(vm_map_entry_t entry) +{ + + return (entry->prev); +} + #define SPLAY_LEFT_STEP(root, y, rlist, test) do { \ vm_size_t max_free; \ \ @@ -1411,7 +1427,7 @@ vm_map_insert(vm_map_t map, vm_object_t object, vm_ooffset_t offset, vm_offset_t start, vm_offset_t end, vm_prot_t prot, vm_prot_t max, int cow) { - vm_map_entry_t new_entry, prev_entry; + vm_map_entry_t new_entry, prev_entry, next_entry; struct ucred *cred; vm_eflags_t protoeflags; vm_inherit_t inheritance; @@ -1442,7 +1458,8 @@ /* * Assert that the next entry doesn't overlap the end point. */ - if (vm_map_entry_succ(prev_entry)->start < end) + next_entry = vm_map_entry_succ(prev_entry); + if (next_entry->start < end) return (KERN_NO_SPACE); if ((cow & MAP_CREATE_GUARD) != 0 && (object != NULL || @@ -1535,8 +1552,7 @@ map->size += end - prev_entry->end; vm_map_entry_resize(map, prev_entry, end - prev_entry->end); - vm_map_try_merge_entries(map, prev_entry, - vm_map_entry_succ(prev_entry)); + vm_map_try_merge_entries(map, prev_entry, next_entry); return (KERN_SUCCESS); } @@ -1597,7 +1613,7 @@ * other cases, which are less common. */ vm_map_try_merge_entries(map, prev_entry, new_entry); - vm_map_try_merge_entries(map, new_entry, vm_map_entry_succ(new_entry)); + vm_map_try_merge_entries(map, new_entry, next_entry); if ((cow & (MAP_PREFAULT | MAP_PREFAULT_PARTIAL)) != 0) { vm_map_pmap_enter(map, start, prot, object, OFF_TO_IDX(offset), @@ -2554,9 +2570,11 @@ * Otherwise, just simplify entries, since some may have been modified. * [Note that clipping is not necessary the second time.] */ - for (current = entry; current->start < end; - vm_map_try_merge_entries(map, vm_map_entry_pred(current), current), - current = vm_map_entry_succ(current)) { + for (current = entry, entry = vm_map_entry_pred(current); + current->start < end; + (vm_map_try_merge_entries(map, entry, current), + entry = current, + current = vm_map_entry_succ(current))) { if (rv != KERN_SUCCESS || (current->eflags & MAP_ENTRY_GUARD) != 0) continue; @@ -2594,7 +2612,7 @@ #undef MASK } } - vm_map_try_merge_entries(map, vm_map_entry_pred(current), current); + vm_map_try_merge_entries(map, entry, current); vm_map_unlock(map); return (rv); } @@ -2654,10 +2672,14 @@ VM_MAP_RANGE_CHECK(map, start, end); if (vm_map_lookup_entry(map, start, &entry)) { - if (modify_map) + if (modify_map) { vm_map_clip_start(map, entry, start); + current = entry; + entry = vm_map_entry_pred(current); + } else + current = entry; } else { - entry = vm_map_entry_succ(entry); + current = vm_map_entry_succ(entry); } if (modify_map) { @@ -2667,8 +2689,8 @@ * We clip the vm_map_entry so that behavioral changes are * limited to the specified address range. */ - for (current = entry; current->start < end; - current = vm_map_entry_succ(current)) { + for (; current->start < end; + entry = current, current = vm_map_entry_succ(current)) { if (current->eflags & MAP_ENTRY_IS_SUB_MAP) continue; @@ -2699,11 +2721,9 @@ default: break; } - vm_map_try_merge_entries(map, - vm_map_entry_pred(current), current); + vm_map_try_merge_entries(map, entry, current); } - vm_map_try_merge_entries(map, vm_map_entry_pred(current), - current); + vm_map_try_merge_entries(map, entry, current); vm_map_unlock(map); } else { vm_pindex_t pstart, pend; @@ -2715,7 +2735,7 @@ * Since we don't clip the vm_map_entry, we have to clip * the vm_object pindex and count. */ - for (current = entry; current->start < end; + for (; current->start < end; current = vm_map_entry_succ(current)) { vm_offset_t useEnd, useStart; @@ -2822,6 +2842,7 @@ if (vm_map_lookup_entry(map, start, &temp_entry)) { entry = temp_entry; vm_map_clip_start(map, entry, start); + temp_entry = vm_map_entry_pred(entry); } else entry = vm_map_entry_succ(temp_entry); while (entry->start < end) { @@ -2829,10 +2850,11 @@ if ((entry->eflags & MAP_ENTRY_GUARD) == 0 || new_inheritance != VM_INHERIT_ZERO) entry->inheritance = new_inheritance; - vm_map_try_merge_entries(map, vm_map_entry_pred(entry), entry); + vm_map_try_merge_entries(map, temp_entry, entry); + temp_entry = entry; entry = vm_map_entry_succ(entry); } - vm_map_try_merge_entries(map, vm_map_entry_pred(entry), entry); + vm_map_try_merge_entries(map, temp_entry, entry); vm_map_unlock(map); return (KERN_SUCCESS); } @@ -2895,7 +2917,7 @@ vm_map_unwire(vm_map_t map, vm_offset_t start, vm_offset_t end, int flags) { - vm_map_entry_t entry, first_entry; + vm_map_entry_t entry, first_entry, next_entry; int rv; bool first_iteration, holes_ok, need_wakeup, user_unwire; @@ -2946,13 +2968,13 @@ ("owned map entry %p", entry)); entry->eflags |= MAP_ENTRY_IN_TRANSITION; entry->wiring_thread = curthread; + next_entry = vm_map_entry_succ(entry); /* * Check the map for holes in the specified region. * If holes_ok, skip this check. */ if (!holes_ok && - (entry->end < end && - vm_map_entry_succ(entry)->start > entry->end)) { + (entry->end < end && next_entry->start > entry->end)) { end = entry->end; rv = KERN_INVALID_ADDRESS; break; @@ -2966,16 +2988,19 @@ rv = KERN_INVALID_ARGUMENT; break; } - entry = vm_map_entry_succ(entry); + entry = next_entry; } need_wakeup = false; if (first_entry == NULL && !vm_map_lookup_entry(map, start, &first_entry)) { KASSERT(holes_ok, ("vm_map_unwire: lookup failed")); - first_entry = vm_map_entry_succ(first_entry); + entry = vm_map_entry_succ(first_entry); + } else { + entry = first_entry; + first_entry = vm_map_entry_pred(entry); } - for (entry = first_entry; entry->start < end; - entry = vm_map_entry_succ(entry)) { + for (; entry->start < end; + first_entry = entry, entry = vm_map_entry_succ(entry)) { /* * If holes_ok was specified, an empty * space in the unwired region could have been mapped @@ -3011,9 +3036,9 @@ entry->eflags &= ~MAP_ENTRY_NEEDS_WAKEUP; need_wakeup = true; } - vm_map_try_merge_entries(map, vm_map_entry_pred(entry), entry); + vm_map_try_merge_entries(map, first_entry, entry); } - vm_map_try_merge_entries(map, vm_map_entry_pred(entry), entry); + vm_map_try_merge_entries(map, first_entry, entry); vm_map_unlock(map); if (need_wakeup) vm_map_wakeup(map); @@ -3241,14 +3266,14 @@ * Check the map for holes in the specified region. * If holes_ok was specified, skip this check. */ + tmp_entry = vm_map_entry_succ(entry); if (!holes_ok && - entry->end < end && - vm_map_entry_succ(entry)->start > entry->end) { + entry->end < end && tmp_entry->start > entry->end) { end = entry->end; rv = KERN_INVALID_ADDRESS; goto done; } - entry = vm_map_entry_succ(entry); + entry = tmp_entry; } rv = KERN_SUCCESS; done: @@ -3256,10 +3281,13 @@ if (first_entry == NULL && !vm_map_lookup_entry(map, start, &first_entry)) { KASSERT(holes_ok, ("vm_map_wire: lookup failed")); - first_entry = vm_map_entry_succ(first_entry); + entry = vm_map_entry_succ(first_entry); + } else { + entry = first_entry; + first_entry = vm_map_entry_pred(entry); } - for (entry = first_entry; entry->start < end; - entry = vm_map_entry_succ(entry)) { + for (; entry->start < end; + first_entry = entry, entry = vm_map_entry_succ(entry)) { /* * If holes_ok was specified, an empty * space in the unwired region could have been mapped @@ -3312,9 +3340,9 @@ entry->eflags &= ~MAP_ENTRY_NEEDS_WAKEUP; need_wakeup = true; } - vm_map_try_merge_entries(map, vm_map_entry_pred(entry), entry); + vm_map_try_merge_entries(map, first_entry, entry); } - vm_map_try_merge_entries(map, vm_map_entry_pred(entry), entry); + vm_map_try_merge_entries(map, first_entry, entry); if (need_wakeup) vm_map_wakeup(map); return (rv); @@ -3344,8 +3372,7 @@ boolean_t syncio, boolean_t invalidate) { - vm_map_entry_t current; - vm_map_entry_t entry; + vm_map_entry_t current, entry, next; vm_size_t size; vm_object_t object; vm_ooffset_t offset; @@ -3364,14 +3391,14 @@ /* * Make a first pass to check for user-wired memory and holes. */ - for (current = entry; current->start < end; - current = vm_map_entry_succ(current)) { + for (current = entry; current->start < end; current = next) { if (invalidate && (current->eflags & MAP_ENTRY_USER_WIRED)) { vm_map_unlock_read(map); return (KERN_INVALID_ARGUMENT); } + next = vm_map_entry_succ(current); if (end > current->end && - current->end != vm_map_entry_succ(current)->start) { + current->end != next->start) { vm_map_unlock_read(map); return (KERN_INVALID_ADDRESS); }