summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2009-07-21 22:34:03 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2009-07-21 22:34:03 +0000
commit2d263036cd1898bec0b94d2065d0844222661f49 (patch)
treeb214f323161f39f16df85b382898cec96db17daf /sys/arch
parent99c98641e7aa8125661822dd134269b4fcabea53 (diff)
Make pmap_enter respect the PMAP_CANFAIL flag. With and essential
memory leak plug from drahn@
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/powerpc/powerpc/pmap.c36
1 files changed, 26 insertions, 10 deletions
diff --git a/sys/arch/powerpc/powerpc/pmap.c b/sys/arch/powerpc/powerpc/pmap.c
index f25a4d8c924..3b9127e2892 100644
--- a/sys/arch/powerpc/powerpc/pmap.c
+++ b/sys/arch/powerpc/powerpc/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.107 2008/10/17 14:04:07 drahn Exp $ */
+/* $OpenBSD: pmap.c,v 1.108 2009/07/21 22:34:02 kettenis Exp $ */
/*
* Copyright (c) 2001, 2002, 2007 Dale Rahn.
@@ -102,7 +102,7 @@ void pmap_page_ro32(pmap_t pm, vaddr_t va);
/* VP routines */
-void pmap_vp_enter(pmap_t pm, vaddr_t va, struct pte_desc *pted);
+int pmap_vp_enter(pmap_t pm, vaddr_t va, struct pte_desc *pted, int flags);
struct pte_desc *pmap_vp_remove(pmap_t pm, vaddr_t va);
void pmap_vp_destroy(pmap_t pm);
struct pte_desc *pmap_vp_lookup(pmap_t pm, vaddr_t va);
@@ -309,8 +309,8 @@ pmap_vp_remove(pmap_t pm, vaddr_t va)
*
* Should this be called under splvm?
*/
-void
-pmap_vp_enter(pmap_t pm, vaddr_t va, struct pte_desc *pted)
+int
+pmap_vp_enter(pmap_t pm, vaddr_t va, struct pte_desc *pted, int flags)
{
struct pmapvp *vp1;
struct pmapvp *vp2;
@@ -323,8 +323,11 @@ pmap_vp_enter(pmap_t pm, vaddr_t va, struct pte_desc *pted)
s = splvm();
vp1 = pool_get(&pmap_vp_pool, PR_NOWAIT | PR_ZERO);
splx(s);
- if (vp1 == NULL)
- panic("pmap_vp_enter: failed to allocate vp1");
+ if (vp1 == NULL) {
+ if ((flags & PMAP_CANFAIL) == 0)
+ panic("pmap_vp_enter: failed to allocate vp1");
+ return ENOMEM;
+ }
pm->pm_vp[VP_SR(va)] = vp1;
}
@@ -333,14 +336,19 @@ pmap_vp_enter(pmap_t pm, vaddr_t va, struct pte_desc *pted)
s = splvm();
vp2 = pool_get(&pmap_vp_pool, PR_NOWAIT | PR_ZERO);
splx(s);
- if (vp2 == NULL)
- panic("pmap_vp_enter: failed to allocate vp2");
+ if (vp2 == NULL) {
+ if ((flags & PMAP_CANFAIL) == 0)
+ panic("pmap_vp_enter: failed to allocate vp2");
+ return ENOMEM;
+ }
vp1->vp[VP_IDX1(va)] = vp2;
}
vp2->vp[VP_IDX2(va)] = pted;
pmap_simpleunlock_pm(pm);
+
+ return 0;
}
/* PTE manipulation/calculations */
@@ -502,6 +510,7 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags)
int s;
int need_sync = 0;
int cache;
+ int error;
/* MP - Acquire lock for this pmap */
@@ -519,9 +528,16 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags)
/* Do not have pted for this, get one and put it in VP */
if (pted == NULL) {
pted = pool_get(&pmap_pted_pool, PR_NOWAIT | PR_ZERO);
- if (pted == NULL)
+ if (pted == NULL) {
+ if ((flags & PMAP_CANFAIL) == 0)
+ return ENOMEM;
panic("pmap_enter: failed to allocate pted");
- pmap_vp_enter(pm, va, pted);
+ }
+ error = pmap_vp_enter(pm, va, pted, flags);
+ if (error) {
+ pool_put(&pmap_pted_pool, pted);
+ return error;
+ }
}
/* Calculate PTE */