summaryrefslogtreecommitdiff
path: root/usr/src/uts/i86pc/vm/htable.c
diff options
context:
space:
mode:
authorkchow <none@none>2006-10-03 14:50:02 -0700
committerkchow <none@none>2006-10-03 14:50:02 -0700
commita985e5786d4eb44e83b59c9c7e38bc77e12fec47 (patch)
treed38fda3a6cee05e7bab87ce71432c45fd32aa6a8 /usr/src/uts/i86pc/vm/htable.c
parent5705dae2b68d5caac5a244659599252ed9235deb (diff)
downloadillumos-gate-a985e5786d4eb44e83b59c9c7e38bc77e12fec47.tar.gz
6426285 ref bit only pte - BAD TRAP: type=e fc-cache: #pf Page fault post install of snv_40
6474786 stack overflow during kmem_cache_free
Diffstat (limited to 'usr/src/uts/i86pc/vm/htable.c')
-rw-r--r--usr/src/uts/i86pc/vm/htable.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/usr/src/uts/i86pc/vm/htable.c b/usr/src/uts/i86pc/vm/htable.c
index 45f8e90ba1..3105ad9e27 100644
--- a/usr/src/uts/i86pc/vm/htable.c
+++ b/usr/src/uts/i86pc/vm/htable.c
@@ -1846,12 +1846,19 @@ x86pte_set(htable_t *ht, uint_t entry, x86pte_t new, void *ptr)
prev = *ptep;
n = new;
/*
- * prevent potential data loss by preserving the MOD
- * bit if set in the current PTE and the pfns are the
- * same. For example, segmap can reissue a read-only
- * hat_memload on top of a dirty page.
+ * prevent potential data loss by preserving the
+ * MOD/REF bits if set in the current PTE, the pfns are
+ * the same and the 'new' pte is non-zero. For example,
+ * segmap can reissue a read-only hat_memload on top
+ * of a dirty page.
+ *
+ * 'new' is required to be non-zero on a remap as at
+ * least the valid bit should be non-zero. The 'new'
+ * check also avoids incorrectly preserving the REF/MOD
+ * bit when unmapping pfn 0.
*/
- if (PTE_ISVALID(prev) && PTE2PFN(prev, ht->ht_level) ==
+ if (new != 0 && PTE_ISVALID(prev) &&
+ PTE2PFN(prev, ht->ht_level) ==
PTE2PFN(n, ht->ht_level)) {
n |= prev & (PT_REF | PT_MOD);
}
@@ -1868,7 +1875,8 @@ x86pte_set(htable_t *ht, uint_t entry, x86pte_t new, void *ptr)
for (;;) {
p32 = *pte32p;
n32 = new;
- if (PTE_ISVALID(p32) && PTE2PFN(p32, ht->ht_level) ==
+ if (new != 0 && PTE_ISVALID(p32) &&
+ PTE2PFN(p32, ht->ht_level) ==
PTE2PFN(n32, ht->ht_level)) {
n32 |= p32 & (PT_REF | PT_MOD);
}