|
Lines 5214-5221
Link Here
|
| 5214 |
pmap_protect_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t sva, vm_prot_t prot) |
5214 |
pmap_protect_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t sva, vm_prot_t prot) |
| 5215 |
{ |
5215 |
{ |
| 5216 |
pd_entry_t newpde, oldpde; |
5216 |
pd_entry_t newpde, oldpde; |
| 5217 |
vm_offset_t eva, va; |
5217 |
vm_page_t m, mt; |
| 5218 |
vm_page_t m; |
|
|
| 5219 |
boolean_t anychanged; |
5218 |
boolean_t anychanged; |
| 5220 |
pt_entry_t PG_G, PG_M, PG_RW; |
5219 |
pt_entry_t PG_G, PG_M, PG_RW; |
| 5221 |
|
5220 |
|
|
Lines 5229-5243
Link Here
|
| 5229 |
anychanged = FALSE; |
5228 |
anychanged = FALSE; |
| 5230 |
retry: |
5229 |
retry: |
| 5231 |
oldpde = newpde = *pde; |
5230 |
oldpde = newpde = *pde; |
| 5232 |
if ((oldpde & (PG_MANAGED | PG_M | PG_RW)) == |
5231 |
if ((prot & VM_PROT_WRITE) == 0) { |
| 5233 |
(PG_MANAGED | PG_M | PG_RW)) { |
5232 |
if ((oldpde & (PG_MANAGED | PG_M | PG_RW)) == |
| 5234 |
eva = sva + NBPDR; |
5233 |
(PG_MANAGED | PG_M | PG_RW)) { |
| 5235 |
for (va = sva, m = PHYS_TO_VM_PAGE(oldpde & PG_PS_FRAME); |
5234 |
m = PHYS_TO_VM_PAGE(oldpde & PG_PS_FRAME); |
| 5236 |
va < eva; va += PAGE_SIZE, m++) |
5235 |
for (mt = m; mt < &m[NBPDR / PAGE_SIZE]; mt++) |
| 5237 |
vm_page_dirty(m); |
5236 |
vm_page_dirty(mt); |
|
|
5237 |
} |
| 5238 |
newpde &= ~(PG_RW | PG_M); |
| 5238 |
} |
5239 |
} |
| 5239 |
if ((prot & VM_PROT_WRITE) == 0) |
|
|
| 5240 |
newpde &= ~(PG_RW | PG_M); |
| 5241 |
if ((prot & VM_PROT_EXECUTE) == 0) |
5240 |
if ((prot & VM_PROT_EXECUTE) == 0) |
| 5242 |
newpde |= pg_nx; |
5241 |
newpde |= pg_nx; |
| 5243 |
if (newpde != oldpde) { |
5242 |
if (newpde != oldpde) { |
|
Lines 7600-7606
Link Here
|
| 7600 |
pmap_t pmap; |
7599 |
pmap_t pmap; |
| 7601 |
pv_entry_t next_pv, pv; |
7600 |
pv_entry_t next_pv, pv; |
| 7602 |
pd_entry_t oldpde, *pde; |
7601 |
pd_entry_t oldpde, *pde; |
| 7603 |
pt_entry_t oldpte, *pte, PG_M, PG_RW, PG_V; |
7602 |
pt_entry_t *pte, PG_M, PG_RW; |
| 7604 |
struct rwlock *lock; |
7603 |
struct rwlock *lock; |
| 7605 |
vm_offset_t va; |
7604 |
vm_offset_t va; |
| 7606 |
int md_gen, pvh_gen; |
7605 |
int md_gen, pvh_gen; |
|
Lines 7636-7668
Link Here
|
| 7636 |
} |
7635 |
} |
| 7637 |
} |
7636 |
} |
| 7638 |
PG_M = pmap_modified_bit(pmap); |
7637 |
PG_M = pmap_modified_bit(pmap); |
| 7639 |
PG_V = pmap_valid_bit(pmap); |
|
|
| 7640 |
PG_RW = pmap_rw_bit(pmap); |
7638 |
PG_RW = pmap_rw_bit(pmap); |
| 7641 |
va = pv->pv_va; |
7639 |
va = pv->pv_va; |
| 7642 |
pde = pmap_pde(pmap, va); |
7640 |
pde = pmap_pde(pmap, va); |
| 7643 |
oldpde = *pde; |
7641 |
oldpde = *pde; |
| 7644 |
if ((oldpde & PG_RW) != 0) { |
7642 |
/* If oldpde has PG_RW set, then it also has PG_M set. */ |
| 7645 |
if (pmap_demote_pde_locked(pmap, pde, va, &lock)) { |
7643 |
if ((oldpde & PG_RW) != 0 && |
| 7646 |
if ((oldpde & PG_W) == 0) { |
7644 |
pmap_demote_pde_locked(pmap, pde, va, &lock) && |
| 7647 |
/* |
7645 |
(oldpde & PG_W) == 0) { |
| 7648 |
* Write protect the mapping to a |
7646 |
/* |
| 7649 |
* single page so that a subsequent |
7647 |
* Write protect the mapping to a single page so that |
| 7650 |
* write access may repromote. |
7648 |
* a subsequent write access may repromote. |
| 7651 |
*/ |
7649 |
*/ |
| 7652 |
va += VM_PAGE_TO_PHYS(m) - (oldpde & |
7650 |
va += VM_PAGE_TO_PHYS(m) - (oldpde & PG_PS_FRAME); |
| 7653 |
PG_PS_FRAME); |
7651 |
pte = pmap_pde_to_pte(pde, va); |
| 7654 |
pte = pmap_pde_to_pte(pde, va); |
7652 |
atomic_clear_long(pte, PG_M | PG_RW); |
| 7655 |
oldpte = *pte; |
7653 |
vm_page_dirty(m); |
| 7656 |
if ((oldpte & PG_V) != 0) { |
7654 |
pmap_invalidate_page(pmap, va); |
| 7657 |
while (!atomic_cmpset_long(pte, |
|
|
| 7658 |
oldpte, |
| 7659 |
oldpte & ~(PG_M | PG_RW))) |
| 7660 |
oldpte = *pte; |
| 7661 |
vm_page_dirty(m); |
| 7662 |
pmap_invalidate_page(pmap, va); |
| 7663 |
} |
| 7664 |
} |
| 7665 |
} |
| 7666 |
} |
7655 |
} |
| 7667 |
PMAP_UNLOCK(pmap); |
7656 |
PMAP_UNLOCK(pmap); |
| 7668 |
} |
7657 |
} |