-/* $OpenBSD: pmap.c,v 1.25 2014/11/16 12:30:57 deraadt Exp $ */
+/* $OpenBSD: pmap.c,v 1.26 2014/12/17 15:26:21 deraadt Exp $ */
/*
* Copyright (c) 2005 Michael Shalayeff
struct pv_entry *pve;
pg = PHYS_TO_VM_PAGE(pa);
- simple_lock(&pg->mdpage.pvh_lock);
for(pve = pg->mdpage.pvh_list; pve; pve = pve->pv_next)
printf("%x:%lx\n", pve->pv_pmap->pm_space, pve->pv_va);
- simple_unlock(&pg->mdpage.pvh_lock);
}
#endif
DPRINTF(PDB_FOLLOW|PDB_PV, ("pmap_pv_remove(%p, %p, 0x%lx)\n",
pg, pmap, va));
- simple_lock(&pg->mdpage.pvh_lock); /* lock pv_head */
for(pv = *(pve = &pg->mdpage.pvh_list);
pv; pv = *(pve = &(*pve)->pv_next))
if (pv->pv_pmap == pmap && pv->pv_va == va) {
*pve = pv->pv_next;
break;
}
- simple_unlock(&pg->mdpage.pvh_lock); /* unlock, done! */
return (pv);
}
va = VM_MIN_KERNEL_ADDRESS + (pmap_nkpdes << PDE_SHIFT);
DPRINTF(PDB_PHYS, ("pmap_growkernel: was va 0x%lx\n", va));
if (va < kva) {
- simple_lock(&pmap_kernel()->pm_obj.vmobjlock);
-
for ( ; va < kva ; pmap_nkpdes++, va += 1 << PDE_SHIFT)
if (uvm.page_init_done) {
if (!pmap_pde_alloc(pmap_kernel(), va, NULL))
pmap_pde_set(pmap_kernel(), va, pa);
pmap_kernel()->pm_stats.resident_count++;
}
-
- simple_unlock(&pmap_kernel()->pm_obj.vmobjlock);
}
DPRINTF(PDB_PHYS|PDB_VP, ("pmap_growkernel: now va 0x%lx\n", va));
return (va);
DPRINTF(PDB_FOLLOW|PDB_PMAP, ("pmap_destroy(%p)\n", pmap));
- simple_lock(&pmap->pm_lock);
refs = --pmap->pm_obj.uo_refs;
- simple_unlock(&pmap->pm_lock);
if (refs > 0)
return;
{
DPRINTF(PDB_FOLLOW|PDB_PMAP, ("pmap_reference(%p)\n", pmap));
- simple_lock(&pmap->pm_lock);
pmap->pm_obj.uo_refs++;
- simple_unlock(&pmap->pm_lock);
}
void
("pmap_enter(%p, 0x%lx, 0x%lx, 0x%x, 0x%x)\n",
pmap, va, pa, prot, flags));
- simple_lock(&pmap->pm_lock);
-
if (!(pde = pmap_pde_get(pmap->pm_pdir, va)) &&
!(pde = pmap_pde_alloc(pmap, va, &ptp))) {
- if (flags & PMAP_CANFAIL) {
- simple_unlock(&pmap->pm_lock);
+ if (flags & PMAP_CANFAIL)
return (ENOMEM);
- }
panic("pmap_enter: cannot allocate pde");
}
pg = PHYS_TO_VM_PAGE(PTE_PAGE(pte));
if (pg != NULL) {
- simple_lock(&pg->mdpage.pvh_lock);
pve = pmap_pv_remove(pg, pmap, va);
pg->mdpage.pvh_attrs |= pmap_pvh_attrs(pte);
- simple_unlock(&pg->mdpage.pvh_lock);
}
} else {
DPRINTF(PDB_ENTER,
if (pmap_initialized && (pg = PHYS_TO_VM_PAGE(pa))) {
if (!pve && !(pve = pmap_pv_alloc())) {
- if (flags & PMAP_CANFAIL) {
- simple_unlock(&pg->mdpage.pvh_lock);
- simple_unlock(&pmap->pm_lock);
+ if (flags & PMAP_CANFAIL)
return (ENOMEM);
- }
panic("pmap_enter: no pv entries available");
}
pte |= pmap_prot(pmap, prot);
- simple_lock(&pg->mdpage.pvh_lock);
if (pmap_check_alias(pg->mdpage.pvh_list, va, pte))
pmap_page_remove(pg);
pmap_pv_enter(pg, pve, pmap, va, ptp);
- simple_unlock(&pg->mdpage.pvh_lock);
} else if (pve)
pmap_pv_free(pve);
pte |= PTE_WIRED;
pmap_pte_set(pde, va, pte);
- simple_unlock(&pmap->pm_lock);
-
DPRINTF(PDB_FOLLOW|PDB_ENTER, ("pmap_enter: leaving\n"));
return (0);
DPRINTF(PDB_FOLLOW|PDB_REMOVE,
("pmap_remove(%p, 0x%lx, 0x%lx)\n", pmap, sva, eva));
- simple_lock(&pmap->pm_lock);
-
for (batch = 0; sva < eva; sva += PAGE_SIZE) {
pdemask = sva & (PDE_MASK|PIE_MASK);
if (!(pde = pmap_pde_get(pmap->pm_pdir, sva))) {
if (pmap_initialized &&
(pg = PHYS_TO_VM_PAGE(PTE_PAGE(pte)))) {
- simple_lock(&pg->mdpage.pvh_lock);
pg->mdpage.pvh_attrs |= pmap_pvh_attrs(pte);
if ((pve = pmap_pv_remove(pg, pmap, sva)))
pmap_pv_free(pve);
- simple_unlock(&pg->mdpage.pvh_lock);
} else {
if (IS_IOPAGE(PTE_PAGE(pte))) {
ptp = pmap_pde_ptp(pmap, pde);
}
}
- simple_unlock(&pmap->pm_lock);
-
DPRINTF(PDB_FOLLOW|PDB_REMOVE, ("pmap_remove: leaving\n"));
}
sva = trunc_page(sva);
tlbprot = pmap_prot(pmap, prot);
- simple_lock(&pmap->pm_lock);
-
for (pdemask = 1; sva < eva; sva += PAGE_SIZE) {
if (pdemask != (sva & (PDE_MASK|PIE_MASK))) {
pdemask = sva & (PDE_MASK|PIE_MASK);
continue;
pg = PHYS_TO_VM_PAGE(PTE_PAGE(pte));
- if (pg != NULL) {
- simple_lock(&pg->mdpage.pvh_lock);
+ if (pg != NULL)
pg->mdpage.pvh_attrs |= pmap_pvh_attrs(pte);
- simple_unlock(&pg->mdpage.pvh_lock);
- }
pmap_pte_flush(pmap, sva, pte);
pte &= ~PTE_ACC_MASK;
pmap_pte_set(pde, sva, pte);
}
}
-
- simple_unlock(&pmap->pm_lock);
}
void
if (pg->mdpage.pvh_list == NULL)
return;
- simple_lock(&pg->mdpage.pvh_lock);
for (pve = pg->mdpage.pvh_list; pve;
pve = (ppve = pve)->pv_next, pmap_pv_free(ppve)) {
struct pmap *pmap = pve->pv_pmap;
volatile pt_entry_t *pde;
pt_entry_t pte;
- simple_lock(&pmap->pm_lock);
-
pde = pmap_pde_get(pmap->pm_pdir, va);
pte = pmap_pte_get(pde, va);
pg->mdpage.pvh_attrs |= pmap_pvh_attrs(pte);
pmap->pm_stats.resident_count--;
pmap_pte_set(pde, va, 0);
- simple_unlock(&pmap->pm_lock);
}
pg->mdpage.pvh_list = NULL;
- simple_unlock(&pg->mdpage.pvh_lock);
DPRINTF(PDB_FOLLOW|PDB_PV, ("pmap_page_remove: leaving\n"));
DPRINTF(PDB_FOLLOW|PDB_PMAP, ("pmap_unwire(%p, 0x%lx)\n", pmap, va));
- simple_lock(&pmap->pm_lock);
if ((pde = pmap_pde_get(pmap->pm_pdir, va))) {
pte = pmap_pte_get(pde, va);
pmap_pte_set(pde, va, pte);
}
}
- simple_unlock(&pmap->pm_lock);
DPRINTF(PDB_FOLLOW|PDB_PMAP, ("pmap_unwire: leaving\n"));
DPRINTF(PDB_FOLLOW|PDB_BITS,
("pmap_changebit(%p, %lx, %lx)\n", pg, (long)set, (long)clear));
- simple_lock(&pg->mdpage.pvh_lock);
res = pg->mdpage.pvh_attrs = 0;
for(pve = pg->mdpage.pvh_list; pve; pve = pve->pv_next) {
struct pmap *pmap = pve->pv_pmap;
volatile pt_entry_t *pde;
pt_entry_t opte, pte;
- simple_lock(&pmap->pm_lock);
if ((pde = pmap_pde_get(pmap->pm_pdir, va))) {
opte = pte = pmap_pte_get(pde, va);
#ifdef PMAPDEBUG
pmap_pte_set(pde, va, pte);
}
}
- simple_unlock(&pmap->pm_lock);
}
- simple_unlock(&pg->mdpage.pvh_lock);
return ((res & (clear | set)) != 0);
}
DPRINTF(PDB_FOLLOW|PDB_BITS, ("pmap_testbit(%p, %lx)\n", pg, (long)bit));
- simple_lock(&pg->mdpage.pvh_lock);
for(pve = pg->mdpage.pvh_list; !(pg->mdpage.pvh_attrs & bit) && pve;
pve = pve->pv_next) {
- simple_lock(&pve->pv_pmap->pm_lock);
pte = pmap_vp_find(pve->pv_pmap, pve->pv_va);
- simple_unlock(&pve->pv_pmap->pm_lock);
pg->mdpage.pvh_attrs |= pmap_pvh_attrs(pte);
}
- simple_unlock(&pg->mdpage.pvh_lock);
return ((pg->mdpage.pvh_attrs & bit) != 0);
}
DPRINTF(PDB_FOLLOW|PDB_EXTRACT, ("pmap_extract(%p, %lx)\n", pmap, va));
- simple_lock(&pmap->pm_lock);
pte = pmap_vp_find(pmap, va);
- simple_unlock(&pmap->pm_lock);
if (pte) {
if (pap) {
struct pv_entry *pve;
/* purge cache for all possible mappings for the pa */
- simple_lock(&pg->mdpage.pvh_lock);
for (pve = pg->mdpage.pvh_list; pve; pve = pve->pv_next) {
if (purge)
pdcache(pve->pv_pmap->pm_space, pve->pv_va, PAGE_SIZE);
pdtlb(pve->pv_pmap->pm_space, pve->pv_va);
pitlb(pve->pv_pmap->pm_space, pve->pv_va);
}
- simple_unlock(&pg->mdpage.pvh_lock);
}
void
DPRINTF(PDB_FOLLOW|PDB_ENTER,
("pmap_kenter_pa(%lx, %lx, %x)\n", va, pa, prot));
- simple_lock(&pmap->pm_lock);
-
if (!(pde = pmap_pde_get(pmap_kernel()->pm_pdir, va)) &&
!(pde = pmap_pde_alloc(pmap_kernel(), va, NULL)))
panic("pmap_kenter_pa: cannot allocate pde for va=0x%lx", va);
if (pmap_initialized && (pg = PHYS_TO_VM_PAGE(PTE_PAGE(pte)))) {
- simple_lock(&pg->mdpage.pvh_lock);
if (pmap_check_alias(pg->mdpage.pvh_list, va, pte))
Debugger();
- simple_unlock(&pg->mdpage.pvh_lock);
}
}
#endif
- simple_unlock(&pmap->pm_lock);
-
DPRINTF(PDB_FOLLOW|PDB_ENTER, ("pmap_kenter_pa: leaving\n"));
}
}
#endif
- simple_lock(&pmap->pm_lock);
-
for (pdemask = 1, eva = va + size; va < eva; va += PAGE_SIZE) {
if (pdemask != (va & (PDE_MASK|PIE_MASK))) {
pdemask = va & (PDE_MASK|PIE_MASK);
pmap_pte_set(pde, va, 0);
if (pmap_initialized && (pg = PHYS_TO_VM_PAGE(PTE_PAGE(pte)))) {
- simple_lock(&pg->mdpage.pvh_lock);
pg->mdpage.pvh_attrs |= pmap_pvh_attrs(pte);
/* just in case we have enter/kenter mismatch */
if ((pve = pmap_pv_remove(pg, pmap_kernel(), va)))
pmap_pv_free(pve);
- simple_unlock(&pg->mdpage.pvh_lock);
}
}
- simple_unlock(&pmap->pm_lock);
-
DPRINTF(PDB_FOLLOW|PDB_REMOVE, ("pmap_kremove: leaving\n"));
}