diff options
author | alc <alc@FreeBSD.org> | 2006-08-01 19:06:06 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2006-08-01 19:06:06 +0000 |
commit | a152234cf9a52766984ecb9a96cc1e5740ae9d78 (patch) | |
tree | 7cf5203513490cb91de50813dfb5015b4f873256 /sys/ia64 | |
parent | a2e0f77d8f100b139a19a4fc8ecece7356b6afdc (diff) | |
download | FreeBSD-src-a152234cf9a52766984ecb9a96cc1e5740ae9d78.zip FreeBSD-src-a152234cf9a52766984ecb9a96cc1e5740ae9d78.tar.gz |
Complete the transition from pmap_page_protect() to pmap_remove_write().
Originally, I had adopted sparc64's name, pmap_clear_write(), for the
function that is now pmap_remove_write(). However, this function is more
like pmap_remove_all() than like pmap_clear_modify() or
pmap_clear_reference(), hence, the name change.
The higher-level rationale behind this change is described in
src/sys/amd64/amd64/pmap.c revision 1.567. The short version is that I'm
trying to clean up and fix our support for execute access.
Reviewed by: marcel@ (ia64)
Diffstat (limited to 'sys/ia64')
-rw-r--r-- | sys/ia64/ia64/pmap.c | 71 |
1 files changed, 37 insertions, 34 deletions
diff --git a/sys/ia64/ia64/pmap.c b/sys/ia64/ia64/pmap.c index 18d9644..e6b09ad 100644 --- a/sys/ia64/ia64/pmap.c +++ b/sys/ia64/ia64/pmap.c @@ -1939,40 +1939,6 @@ pmap_remove_pages(pmap_t pmap) } /* - * pmap_page_protect: - * - * Lower the permission for all mappings to a given page. - */ -void -pmap_page_protect(vm_page_t m, vm_prot_t prot) -{ - struct ia64_lpte *pte; - pmap_t oldpmap, pmap; - pv_entry_t pv; - - if ((prot & VM_PROT_WRITE) != 0) - return; - if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { - if ((m->flags & PG_WRITEABLE) == 0) - return; - TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) { - pmap = pv->pv_pmap; - PMAP_LOCK(pmap); - oldpmap = pmap_install(pmap); - pte = pmap_find_vhpt(pv->pv_va); - KASSERT(pte != NULL, ("pte")); - pmap_pte_prot(pmap, pte, prot); - pmap_invalidate_page(pmap, pv->pv_va); - pmap_install(oldpmap); - PMAP_UNLOCK(pmap); - } - vm_page_flag_clear(m, PG_WRITEABLE); - } else { - pmap_remove_all(m); - } -} - -/* * pmap_ts_referenced: * * Return a count of reference bits for a page, clearing those bits. @@ -2119,6 +2085,43 @@ pmap_clear_reference(vm_page_t m) } /* + * Clear the write and modified bits in each of the given page's mappings. + */ +void +pmap_remove_write(vm_page_t m) +{ + struct ia64_lpte *pte; + pmap_t oldpmap, pmap; + pv_entry_t pv; + vm_prot_t prot; + + mtx_assert(&vm_page_queue_mtx, MA_OWNED); + if ((m->flags & PG_FICTITIOUS) != 0 || + (m->flags & PG_WRITEABLE) == 0) + return; + TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) { + pmap = pv->pv_pmap; + PMAP_LOCK(pmap); + oldpmap = pmap_install(pmap); + pte = pmap_find_vhpt(pv->pv_va); + KASSERT(pte != NULL, ("pte")); + prot = pmap_prot(pte); + if ((prot & VM_PROT_WRITE) != 0) { + if (pmap_dirty(pte)) { + vm_page_dirty(m); + pmap_clear_dirty(pte); + } + prot &= ~VM_PROT_WRITE; + pmap_pte_prot(pmap, pte, prot); + pmap_invalidate_page(pmap, pv->pv_va); + } + pmap_install(oldpmap); + PMAP_UNLOCK(pmap); + } + vm_page_flag_clear(m, PG_WRITEABLE); +} + +/* * Map a set of physical memory pages into the kernel virtual * address space. Return a pointer to where it is mapped. This * routine is intended to be used for mapping device memory, |