Changeset View
Changeset View
Standalone View
Standalone View
head/sys/vm/vm_map.c
Show First 20 Lines • Show All 997 Lines • ▼ Show 20 Lines | vm_map_entry_link(vm_map_t map, | ||||
vm_map_entry_t after_where, | vm_map_entry_t after_where, | ||||
vm_map_entry_t entry) | vm_map_entry_t entry) | ||||
{ | { | ||||
CTR4(KTR_VM, | CTR4(KTR_VM, | ||||
"vm_map_entry_link: map %p, nentries %d, entry %p, after %p", map, | "vm_map_entry_link: map %p, nentries %d, entry %p, after %p", map, | ||||
map->nentries, entry, after_where); | map->nentries, entry, after_where); | ||||
VM_MAP_ASSERT_LOCKED(map); | VM_MAP_ASSERT_LOCKED(map); | ||||
KASSERT(after_where == &map->header || | KASSERT(after_where->end <= entry->start, | ||||
after_where->end <= entry->start, | |||||
("vm_map_entry_link: prev end %jx new start %jx overlap", | ("vm_map_entry_link: prev end %jx new start %jx overlap", | ||||
(uintmax_t)after_where->end, (uintmax_t)entry->start)); | (uintmax_t)after_where->end, (uintmax_t)entry->start)); | ||||
KASSERT(after_where->next == &map->header || | KASSERT(entry->end <= after_where->next->start, | ||||
entry->end <= after_where->next->start, | |||||
("vm_map_entry_link: new end %jx next start %jx overlap", | ("vm_map_entry_link: new end %jx next start %jx overlap", | ||||
(uintmax_t)entry->end, (uintmax_t)after_where->next->start)); | (uintmax_t)entry->end, (uintmax_t)after_where->next->start)); | ||||
map->nentries++; | map->nentries++; | ||||
entry->prev = after_where; | entry->prev = after_where; | ||||
entry->next = after_where->next; | entry->next = after_where->next; | ||||
entry->next->prev = entry; | entry->next->prev = entry; | ||||
after_where->next = entry; | after_where->next = entry; | ||||
if (after_where != &map->header) { | if (after_where != &map->header) { | ||||
if (after_where != map->root) | if (after_where != map->root) | ||||
vm_map_entry_splay(after_where->start, map->root); | vm_map_entry_splay(after_where->start, map->root); | ||||
entry->right = after_where->right; | entry->right = after_where->right; | ||||
entry->left = after_where; | entry->left = after_where; | ||||
after_where->right = NULL; | after_where->right = NULL; | ||||
after_where->adj_free = entry->start - after_where->end; | after_where->adj_free = entry->start - after_where->end; | ||||
vm_map_entry_set_max_free(after_where); | vm_map_entry_set_max_free(after_where); | ||||
} else { | } else { | ||||
entry->right = map->root; | entry->right = map->root; | ||||
entry->left = NULL; | entry->left = NULL; | ||||
} | } | ||||
entry->adj_free = (entry->next == &map->header ? map->max_offset : | entry->adj_free = entry->next->start - entry->end; | ||||
entry->next->start) - entry->end; | |||||
vm_map_entry_set_max_free(entry); | vm_map_entry_set_max_free(entry); | ||||
map->root = entry; | map->root = entry; | ||||
} | } | ||||
static void | static void | ||||
vm_map_entry_unlink(vm_map_t map, | vm_map_entry_unlink(vm_map_t map, | ||||
vm_map_entry_t entry) | vm_map_entry_t entry) | ||||
{ | { | ||||
vm_map_entry_t next, prev, root; | vm_map_entry_t next, prev, root; | ||||
VM_MAP_ASSERT_LOCKED(map); | VM_MAP_ASSERT_LOCKED(map); | ||||
if (entry != map->root) | if (entry != map->root) | ||||
vm_map_entry_splay(entry->start, map->root); | vm_map_entry_splay(entry->start, map->root); | ||||
if (entry->left == NULL) | if (entry->left == NULL) | ||||
root = entry->right; | root = entry->right; | ||||
else { | else { | ||||
root = vm_map_entry_splay(entry->start, entry->left); | root = vm_map_entry_splay(entry->start, entry->left); | ||||
root->right = entry->right; | root->right = entry->right; | ||||
root->adj_free = (entry->next == &map->header ? map->max_offset : | root->adj_free = entry->next->start - root->end; | ||||
entry->next->start) - root->end; | |||||
vm_map_entry_set_max_free(root); | vm_map_entry_set_max_free(root); | ||||
} | } | ||||
map->root = root; | map->root = root; | ||||
prev = entry->prev; | prev = entry->prev; | ||||
next = entry->next; | next = entry->next; | ||||
next->prev = prev; | next->prev = prev; | ||||
prev->next = next; | prev->next = next; | ||||
Show All 19 Lines | vm_map_entry_resize_free(vm_map_t map, vm_map_entry_t entry) | ||||
/* | /* | ||||
* Using splay trees without parent pointers, propagating | * Using splay trees without parent pointers, propagating | ||||
* max_free up the tree is done by moving the entry to the | * max_free up the tree is done by moving the entry to the | ||||
* root and making the change there. | * root and making the change there. | ||||
*/ | */ | ||||
if (entry != map->root) | if (entry != map->root) | ||||
map->root = vm_map_entry_splay(entry->start, map->root); | map->root = vm_map_entry_splay(entry->start, map->root); | ||||
entry->adj_free = (entry->next == &map->header ? map->max_offset : | entry->adj_free = entry->next->start - entry->end; | ||||
entry->next->start) - entry->end; | |||||
vm_map_entry_set_max_free(entry); | vm_map_entry_set_max_free(entry); | ||||
} | } | ||||
/* | /* | ||||
* vm_map_lookup_entry: [ internal use only ] | * vm_map_lookup_entry: [ internal use only ] | ||||
* | * | ||||
* Finds the map entry containing (or | * Finds the map entry containing (or | ||||
* immediately preceding) the specified address | * immediately preceding) the specified address | ||||
▲ Show 20 Lines • Show All 113 Lines • ▼ Show 20 Lines | vm_map_insert(vm_map_t map, vm_object_t object, vm_ooffset_t offset, | ||||
if (vm_map_lookup_entry(map, start, &temp_entry)) | if (vm_map_lookup_entry(map, start, &temp_entry)) | ||||
return (KERN_NO_SPACE); | return (KERN_NO_SPACE); | ||||
prev_entry = temp_entry; | prev_entry = temp_entry; | ||||
/* | /* | ||||
* Assert that the next entry doesn't overlap the end point. | * Assert that the next entry doesn't overlap the end point. | ||||
*/ | */ | ||||
if (prev_entry->next != &map->header && prev_entry->next->start < end) | if (prev_entry->next->start < end) | ||||
return (KERN_NO_SPACE); | return (KERN_NO_SPACE); | ||||
if ((cow & MAP_CREATE_GUARD) != 0 && (object != NULL || | if ((cow & MAP_CREATE_GUARD) != 0 && (object != NULL || | ||||
max != VM_PROT_NONE)) | max != VM_PROT_NONE)) | ||||
return (KERN_INVALID_ARGUMENT); | return (KERN_INVALID_ARGUMENT); | ||||
protoeflags = 0; | protoeflags = 0; | ||||
if (cow & MAP_COPY_ON_WRITE) | if (cow & MAP_COPY_ON_WRITE) | ||||
▲ Show 20 Lines • Show All 855 Lines • ▼ Show 20 Lines | if (vm_map_lookup_entry(map, start, &entry)) { | ||||
vm_map_clip_start(map, entry, start); | vm_map_clip_start(map, entry, start); | ||||
} else { | } else { | ||||
entry = entry->next; | entry = entry->next; | ||||
} | } | ||||
/* | /* | ||||
* Make a first pass to check for protection violations. | * Make a first pass to check for protection violations. | ||||
*/ | */ | ||||
for (current = entry; current != &map->header && current->start < end; | for (current = entry; current->start < end; current = current->next) { | ||||
current = current->next) { | |||||
if ((current->eflags & MAP_ENTRY_GUARD) != 0) | if ((current->eflags & MAP_ENTRY_GUARD) != 0) | ||||
continue; | continue; | ||||
if (current->eflags & MAP_ENTRY_IS_SUB_MAP) { | if (current->eflags & MAP_ENTRY_IS_SUB_MAP) { | ||||
vm_map_unlock(map); | vm_map_unlock(map); | ||||
return (KERN_INVALID_ARGUMENT); | return (KERN_INVALID_ARGUMENT); | ||||
} | } | ||||
if ((new_prot & current->max_protection) != new_prot) { | if ((new_prot & current->max_protection) != new_prot) { | ||||
vm_map_unlock(map); | vm_map_unlock(map); | ||||
return (KERN_PROTECTION_FAILURE); | return (KERN_PROTECTION_FAILURE); | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Do an accounting pass for private read-only mappings that | * Do an accounting pass for private read-only mappings that | ||||
* now will do cow due to allowed write (e.g. debugger sets | * now will do cow due to allowed write (e.g. debugger sets | ||||
* breakpoint on text segment) | * breakpoint on text segment) | ||||
*/ | */ | ||||
for (current = entry; current != &map->header && current->start < end; | for (current = entry; current->start < end; current = current->next) { | ||||
current = current->next) { | |||||
vm_map_clip_end(map, current, end); | vm_map_clip_end(map, current, end); | ||||
if (set_max || | if (set_max || | ||||
((new_prot & ~(current->protection)) & VM_PROT_WRITE) == 0 || | ((new_prot & ~(current->protection)) & VM_PROT_WRITE) == 0 || | ||||
ENTRY_CHARGED(current) || | ENTRY_CHARGED(current) || | ||||
(current->eflags & MAP_ENTRY_GUARD) != 0) { | (current->eflags & MAP_ENTRY_GUARD) != 0) { | ||||
continue; | continue; | ||||
Show All 37 Lines | for (current = entry; current->start < end; current = current->next) { | ||||
obj->charge = ptoa(obj->size); | obj->charge = ptoa(obj->size); | ||||
VM_OBJECT_WUNLOCK(obj); | VM_OBJECT_WUNLOCK(obj); | ||||
} | } | ||||
/* | /* | ||||
* Go back and fix up protections. [Note that clipping is not | * Go back and fix up protections. [Note that clipping is not | ||||
* necessary the second time.] | * necessary the second time.] | ||||
*/ | */ | ||||
for (current = entry; current != &map->header && current->start < end; | for (current = entry; current->start < end; current = current->next) { | ||||
current = current->next) { | |||||
if ((current->eflags & MAP_ENTRY_GUARD) != 0) | if ((current->eflags & MAP_ENTRY_GUARD) != 0) | ||||
continue; | continue; | ||||
old_prot = current->protection; | old_prot = current->protection; | ||||
if (set_max) | if (set_max) | ||||
current->protection = | current->protection = | ||||
(current->max_protection = new_prot) & | (current->max_protection = new_prot) & | ||||
▲ Show 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | vm_map_madvise( | ||||
if (modify_map) { | if (modify_map) { | ||||
/* | /* | ||||
* madvise behaviors that are implemented in the vm_map_entry. | * madvise behaviors that are implemented in the vm_map_entry. | ||||
* | * | ||||
* We clip the vm_map_entry so that behavioral changes are | * We clip the vm_map_entry so that behavioral changes are | ||||
* limited to the specified address range. | * limited to the specified address range. | ||||
*/ | */ | ||||
for (current = entry; | for (current = entry; current->start < end; | ||||
(current != &map->header) && (current->start < end); | current = current->next) { | ||||
current = current->next | |||||
) { | |||||
if (current->eflags & MAP_ENTRY_IS_SUB_MAP) | if (current->eflags & MAP_ENTRY_IS_SUB_MAP) | ||||
continue; | continue; | ||||
vm_map_clip_end(map, current, end); | vm_map_clip_end(map, current, end); | ||||
switch (behav) { | switch (behav) { | ||||
case MADV_NORMAL: | case MADV_NORMAL: | ||||
vm_map_entry_set_behavior(current, MAP_ENTRY_BEHAV_NORMAL); | vm_map_entry_set_behavior(current, MAP_ENTRY_BEHAV_NORMAL); | ||||
Show All 27 Lines | if (modify_map) { | ||||
/* | /* | ||||
* madvise behaviors that are implemented in the underlying | * madvise behaviors that are implemented in the underlying | ||||
* vm_object. | * vm_object. | ||||
* | * | ||||
* Since we don't clip the vm_map_entry, we have to clip | * Since we don't clip the vm_map_entry, we have to clip | ||||
* the vm_object pindex and count. | * the vm_object pindex and count. | ||||
*/ | */ | ||||
for (current = entry; | for (current = entry; current->start < end; | ||||
(current != &map->header) && (current->start < end); | current = current->next) { | ||||
current = current->next | |||||
) { | |||||
vm_offset_t useEnd, useStart; | vm_offset_t useEnd, useStart; | ||||
if (current->eflags & MAP_ENTRY_IS_SUB_MAP) | if (current->eflags & MAP_ENTRY_IS_SUB_MAP) | ||||
continue; | continue; | ||||
pstart = OFF_TO_IDX(current->offset); | pstart = OFF_TO_IDX(current->offset); | ||||
pend = pstart + atop(current->end - current->start); | pend = pstart + atop(current->end - current->start); | ||||
useStart = current->start; | useStart = current->start; | ||||
▲ Show 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | if (start == end) | ||||
return (KERN_SUCCESS); | return (KERN_SUCCESS); | ||||
vm_map_lock(map); | vm_map_lock(map); | ||||
VM_MAP_RANGE_CHECK(map, start, end); | VM_MAP_RANGE_CHECK(map, start, end); | ||||
if (vm_map_lookup_entry(map, start, &temp_entry)) { | if (vm_map_lookup_entry(map, start, &temp_entry)) { | ||||
entry = temp_entry; | entry = temp_entry; | ||||
vm_map_clip_start(map, entry, start); | vm_map_clip_start(map, entry, start); | ||||
} else | } else | ||||
entry = temp_entry->next; | entry = temp_entry->next; | ||||
while ((entry != &map->header) && (entry->start < end)) { | while (entry->start < end) { | ||||
vm_map_clip_end(map, entry, end); | vm_map_clip_end(map, entry, end); | ||||
if ((entry->eflags & MAP_ENTRY_GUARD) == 0 || | if ((entry->eflags & MAP_ENTRY_GUARD) == 0 || | ||||
new_inheritance != VM_INHERIT_ZERO) | new_inheritance != VM_INHERIT_ZERO) | ||||
entry->inheritance = new_inheritance; | entry->inheritance = new_inheritance; | ||||
vm_map_simplify_entry(map, entry); | vm_map_simplify_entry(map, entry); | ||||
entry = entry->next; | entry = entry->next; | ||||
} | } | ||||
vm_map_unlock(map); | vm_map_unlock(map); | ||||
Show All 25 Lines | if (flags & VM_MAP_WIRE_HOLESOK) | ||||
first_entry = first_entry->next; | first_entry = first_entry->next; | ||||
else { | else { | ||||
vm_map_unlock(map); | vm_map_unlock(map); | ||||
return (KERN_INVALID_ADDRESS); | return (KERN_INVALID_ADDRESS); | ||||
} | } | ||||
} | } | ||||
last_timestamp = map->timestamp; | last_timestamp = map->timestamp; | ||||
entry = first_entry; | entry = first_entry; | ||||
while (entry != &map->header && entry->start < end) { | while (entry->start < end) { | ||||
if (entry->eflags & MAP_ENTRY_IN_TRANSITION) { | if (entry->eflags & MAP_ENTRY_IN_TRANSITION) { | ||||
/* | /* | ||||
* We have not yet clipped the entry. | * We have not yet clipped the entry. | ||||
*/ | */ | ||||
saved_start = (start >= entry->start) ? start : | saved_start = (start >= entry->start) ? start : | ||||
entry->start; | entry->start; | ||||
entry->eflags |= MAP_ENTRY_NEEDS_WAKEUP; | entry->eflags |= MAP_ENTRY_NEEDS_WAKEUP; | ||||
if (vm_map_unlock_and_wait(map, 0)) { | if (vm_map_unlock_and_wait(map, 0)) { | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | KASSERT((entry->eflags & MAP_ENTRY_IN_TRANSITION) == 0 && | ||||
("owned map entry %p", entry)); | ("owned map entry %p", entry)); | ||||
entry->eflags |= MAP_ENTRY_IN_TRANSITION; | entry->eflags |= MAP_ENTRY_IN_TRANSITION; | ||||
entry->wiring_thread = curthread; | entry->wiring_thread = curthread; | ||||
/* | /* | ||||
* Check the map for holes in the specified region. | * Check the map for holes in the specified region. | ||||
* If VM_MAP_WIRE_HOLESOK was specified, skip this check. | * If VM_MAP_WIRE_HOLESOK was specified, skip this check. | ||||
*/ | */ | ||||
if (((flags & VM_MAP_WIRE_HOLESOK) == 0) && | if (((flags & VM_MAP_WIRE_HOLESOK) == 0) && | ||||
(entry->end < end && (entry->next == &map->header || | (entry->end < end && entry->next->start > entry->end)) { | ||||
entry->next->start > entry->end))) { | |||||
end = entry->end; | end = entry->end; | ||||
rv = KERN_INVALID_ADDRESS; | rv = KERN_INVALID_ADDRESS; | ||||
goto done; | goto done; | ||||
} | } | ||||
/* | /* | ||||
* If system unwiring, require that the entry is system wired. | * If system unwiring, require that the entry is system wired. | ||||
*/ | */ | ||||
if (!user_unwire && | if (!user_unwire && | ||||
Show All 9 Lines | done: | ||||
need_wakeup = FALSE; | need_wakeup = FALSE; | ||||
if (first_entry == NULL) { | if (first_entry == NULL) { | ||||
result = vm_map_lookup_entry(map, start, &first_entry); | result = vm_map_lookup_entry(map, start, &first_entry); | ||||
if (!result && (flags & VM_MAP_WIRE_HOLESOK)) | if (!result && (flags & VM_MAP_WIRE_HOLESOK)) | ||||
first_entry = first_entry->next; | first_entry = first_entry->next; | ||||
else | else | ||||
KASSERT(result, ("vm_map_unwire: lookup failed")); | KASSERT(result, ("vm_map_unwire: lookup failed")); | ||||
} | } | ||||
for (entry = first_entry; entry != &map->header && entry->start < end; | for (entry = first_entry; entry->start < end; entry = entry->next) { | ||||
entry = entry->next) { | |||||
/* | /* | ||||
* If VM_MAP_WIRE_HOLESOK was specified, an empty | * If VM_MAP_WIRE_HOLESOK was specified, an empty | ||||
* space in the unwired region could have been mapped | * space in the unwired region could have been mapped | ||||
* while the map lock was dropped for draining | * while the map lock was dropped for draining | ||||
* MAP_ENTRY_IN_TRANSITION. Moreover, another thread | * MAP_ENTRY_IN_TRANSITION. Moreover, another thread | ||||
* could be simultaneously wiring this new mapping | * could be simultaneously wiring this new mapping | ||||
* entry. Detect these cases and skip any entries | * entry. Detect these cases and skip any entries | ||||
* marked as in transition by us. | * marked as in transition by us. | ||||
▲ Show 20 Lines • Show All 97 Lines • ▼ Show 20 Lines | if (flags & VM_MAP_WIRE_HOLESOK) | ||||
first_entry = first_entry->next; | first_entry = first_entry->next; | ||||
else { | else { | ||||
vm_map_unlock(map); | vm_map_unlock(map); | ||||
return (KERN_INVALID_ADDRESS); | return (KERN_INVALID_ADDRESS); | ||||
} | } | ||||
} | } | ||||
last_timestamp = map->timestamp; | last_timestamp = map->timestamp; | ||||
entry = first_entry; | entry = first_entry; | ||||
while (entry != &map->header && entry->start < end) { | while (entry->start < end) { | ||||
if (entry->eflags & MAP_ENTRY_IN_TRANSITION) { | if (entry->eflags & MAP_ENTRY_IN_TRANSITION) { | ||||
/* | /* | ||||
* We have not yet clipped the entry. | * We have not yet clipped the entry. | ||||
*/ | */ | ||||
saved_start = (start >= entry->start) ? start : | saved_start = (start >= entry->start) ? start : | ||||
entry->start; | entry->start; | ||||
entry->eflags |= MAP_ENTRY_NEEDS_WAKEUP; | entry->eflags |= MAP_ENTRY_NEEDS_WAKEUP; | ||||
if (vm_map_unlock_and_wait(map, 0)) { | if (vm_map_unlock_and_wait(map, 0)) { | ||||
▲ Show 20 Lines • Show All 120 Lines • ▼ Show 20 Lines | if (entry->wired_count == 0) { | ||||
entry->wired_count++; | entry->wired_count++; | ||||
} | } | ||||
/* | /* | ||||
* Check the map for holes in the specified region. | * Check the map for holes in the specified region. | ||||
* If VM_MAP_WIRE_HOLESOK was specified, skip this check. | * If VM_MAP_WIRE_HOLESOK was specified, skip this check. | ||||
*/ | */ | ||||
next_entry: | next_entry: | ||||
if ((flags & VM_MAP_WIRE_HOLESOK) == 0 && | if ((flags & VM_MAP_WIRE_HOLESOK) == 0 && | ||||
entry->end < end && (entry->next == &map->header || | entry->end < end && entry->next->start > entry->end) { | ||||
entry->next->start > entry->end)) { | |||||
end = entry->end; | end = entry->end; | ||||
rv = KERN_INVALID_ADDRESS; | rv = KERN_INVALID_ADDRESS; | ||||
goto done; | goto done; | ||||
} | } | ||||
entry = entry->next; | entry = entry->next; | ||||
} | } | ||||
rv = KERN_SUCCESS; | rv = KERN_SUCCESS; | ||||
done: | done: | ||||
need_wakeup = FALSE; | need_wakeup = FALSE; | ||||
if (first_entry == NULL) { | if (first_entry == NULL) { | ||||
result = vm_map_lookup_entry(map, start, &first_entry); | result = vm_map_lookup_entry(map, start, &first_entry); | ||||
if (!result && (flags & VM_MAP_WIRE_HOLESOK)) | if (!result && (flags & VM_MAP_WIRE_HOLESOK)) | ||||
first_entry = first_entry->next; | first_entry = first_entry->next; | ||||
else | else | ||||
KASSERT(result, ("vm_map_wire: lookup failed")); | KASSERT(result, ("vm_map_wire: lookup failed")); | ||||
} | } | ||||
for (entry = first_entry; entry != &map->header && entry->start < end; | for (entry = first_entry; entry->start < end; entry = entry->next) { | ||||
entry = entry->next) { | |||||
/* | /* | ||||
* If VM_MAP_WIRE_HOLESOK was specified, an empty | * If VM_MAP_WIRE_HOLESOK was specified, an empty | ||||
* space in the unwired region could have been mapped | * space in the unwired region could have been mapped | ||||
* while the map lock was dropped for faulting in the | * while the map lock was dropped for faulting in the | ||||
* pages or draining MAP_ENTRY_IN_TRANSITION. | * pages or draining MAP_ENTRY_IN_TRANSITION. | ||||
* Moreover, another thread could be simultaneously | * Moreover, another thread could be simultaneously | ||||
* wiring this new mapping entry. Detect these cases | * wiring this new mapping entry. Detect these cases | ||||
* and skip any entries marked as in transition not by us. | * and skip any entries marked as in transition not by us. | ||||
▲ Show 20 Lines • Show All 87 Lines • ▼ Show 20 Lines | if (!vm_map_lookup_entry(map, start, &entry)) { | ||||
return (KERN_INVALID_ADDRESS); | return (KERN_INVALID_ADDRESS); | ||||
} else if (start == end) { | } else if (start == end) { | ||||
start = entry->start; | start = entry->start; | ||||
end = entry->end; | end = entry->end; | ||||
} | } | ||||
/* | /* | ||||
* Make a first pass to check for user-wired memory and holes. | * Make a first pass to check for user-wired memory and holes. | ||||
*/ | */ | ||||
for (current = entry; current != &map->header && current->start < end; | for (current = entry; current->start < end; current = current->next) { | ||||
current = current->next) { | |||||
if (invalidate && (current->eflags & MAP_ENTRY_USER_WIRED)) { | if (invalidate && (current->eflags & MAP_ENTRY_USER_WIRED)) { | ||||
vm_map_unlock_read(map); | vm_map_unlock_read(map); | ||||
return (KERN_INVALID_ARGUMENT); | return (KERN_INVALID_ARGUMENT); | ||||
} | } | ||||
if (end > current->end && | if (end > current->end && | ||||
(current->next == &map->header || | current->end != current->next->start) { | ||||
current->end != current->next->start)) { | |||||
vm_map_unlock_read(map); | vm_map_unlock_read(map); | ||||
return (KERN_INVALID_ADDRESS); | return (KERN_INVALID_ADDRESS); | ||||
} | } | ||||
} | } | ||||
if (invalidate) | if (invalidate) | ||||
pmap_remove(map->pmap, start, end); | pmap_remove(map->pmap, start, end); | ||||
failed = FALSE; | failed = FALSE; | ||||
/* | /* | ||||
* Make a second pass, cleaning/uncaching pages from the indicated | * Make a second pass, cleaning/uncaching pages from the indicated | ||||
* objects as we go. | * objects as we go. | ||||
*/ | */ | ||||
for (current = entry; current != &map->header && current->start < end;) { | for (current = entry; current->start < end;) { | ||||
offset = current->offset + (start - current->start); | offset = current->offset + (start - current->start); | ||||
size = (end <= current->end ? end : current->end) - start; | size = (end <= current->end ? end : current->end) - start; | ||||
if (current->eflags & MAP_ENTRY_IS_SUB_MAP) { | if (current->eflags & MAP_ENTRY_IS_SUB_MAP) { | ||||
vm_map_t smap; | vm_map_t smap; | ||||
vm_map_entry_t tentry; | vm_map_entry_t tentry; | ||||
vm_size_t tsize; | vm_size_t tsize; | ||||
smap = current->object.sub_map; | smap = current->object.sub_map; | ||||
▲ Show 20 Lines • Show All 160 Lines • ▼ Show 20 Lines | vm_map_delete(vm_map_t map, vm_offset_t start, vm_offset_t end) | ||||
else { | else { | ||||
entry = first_entry; | entry = first_entry; | ||||
vm_map_clip_start(map, entry, start); | vm_map_clip_start(map, entry, start); | ||||
} | } | ||||
/* | /* | ||||
* Step through all entries in this region | * Step through all entries in this region | ||||
*/ | */ | ||||
while ((entry != &map->header) && (entry->start < end)) { | while (entry->start < end) { | ||||
vm_map_entry_t next; | vm_map_entry_t next; | ||||
/* | /* | ||||
* Wait for wiring or unwiring of an entry to complete. | * Wait for wiring or unwiring of an entry to complete. | ||||
* Also wait for any system wirings to disappear on | * Also wait for any system wirings to disappear on | ||||
* user maps. | * user maps. | ||||
*/ | */ | ||||
if ((entry->eflags & MAP_ENTRY_IN_TRANSITION) != 0 || | if ((entry->eflags & MAP_ENTRY_IN_TRANSITION) != 0 || | ||||
▲ Show 20 Lines • Show All 91 Lines • ▼ Show 20 Lines | vm_map_check_protection(vm_map_t map, vm_offset_t start, vm_offset_t end, | ||||
vm_map_entry_t entry; | vm_map_entry_t entry; | ||||
vm_map_entry_t tmp_entry; | vm_map_entry_t tmp_entry; | ||||
if (!vm_map_lookup_entry(map, start, &tmp_entry)) | if (!vm_map_lookup_entry(map, start, &tmp_entry)) | ||||
return (FALSE); | return (FALSE); | ||||
entry = tmp_entry; | entry = tmp_entry; | ||||
while (start < end) { | while (start < end) { | ||||
if (entry == &map->header) | |||||
return (FALSE); | |||||
/* | /* | ||||
* No holes allowed! | * No holes allowed! | ||||
*/ | */ | ||||
if (start < entry->start) | if (start < entry->start) | ||||
return (FALSE); | return (FALSE); | ||||
/* | /* | ||||
* Check protection associated with entry. | * Check protection associated with entry. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 447 Lines • ▼ Show 20 Lines | vm_map_stack_locked(vm_map_t map, vm_offset_t addrbos, vm_size_t max_ssize, | ||||
/* If addr is already mapped, no go */ | /* If addr is already mapped, no go */ | ||||
if (vm_map_lookup_entry(map, addrbos, &prev_entry)) | if (vm_map_lookup_entry(map, addrbos, &prev_entry)) | ||||
return (KERN_NO_SPACE); | return (KERN_NO_SPACE); | ||||
/* | /* | ||||
* If we can't accommodate max_ssize in the current mapping, no go. | * If we can't accommodate max_ssize in the current mapping, no go. | ||||
*/ | */ | ||||
if ((prev_entry->next != &map->header) && | if (prev_entry->next->start < addrbos + max_ssize) | ||||
(prev_entry->next->start < addrbos + max_ssize)) | |||||
return (KERN_NO_SPACE); | return (KERN_NO_SPACE); | ||||
/* | /* | ||||
* We initially map a stack of only init_ssize. We will grow as | * We initially map a stack of only init_ssize. We will grow as | ||||
* needed later. Depending on the orientation of the stack (i.e. | * needed later. Depending on the orientation of the stack (i.e. | ||||
* the grow direction) we either map at the top of the range, the | * the grow direction) we either map at the top of the range, the | ||||
* bottom of the range or in the middle. | * bottom of the range or in the middle. | ||||
* | * | ||||
▲ Show 20 Lines • Show All 727 Lines • Show Last 20 Lines |