diff options
-rw-r--r-- | sys/kern/kern_subr.c | 2 | ||||
-rw-r--r-- | sys/vm/vm_fault.c | 11 |
2 files changed, 10 insertions, 3 deletions
diff --git a/sys/kern/kern_subr.c b/sys/kern/kern_subr.c index 6728e8d..a5d6d0f 100644 --- a/sys/kern/kern_subr.c +++ b/sys/kern/kern_subr.c @@ -87,7 +87,7 @@ vm_pgmoveco(vm_map_t mapa, vm_object_t srcobj, vm_offset_t kaddr, kern_pg = PHYS_TO_VM_PAGE(vtophys(kaddr)); if ((vm_map_lookup(&map, uaddr, - VM_PROT_READ, &entry, &uobject, + VM_PROT_WRITE, &entry, &uobject, &upindex, &prot, &wired)) != KERN_SUCCESS) { return(EFAULT); } diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index e443a00..a620576 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -310,11 +310,18 @@ RetryFault:; int queue, s; /* - * check for page-based copy on write + * check for page-based copy on write. + * We check fs.object == fs.first_object so + * as to ensure the legacy COW mechanism is + * used when the page in question is part of + * a shadow object. Otherwise, vm_page_cowfault() + * removes the page from the backing object, + * which is not what we want. */ vm_page_lock_queues(); if ((fs.m->cow) && - (fault_type & VM_PROT_WRITE)) { + (fault_type & VM_PROT_WRITE) && + (fs.object == fs.first_object)) { s = splvm(); vm_page_cowfault(fs.m); splx(s); |