summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2006-06-27 04:28:23 +0000
committeralc <alc@FreeBSD.org>2006-06-27 04:28:23 +0000
commit49b81721c75aa7d09b4439821e3d832e5f4cc900 (patch)
tree5f301ab478f99906131d417e3ced409158979b03 /sys/amd64
parent2624aa9b6bf3b6e21b0e1c590665aaae07ea928d (diff)
downloadFreeBSD-src-49b81721c75aa7d09b4439821e3d832e5f4cc900.zip
FreeBSD-src-49b81721c75aa7d09b4439821e3d832e5f4cc900.tar.gz
Correct a very old and very obscure bug: vmspace_fork() calls
pmap_copy() if the mapping is VM_INHERIT_SHARE. Suppose the mapping is also wired. vmspace_fork() clears the wiring attributes in the vm map entry but pmap_copy() copies the PG_W attribute in the PTE. I don't think this is catastrophic. It blocks pmap_remove_pages() from destroying the mapping and corrupts the pmap's wiring count. This revision fixes the problem by changing pmap_copy() to clear the PG_W attribute. Reviewed by: tegge@
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/amd64/pmap.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 2d82790..dd05e18 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -2674,7 +2674,7 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
PHYS_TO_DMAP(VM_PAGE_TO_PHYS(dstmpde));
pde = &pde[pmap_pde_index(addr)];
if (*pde == 0) {
- *pde = srcptepaddr;
+ *pde = srcptepaddr & ~PG_W;
dst_pmap->pm_stats.resident_count +=
NBPDR / PAGE_SIZE;
} else
@@ -2708,11 +2708,12 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
pmap_try_insert_pv_entry(dst_pmap, addr,
PHYS_TO_VM_PAGE(ptetemp & PG_FRAME))) {
/*
- * Clear the modified and
+ * Clear the wired, modified, and
* accessed (referenced) bits
* during the copy.
*/
- *dst_pte = ptetemp & ~(PG_M | PG_A);
+ *dst_pte = ptetemp & ~(PG_W | PG_M |
+ PG_A);
dst_pmap->pm_stats.resident_count++;
} else
pmap_unwire_pte_hold(dst_pmap, addr,
OpenPOWER on IntegriCloud