mostly checks for unallocated pages in range
SCCS-vsn: sys/vm/vm_map.c 7.10
*
* %sccs.include.redist.c%
*
*
* %sccs.include.redist.c%
*
- * @(#)vm_map.c 7.9 (Berkeley) %G%
+ * @(#)vm_map.c 7.10 (Berkeley) %G%
*
*
* Copyright (c) 1987, 1990 Carnegie-Mellon University.
*
*
* Copyright (c) 1987, 1990 Carnegie-Mellon University.
register boolean_t new_pageable;
{
register vm_map_entry_t entry;
register boolean_t new_pageable;
{
register vm_map_entry_t entry;
- vm_map_entry_t temp_entry;
+ vm_map_entry_t start_entry;
register vm_offset_t failed;
int rv;
register vm_offset_t failed;
int rv;
* for the entire region. We do so before making any changes.
*/
* for the entire region. We do so before making any changes.
*/
- if (vm_map_lookup_entry(map, start, &temp_entry)) {
- entry = temp_entry;
- vm_map_clip_start(map, entry, start);
+ if (vm_map_lookup_entry(map, start, &start_entry) == FALSE) {
+ vm_map_unlock(map);
+ return(KERN_INVALID_ADDRESS);
- else
- entry = temp_entry->next;
- temp_entry = entry;
/*
* Actions are rather different for wiring and unwiring,
/*
* Actions are rather different for wiring and unwiring,
+ vm_map_clip_start(map, entry, start);
+
/*
* Unwiring. First ensure that the range to be
/*
* Unwiring. First ensure that the range to be
- * unwired is really wired down.
+ * unwired is really wired down and that there
+ * are no holes.
*/
while ((entry != &map->header) && (entry->start < end)) {
*/
while ((entry != &map->header) && (entry->start < end)) {
- if (entry->wired_count == 0) {
+ if (entry->wired_count == 0 ||
+ (entry->end < end &&
+ (entry->next == &map->header ||
+ entry->next->start > entry->end))) {
vm_map_unlock(map);
return(KERN_INVALID_ARGUMENT);
}
vm_map_unlock(map);
return(KERN_INVALID_ARGUMENT);
}
*/
lock_set_recursive(&map->lock);
*/
lock_set_recursive(&map->lock);
while ((entry != &map->header) && (entry->start < end)) {
vm_map_clip_end(map, entry, end);
while ((entry != &map->header) && (entry->start < end)) {
vm_map_clip_end(map, entry, end);
/*
* Wiring. We must do this in two passes:
*
/*
* Wiring. We must do this in two passes:
*
- * 1. Holding the write lock, we increment the
- * wiring count. For any area that is not already
- * wired, we create any shadow objects that need
- * to be created.
+ * 1. Holding the write lock, we create any shadow
+ * or zero-fill objects that need to be created.
+ * Then we clip each map entry to the region to be
+ * wired and increment its wiring count. We
+ * create objects before clipping the map entries
+ * to avoid object proliferation.
*
* 2. We downgrade to a read lock, and call
* vm_fault_wire to fault in the pages for any
*
* 2. We downgrade to a read lock, and call
* vm_fault_wire to fault in the pages for any
while ((entry != &map->header) && (entry->start < end)) {
while ((entry != &map->header) && (entry->start < end)) {
vm_map_clip_end(map, entry, end);
vm_map_clip_end(map, entry, end);
-
- entry->wired_count++;
- if (entry->wired_count == 1) {
+#endif
+ if (entry->wired_count == 0) {
/*
* Perform actions of vm_map_lookup that need
/*
* Perform actions of vm_map_lookup that need
+ vm_map_clip_start(map, entry, start);
+ vm_map_clip_end(map, entry, end);
+ entry->wired_count++;
+ /*
+ * Check for holes
+ */
+ if (entry->end < end &&
+ (entry->next == &map->header ||
+ entry->next->start > entry->end)) {
+ /*
+ * Found one. Object creation actions
+ * do not need to be undone, but the
+ * wired counts need to be restored.
+ */
+ while (entry != &map->header && entry->end > start) {
+ entry->wired_count--;
+ entry = entry->prev;
+ }
+ vm_map_unlock(map);
+ return(KERN_INVALID_ARGUMENT);
+ }
while (entry != &map->header && entry->start < end) {
/*
* If vm_fault_wire fails for any page we need to
while (entry != &map->header && entry->start < end) {
/*
* If vm_fault_wire fails for any page we need to
new_share_entry =
vm_map_entry_create(new_share_map);
*new_share_entry = *old_entry;
new_share_entry =
vm_map_entry_create(new_share_map);
*new_share_entry = *old_entry;
+ new_share_entry->wired_count = 0;
/*
* Insert the entry into the new sharing
/*
* Insert the entry into the new sharing
new_entry = vm_map_entry_create(new_map);
*new_entry = *old_entry;
new_entry = vm_map_entry_create(new_map);
*new_entry = *old_entry;
+ new_entry->wired_count = 0;
vm_map_reference(new_entry->object.share_map);
/*
vm_map_reference(new_entry->object.share_map);
/*