diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2002-06-02 22:16:53 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2002-06-02 22:16:53 +0000 |
commit | 79ec5f1cb9103d22ecbe683299c3d7bb72e8cb6e (patch) | |
tree | aa698559ce6c5b8bc7b08fc75ce38b9f22810fb3 /sys/arch/m68k | |
parent | 8c7a91c38f582950fd5386dba1e1be5c911f2aff (diff) |
Implement PMAP_CANFAIL handling for m68k shared pmap module.
Diffstat (limited to 'sys/arch/m68k')
-rw-r--r-- | sys/arch/m68k/m68k/pmap_motorola.c | 48 |
1 files changed, 34 insertions, 14 deletions
diff --git a/sys/arch/m68k/m68k/pmap_motorola.c b/sys/arch/m68k/m68k/pmap_motorola.c index fc40677296c..269eea75365 100644 --- a/sys/arch/m68k/m68k/pmap_motorola.c +++ b/sys/arch/m68k/m68k/pmap_motorola.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap_motorola.c,v 1.18 2002/04/16 20:49:49 miod Exp $ */ +/* $OpenBSD: pmap_motorola.c,v 1.19 2002/06/02 22:16:52 miod Exp $ */ /* * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -320,7 +320,7 @@ int pmap_mapmulti(pmap_t, vaddr_t); void pmap_remove_mapping(pmap_t, vaddr_t, pt_entry_t *, int); boolean_t pmap_testbit(paddr_t, int); void pmap_changebit(paddr_t, int, int); -void pmap_enter_ptpage(pmap_t, vaddr_t); +int pmap_enter_ptpage(pmap_t, vaddr_t); void pmap_ptpage_addref(vaddr_t); int pmap_ptpage_delref(vaddr_t); void pmap_collect1(pmap_t, paddr_t, paddr_t); @@ -594,8 +594,8 @@ pmap_alloc_pv() if (pv_nfree == 0) { pvp = (struct pv_page *)uvm_km_zalloc(kernel_map, PAGE_SIZE); - if (pvp == 0) - panic("pmap_alloc_pv: uvm_km_zalloc() failed"); + if (pvp == NULL) + return NULL; pvp->pvp_pgi.pgi_freelist = pv = &pvp->pvp_pv[1]; for (i = NPVPPG - 2; i; i--, pv++) pv->pv_next = pv + 1; @@ -1129,7 +1129,7 @@ pmap_enter(pmap, va, pa, prot, flags) int flags; { pt_entry_t *pte; - int npte; + int npte, error; paddr_t opa; boolean_t cacheable = TRUE; boolean_t checkpv = TRUE; @@ -1158,8 +1158,15 @@ pmap_enter(pmap, va, pa, prot, flags) /* * Segment table entry not valid, we need a new PT page */ - if (!pmap_ste_v(pmap, va)) - pmap_enter_ptpage(pmap, va); + if (!pmap_ste_v(pmap, va)) { + error = pmap_enter_ptpage(pmap, va); + if (error != 0) { + if (flags & PMAP_CANFAIL) + return (error); + else + panic("pmap_enter: out of address space"); + } + } pa = trunc_page(pa); pte = pmap_pte(pmap, va); @@ -1250,6 +1257,13 @@ pmap_enter(pmap, va, pa, prot, flags) panic("pmap_enter: already in pv_tab"); #endif npv = pmap_alloc_pv(); + if (npv == NULL) { + if (flags & PMAP_CANFAIL) { + splx(s); + return (ENOMEM); + } else + panic("pmap_enter: uvm_km_zalloc() failed"); + } npv->pv_va = va; npv->pv_pmap = pmap; npv->pv_next = pv->pv_next; @@ -1416,7 +1430,7 @@ pmap_kenter_pa(va, pa, prot) { struct pmap *pmap = pmap_kernel(); pt_entry_t *pte; - int s, npte; + int s, npte, error; PMAP_DPRINTF(PDB_FOLLOW|PDB_ENTER, ("pmap_kenter_pa(%lx, %lx, %x)\n", va, pa, prot)); @@ -1427,7 +1441,9 @@ pmap_kenter_pa(va, pa, prot) if (!pmap_ste_v(pmap, va)) { s = splvm(); - pmap_enter_ptpage(pmap, va); + error = pmap_enter_ptpage(pmap, va); + if (error != 0) + panic("pmap_kenter_pa: out of address space"); splx(s); } @@ -2564,7 +2580,7 @@ pmap_changebit(pa, set, mask) * Allocate and map a PT page for the specified pmap/va pair. */ /* static */ -void +int pmap_enter_ptpage(pmap, va) pmap_t pmap; vaddr_t va; @@ -2639,8 +2655,9 @@ pmap_enter_ptpage(pmap, va) caddr_t addr; ix = bmtol2(pmap->pm_stfree); - if (ix == -1) - panic("enter: out of address space"); /* XXX */ + if (ix == -1) { + return (ENOMEM); + } pmap->pm_stfree &= ~l2tobm(ix); addr = (caddr_t)&pmap->pm_stab[ix*SG4_LEV2SIZE]; bzero(addr, SG4_LEV2SIZE*sizeof(st_entry_t)); @@ -2684,8 +2701,10 @@ pmap_enter_ptpage(pmap, va) PMAP_DPRINTF(PDB_COLLECT, ("enter: no KPT pages, collecting...\n")); pmap_collect(pmap_kernel()); - if ((kpt = kpt_free_list) == NULL) - panic("pmap_enter_ptpage: can't get KPT page"); + if ((kpt = kpt_free_list) == NULL) { + splx(s); + return (ENOMEM); + } } kpt_free_list = kpt->kpt_next; kpt->kpt_next = kpt_used_list; @@ -2823,6 +2842,7 @@ pmap_enter_ptpage(pmap, va) #endif pmap->pm_ptpages++; splx(s); + return (0); } /* |