Additional pmap locking

Tested by: marcel@
This commit is contained in:
Alan Cox 2004-07-21 07:01:48 +00:00
parent ee92911f48
commit 756e6d1939
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=132487

View file

@ -990,18 +990,19 @@ pmap_extract(pmap_t pmap, vm_offset_t va)
{ {
struct ia64_lpte *pte; struct ia64_lpte *pte;
pmap_t oldpmap; pmap_t oldpmap;
vm_paddr_t pa;
if (!pmap) pa = 0;
return 0; if (pmap == NULL)
return (pa);
PMAP_LOCK(pmap);
oldpmap = pmap_install(pmap); oldpmap = pmap_install(pmap);
pte = pmap_find_vhpt(va); pte = pmap_find_vhpt(va);
if (pte != NULL && pmap_pte_v(pte))
pa = pmap_pte_pa(pte);
pmap_install(oldpmap); pmap_install(oldpmap);
PMAP_UNLOCK(pmap);
if (!pte) return (pa);
return 0;
return pmap_pte_pa(pte);
} }
/* /*
@ -1898,6 +1899,8 @@ pmap_remove_pages(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
void void
pmap_page_protect(vm_page_t m, vm_prot_t prot) pmap_page_protect(vm_page_t m, vm_prot_t prot)
{ {
struct ia64_lpte *pte;
pmap_t oldpmap;
pv_entry_t pv; pv_entry_t pv;
if ((prot & VM_PROT_WRITE) != 0) if ((prot & VM_PROT_WRITE) != 0)
@ -1907,14 +1910,15 @@ pmap_page_protect(vm_page_t m, vm_prot_t prot)
return; return;
TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) { TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
int newprot = pte_prot(pv->pv_pmap, prot); int newprot = pte_prot(pv->pv_pmap, prot);
pmap_t oldpmap = pmap_install(pv->pv_pmap); PMAP_LOCK(pv->pv_pmap);
struct ia64_lpte *pte; oldpmap = pmap_install(pv->pv_pmap);
pte = pmap_find_vhpt(pv->pv_va); pte = pmap_find_vhpt(pv->pv_va);
KASSERT(pte != NULL, ("pte")); KASSERT(pte != NULL, ("pte"));
pmap_pte_set_prot(pte, newprot); pmap_pte_set_prot(pte, newprot);
pmap_update_vhpt(pte, pv->pv_va); pmap_update_vhpt(pte, pv->pv_va);
pmap_invalidate_page(pv->pv_pmap, pv->pv_va); pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
pmap_install(oldpmap); pmap_install(oldpmap);
PMAP_UNLOCK(pv->pv_pmap);
} }
vm_page_flag_clear(m, PG_WRITEABLE); vm_page_flag_clear(m, PG_WRITEABLE);
} else { } else {
@ -1937,6 +1941,8 @@ pmap_page_protect(vm_page_t m, vm_prot_t prot)
int int
pmap_ts_referenced(vm_page_t m) pmap_ts_referenced(vm_page_t m)
{ {
struct ia64_lpte *pte;
pmap_t oldpmap;
pv_entry_t pv; pv_entry_t pv;
int count = 0; int count = 0;
@ -1944,8 +1950,8 @@ pmap_ts_referenced(vm_page_t m)
return 0; return 0;
TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) { TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
pmap_t oldpmap = pmap_install(pv->pv_pmap); PMAP_LOCK(pv->pv_pmap);
struct ia64_lpte *pte; oldpmap = pmap_install(pv->pv_pmap);
pte = pmap_find_vhpt(pv->pv_va); pte = pmap_find_vhpt(pv->pv_va);
KASSERT(pte != NULL, ("pte")); KASSERT(pte != NULL, ("pte"));
if (pte->pte_a) { if (pte->pte_a) {
@ -1955,6 +1961,7 @@ pmap_ts_referenced(vm_page_t m)
pmap_invalidate_page(pv->pv_pmap, pv->pv_va); pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
} }
pmap_install(oldpmap); pmap_install(oldpmap);
PMAP_UNLOCK(pv->pv_pmap);
} }
return count; return count;
@ -1997,21 +2004,28 @@ pmap_is_referenced(vm_page_t m)
boolean_t boolean_t
pmap_is_modified(vm_page_t m) pmap_is_modified(vm_page_t m)
{ {
struct ia64_lpte *pte;
pmap_t oldpmap;
pv_entry_t pv; pv_entry_t pv;
boolean_t rv;
rv = FALSE;
if (!pmap_initialized || (m->flags & PG_FICTITIOUS)) if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
return FALSE; return (rv);
TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) { TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
pmap_t oldpmap = pmap_install(pv->pv_pmap); PMAP_LOCK(pv->pv_pmap);
struct ia64_lpte *pte = pmap_find_vhpt(pv->pv_va); oldpmap = pmap_install(pv->pv_pmap);
pte = pmap_find_vhpt(pv->pv_va);
pmap_install(oldpmap); pmap_install(oldpmap);
KASSERT(pte != NULL, ("pte")); KASSERT(pte != NULL, ("pte"));
if (pte->pte_d) rv = pte->pte_d != 0;
return 1; PMAP_UNLOCK(pv->pv_pmap);
if (rv)
break;
} }
return 0; return (rv);
} }
/* /*
@ -2037,14 +2051,17 @@ pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr)
void void
pmap_clear_modify(vm_page_t m) pmap_clear_modify(vm_page_t m)
{ {
struct ia64_lpte *pte;
pmap_t oldpmap;
pv_entry_t pv; pv_entry_t pv;
if (!pmap_initialized || (m->flags & PG_FICTITIOUS)) if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
return; return;
TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) { TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
pmap_t oldpmap = pmap_install(pv->pv_pmap); PMAP_LOCK(pv->pv_pmap);
struct ia64_lpte *pte = pmap_find_vhpt(pv->pv_va); oldpmap = pmap_install(pv->pv_pmap);
pte = pmap_find_vhpt(pv->pv_va);
KASSERT(pte != NULL, ("pte")); KASSERT(pte != NULL, ("pte"));
if (pte->pte_d) { if (pte->pte_d) {
pte->pte_d = 0; pte->pte_d = 0;
@ -2052,6 +2069,7 @@ pmap_clear_modify(vm_page_t m)
pmap_invalidate_page(pv->pv_pmap, pv->pv_va); pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
} }
pmap_install(oldpmap); pmap_install(oldpmap);
PMAP_UNLOCK(pv->pv_pmap);
} }
} }
@ -2063,14 +2081,17 @@ pmap_clear_modify(vm_page_t m)
void void
pmap_clear_reference(vm_page_t m) pmap_clear_reference(vm_page_t m)
{ {
struct ia64_lpte *pte;
pmap_t oldpmap;
pv_entry_t pv; pv_entry_t pv;
if (!pmap_initialized || (m->flags & PG_FICTITIOUS)) if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
return; return;
TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) { TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
pmap_t oldpmap = pmap_install(pv->pv_pmap); PMAP_LOCK(pv->pv_pmap);
struct ia64_lpte *pte = pmap_find_vhpt(pv->pv_va); oldpmap = pmap_install(pv->pv_pmap);
pte = pmap_find_vhpt(pv->pv_va);
KASSERT(pte != NULL, ("pte")); KASSERT(pte != NULL, ("pte"));
if (pte->pte_a) { if (pte->pte_a) {
pte->pte_a = 0; pte->pte_a = 0;
@ -2078,6 +2099,7 @@ pmap_clear_reference(vm_page_t m)
pmap_invalidate_page(pv->pv_pmap, pv->pv_va); pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
} }
pmap_install(oldpmap); pmap_install(oldpmap);
PMAP_UNLOCK(pv->pv_pmap);
} }
} }
@ -2169,9 +2191,11 @@ pmap_mincore(pmap_t pmap, vm_offset_t addr)
struct ia64_lpte *pte; struct ia64_lpte *pte;
int val = 0; int val = 0;
PMAP_LOCK(pmap);
oldpmap = pmap_install(pmap); oldpmap = pmap_install(pmap);
pte = pmap_find_vhpt(addr); pte = pmap_find_vhpt(addr);
pmap_install(oldpmap); pmap_install(oldpmap);
PMAP_UNLOCK(pmap);
if (!pte) if (!pte)
return 0; return 0;