- vm_fault_copy_entry() should not assume that the source object contains

every page.  If the source entry was read-only, one or more wired pages
   could be in backing objects.
 - vm_fault_copy_entry() should not set the PG_WRITEABLE flag on the page
   unless the destination entry is, in fact, writeable.
This commit is contained in:
Alan Cox 2003-10-15 08:00:45 +00:00
parent 08fd6713b2
commit c5b65a6723

View File

@ -1124,10 +1124,11 @@ vm_fault_copy_entry(dst_map, src_map, dst_entry, src_entry)
vm_map_entry_t dst_entry;
vm_map_entry_t src_entry;
{
vm_object_t dst_object;
vm_object_t backing_object, dst_object, object;
vm_object_t src_object;
vm_ooffset_t dst_offset;
vm_ooffset_t src_offset;
vm_pindex_t pindex;
vm_prot_t prot;
vm_offset_t vaddr;
vm_page_t dst_m;
@ -1181,12 +1182,24 @@ vm_fault_copy_entry(dst_map, src_map, dst_entry, src_entry)
* memory.)
*/
VM_OBJECT_LOCK(src_object);
src_m = vm_page_lookup(src_object,
OFF_TO_IDX(dst_offset + src_offset));
object = src_object;
pindex = 0;
while ((src_m = vm_page_lookup(object, pindex +
OFF_TO_IDX(dst_offset + src_offset))) == NULL &&
(src_entry->protection & VM_PROT_WRITE) == 0 &&
(backing_object = object->backing_object) != NULL) {
/*
* Allow fallback to backing objects if we are reading.
*/
VM_OBJECT_LOCK(backing_object);
pindex += OFF_TO_IDX(object->backing_object_offset);
VM_OBJECT_UNLOCK(object);
object = backing_object;
}
if (src_m == NULL)
panic("vm_fault_copy_wired: page missing");
pmap_copy_page(src_m, dst_m);
VM_OBJECT_UNLOCK(src_object);
VM_OBJECT_UNLOCK(object);
dst_m->valid = VM_PAGE_BITS_ALL;
VM_OBJECT_UNLOCK(dst_object);
@ -1196,7 +1209,8 @@ vm_fault_copy_entry(dst_map, src_map, dst_entry, src_entry)
pmap_enter(dst_map->pmap, vaddr, dst_m, prot, FALSE);
VM_OBJECT_LOCK(dst_object);
vm_page_lock_queues();
vm_page_flag_set(dst_m, PG_WRITEABLE);
if ((prot & VM_PROT_WRITE) != 0)
vm_page_flag_set(dst_m, PG_WRITEABLE);
/*
* Mark it no longer busy, and put it on the active list.