git: ef9017aa174d - main - pmap_growkernel(): do not panic immediately, optionally return the error
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 19 Jun 2025 22:26:26 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=ef9017aa174db96ee741b936b984f2b5d61dff9f
commit ef9017aa174db96ee741b936b984f2b5d61dff9f
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-12-05 20:54:35 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-06-19 22:25:56 +0000
pmap_growkernel(): do not panic immediately, optionally return the error
Reviewed by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D47935
---
sys/amd64/amd64/pmap.c | 40 +++++++++++++++++++++++++++++--------
sys/arm/arm/pmap-v6.c | 23 ++++++++++++++++++---
sys/arm64/arm64/pmap.c | 25 +++++++++++++++++++----
sys/i386/i386/pmap.c | 6 ++++--
sys/i386/i386/pmap_base.c | 14 +++++++++++--
sys/i386/include/pmap_base.h | 2 +-
sys/powerpc/aim/mmu_radix.c | 13 ++++++------
sys/powerpc/include/mmuvar.h | 4 ++--
sys/powerpc/powerpc/pmap_dispatch.c | 19 +++++++++++++++++-
sys/riscv/riscv/pmap.c | 27 +++++++++++++++++++++----
sys/vm/pmap.h | 2 +-
sys/vm/vm_map.c | 9 +++++++--
12 files changed, 148 insertions(+), 36 deletions(-)
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 2962f2823596..6d1c2d70d8c0 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -578,6 +578,11 @@ static pml4_entry_t *pti_pml4;
static vm_pindex_t pti_pg_idx;
static bool pti_finalized;
+static int pmap_growkernel_panic = 0;
+SYSCTL_INT(_vm_pmap, OID_AUTO, growkernel_panic, CTLFLAG_RDTUN,
+ &pmap_growkernel_panic, 0,
+ "panic on failure to allocate kernel page table page");
+
struct pmap_pkru_range {
struct rs_el pkru_rs_el;
u_int pkru_keyidx;
@@ -5124,17 +5129,19 @@ pmap_page_array_startup(long pages)
/*
* grow the number of kernel page table entries, if needed
*/
-void
-pmap_growkernel(vm_offset_t addr)
+static int
+pmap_growkernel_nopanic(vm_offset_t addr)
{
vm_paddr_t paddr;
vm_page_t nkpg;
pd_entry_t *pde, newpdir;
pdp_entry_t *pdpe;
vm_offset_t end;
+ int rv;
TSENTER();
mtx_assert(&kernel_map->system_mtx, MA_OWNED);
+ rv = KERN_SUCCESS;
/*
* The kernel map covers two distinct regions of KVA: that used
@@ -5162,7 +5169,7 @@ pmap_growkernel(vm_offset_t addr)
end = KERNBASE + nkpt * NBPDR;
if (end == 0) {
TSEXIT();
- return;
+ return (rv);
}
} else {
end = kernel_vm_end;
@@ -5177,7 +5184,7 @@ pmap_growkernel(vm_offset_t addr)
* nothing to do.
*/
TSEXIT();
- return;
+ return (rv);
}
kasan_shadow_map(end, addr - end);
@@ -5188,8 +5195,10 @@ pmap_growkernel(vm_offset_t addr)
nkpg = pmap_alloc_pt_page(kernel_pmap,
pmap_pdpe_pindex(end), VM_ALLOC_INTERRUPT |
VM_ALLOC_NOFREE | VM_ALLOC_WIRED | VM_ALLOC_ZERO);
- if (nkpg == NULL)
- panic("pmap_growkernel: no memory to grow kernel");
+ if (nkpg == NULL) {
+ rv = KERN_RESOURCE_SHORTAGE;
+ break;
+ }
paddr = VM_PAGE_TO_PHYS(nkpg);
*pdpe = (pdp_entry_t)(paddr | X86_PG_V | X86_PG_RW |
X86_PG_A | X86_PG_M);
@@ -5208,8 +5217,11 @@ pmap_growkernel(vm_offset_t addr)
nkpg = pmap_alloc_pt_page(kernel_pmap, pmap_pde_pindex(end),
VM_ALLOC_INTERRUPT | VM_ALLOC_NOFREE | VM_ALLOC_WIRED |
VM_ALLOC_ZERO);
- if (nkpg == NULL)
- panic("pmap_growkernel: no memory to grow kernel");
+ if (nkpg == NULL) {
+ rv = KERN_RESOURCE_SHORTAGE;
+ break;
+ }
+
paddr = VM_PAGE_TO_PHYS(nkpg);
newpdir = paddr | X86_PG_V | X86_PG_RW | X86_PG_A | X86_PG_M;
pde_store(pde, newpdir);
@@ -5226,6 +5238,18 @@ pmap_growkernel(vm_offset_t addr)
else
nkpt = howmany(end - KERNBASE, NBPDR);
TSEXIT();
+ return (rv);
+}
+
+int
+pmap_growkernel(vm_offset_t addr)
+{
+ int rv;
+
+ rv = pmap_growkernel_nopanic(addr);
+ if (rv != KERN_SUCCESS && pmap_growkernel_panic)
+ panic("pmap_growkernel: no memory to grow kernel");
+ return (rv);
}
/***************************************************
diff --git a/sys/arm/arm/pmap-v6.c b/sys/arm/arm/pmap-v6.c
index a0158bb128e7..92eb0589f80b 100644
--- a/sys/arm/arm/pmap-v6.c
+++ b/sys/arm/arm/pmap-v6.c
@@ -1577,6 +1577,11 @@ static int sp_enabled = 1;
SYSCTL_INT(_vm_pmap, OID_AUTO, sp_enabled, CTLFLAG_RDTUN | CTLFLAG_NOFETCH,
&sp_enabled, 0, "Are large page mappings enabled?");
+static int pmap_growkernel_panic = 0;
+SYSCTL_INT(_vm_pmap, OID_AUTO, growkernel_panic, CTLFLAG_RDTUN,
+ &pmap_growkernel_panic, 0,
+ "panic on failure to allocate kernel page table page");
+
bool
pmap_ps_enabled(pmap_t pmap __unused)
{
@@ -2031,8 +2036,8 @@ pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
/*
* Grow the number of kernel L2 page table entries, if needed.
*/
-void
-pmap_growkernel(vm_offset_t addr)
+static int
+pmap_growkernel_nopanic(vm_offset_t addr)
{
vm_page_t m;
vm_paddr_t pt2pg_pa, pt2_pa;
@@ -2085,7 +2090,7 @@ pmap_growkernel(vm_offset_t addr)
m = vm_page_alloc_noobj(VM_ALLOC_INTERRUPT |
VM_ALLOC_NOFREE | VM_ALLOC_WIRED | VM_ALLOC_ZERO);
if (m == NULL)
- panic("%s: no memory to grow kernel", __func__);
+ return (KERN_RESOURCE_SHORTAGE);
m->pindex = pte1_index(kernel_vm_end) & ~PT2PG_MASK;
/*
@@ -2110,6 +2115,18 @@ pmap_growkernel(vm_offset_t addr)
break;
}
}
+ return (KERN_SUCCESS);
+}
+
+int
+pmap_growkernel(vm_offset_t addr)
+{
+ int rv;
+
+ rv = pmap_growkernel_nopanic(addr);
+ if (rv != KERN_SUCCESS && pmap_growkernel_panic)
+ panic("pmap_growkernel: no memory to grow kernel");
+ return (rv);
}
static int
diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c
index a53e8b3684e3..d2e56a270f54 100644
--- a/sys/arm64/arm64/pmap.c
+++ b/sys/arm64/arm64/pmap.c
@@ -357,6 +357,11 @@ static u_int physmap_idx;
static SYSCTL_NODE(_vm, OID_AUTO, pmap, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
"VM/pmap parameters");
+static int pmap_growkernel_panic = 0;
+SYSCTL_INT(_vm_pmap, OID_AUTO, growkernel_panic, CTLFLAG_RDTUN,
+ &pmap_growkernel_panic, 0,
+ "panic on failure to allocate kernel page table page");
+
bool pmap_lpa_enabled __read_mostly = false;
pt_entry_t pmap_sh_attr __read_mostly = ATTR_SH(ATTR_SH_IS);
@@ -3096,8 +3101,8 @@ SYSCTL_PROC(_vm, OID_AUTO, kvm_free, CTLTYPE_LONG | CTLFLAG_RD | CTLFLAG_MPSAFE,
/*
* grow the number of kernel page table entries, if needed
*/
-void
-pmap_growkernel(vm_offset_t addr)
+static int
+pmap_growkernel_nopanic(vm_offset_t addr)
{
vm_page_t nkpg;
pd_entry_t *l0, *l1, *l2;
@@ -3122,7 +3127,7 @@ pmap_growkernel(vm_offset_t addr)
nkpg = vm_page_alloc_noobj(VM_ALLOC_INTERRUPT |
VM_ALLOC_NOFREE | VM_ALLOC_WIRED | VM_ALLOC_ZERO);
if (nkpg == NULL)
- panic("pmap_growkernel: no memory to grow kernel");
+ return (KERN_RESOURCE_SHORTAGE);
nkpg->pindex = pmap_l1_pindex(kernel_vm_end);
/* See the dmb() in _pmap_alloc_l3(). */
dmb(ishst);
@@ -3142,7 +3147,7 @@ pmap_growkernel(vm_offset_t addr)
nkpg = vm_page_alloc_noobj(VM_ALLOC_INTERRUPT |
VM_ALLOC_NOFREE | VM_ALLOC_WIRED | VM_ALLOC_ZERO);
if (nkpg == NULL)
- panic("pmap_growkernel: no memory to grow kernel");
+ return (KERN_RESOURCE_SHORTAGE);
nkpg->pindex = pmap_l2_pindex(kernel_vm_end);
/* See the dmb() in _pmap_alloc_l3(). */
dmb(ishst);
@@ -3154,6 +3159,18 @@ pmap_growkernel(vm_offset_t addr)
break;
}
}
+ return (KERN_SUCCESS);
+}
+
+int
+pmap_growkernel(vm_offset_t addr)
+{
+ int rv;
+
+ rv = pmap_growkernel_nopanic(addr);
+ if (rv != KERN_SUCCESS && pmap_growkernel_panic)
+ panic("pmap_growkernel: no memory to grow kernel");
+ return (rv);
}
/***************************************************
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index 89701c1061b0..465b4d0f365b 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -2234,7 +2234,7 @@ __CONCAT(PMTYPE, release)(pmap_t pmap)
/*
* grow the number of kernel page table entries, if needed
*/
-static void
+static int
__CONCAT(PMTYPE, growkernel)(vm_offset_t addr)
{
vm_paddr_t ptppaddr;
@@ -2258,7 +2258,7 @@ __CONCAT(PMTYPE, growkernel)(vm_offset_t addr)
nkpg = vm_page_alloc_noobj(VM_ALLOC_INTERRUPT |
VM_ALLOC_NOFREE | VM_ALLOC_WIRED | VM_ALLOC_ZERO);
if (nkpg == NULL)
- panic("pmap_growkernel: no memory to grow kernel");
+ return (KERN_RESOURCE_SHORTAGE);
nkpg->pindex = kernel_vm_end >> PDRSHIFT;
nkpt++;
@@ -2273,6 +2273,8 @@ __CONCAT(PMTYPE, growkernel)(vm_offset_t addr)
break;
}
}
+
+ return (KERN_SUCCESS);
}
/***************************************************
diff --git a/sys/i386/i386/pmap_base.c b/sys/i386/i386/pmap_base.c
index f6252a7ca5da..cdbfd688f110 100644
--- a/sys/i386/i386/pmap_base.c
+++ b/sys/i386/i386/pmap_base.c
@@ -109,6 +109,7 @@ static SYSCTL_NODE(_vm, OID_AUTO, pmap, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
#include <machine/vmparam.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
+#include <vm/vm_param.h>
#include <vm/pmap.h>
#include <machine/pmap_base.h>
@@ -252,6 +253,11 @@ SYSCTL_INT(_vm_pmap, OID_AUTO, pv_entry_spare, CTLFLAG_RD,
"Current number of spare pv entries");
#endif
+static int pmap_growkernel_panic = 0;
+SYSCTL_INT(_vm_pmap, OID_AUTO, growkernel_panic, CTLFLAG_RDTUN,
+ &pmap_growkernel_panic, 0,
+ "panic on failure to allocate kernel page table page");
+
struct pmap kernel_pmap_store;
static struct pmap_methods *pmap_methods_ptr;
@@ -893,11 +899,15 @@ pmap_init_pat(void)
pmap_methods_ptr->pm_init_pat();
}
-void
+int
pmap_growkernel(vm_offset_t addr)
{
+ int rv;
- pmap_methods_ptr->pm_growkernel(addr);
+ rv = pmap_methods_ptr->pm_growkernel(addr);
+ if (rv != KERN_SUCCESS && pmap_growkernel_panic)
+ panic("pmap_growkernel: no memory to grow kernel");
+ return (rv);
}
void
diff --git a/sys/i386/include/pmap_base.h b/sys/i386/include/pmap_base.h
index 1a13da16e39c..20f814195281 100644
--- a/sys/i386/include/pmap_base.h
+++ b/sys/i386/include/pmap_base.h
@@ -107,7 +107,7 @@ struct pmap_methods {
void (*pm_remove_all)(vm_page_t);
void (*pm_init)(void);
void (*pm_init_pat)(void);
- void (*pm_growkernel)(vm_offset_t);
+ int (*pm_growkernel)(vm_offset_t);
void (*pm_invalidate_page)(pmap_t, vm_offset_t);
void (*pm_invalidate_range)(pmap_t, vm_offset_t, vm_offset_t);
void (*pm_invalidate_all)(pmap_t);
diff --git a/sys/powerpc/aim/mmu_radix.c b/sys/powerpc/aim/mmu_radix.c
index cda8dd1c0946..45f7bef8bcc9 100644
--- a/sys/powerpc/aim/mmu_radix.c
+++ b/sys/powerpc/aim/mmu_radix.c
@@ -480,7 +480,7 @@ static void mmu_radix_bootstrap(vm_offset_t, vm_offset_t);
static void mmu_radix_copy_page(vm_page_t, vm_page_t);
static void mmu_radix_copy_pages(vm_page_t *ma, vm_offset_t a_offset,
vm_page_t *mb, vm_offset_t b_offset, int xfersize);
-static void mmu_radix_growkernel(vm_offset_t);
+static int mmu_radix_growkernel(vm_offset_t);
static void mmu_radix_init(void);
static int mmu_radix_mincore(pmap_t, vm_offset_t, vm_paddr_t *);
static vm_offset_t mmu_radix_map(vm_offset_t *, vm_paddr_t, vm_paddr_t, int);
@@ -501,7 +501,7 @@ static struct pmap_funcs mmu_radix_methods = {
.copy_page = mmu_radix_copy_page,
.copy_pages = mmu_radix_copy_pages,
.cpu_bootstrap = mmu_radix_cpu_bootstrap,
- .growkernel = mmu_radix_growkernel,
+ .growkernel_nopanic = mmu_radix_growkernel,
.init = mmu_radix_init,
.map = mmu_radix_map,
.mincore = mmu_radix_mincore,
@@ -3560,7 +3560,7 @@ mmu_radix_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
return (m);
}
-static void
+static int
mmu_radix_growkernel(vm_offset_t addr)
{
vm_paddr_t paddr;
@@ -3571,7 +3571,7 @@ mmu_radix_growkernel(vm_offset_t addr)
CTR2(KTR_PMAP, "%s(%#x)", __func__, addr);
if (VM_MIN_KERNEL_ADDRESS < addr &&
addr < (VM_MIN_KERNEL_ADDRESS + nkpt * L3_PAGE_SIZE))
- return;
+ return (KERN_SUCCESS);
addr = roundup2(addr, L3_PAGE_SIZE);
if (addr - 1 >= vm_map_max(kernel_map))
@@ -3583,7 +3583,7 @@ mmu_radix_growkernel(vm_offset_t addr)
nkpg = vm_page_alloc_noobj(VM_ALLOC_INTERRUPT |
VM_ALLOC_NOFREE | VM_ALLOC_WIRED | VM_ALLOC_ZERO);
if (nkpg == NULL)
- panic("pmap_growkernel: no memory to grow kernel");
+ return (KERN_RESOURCE_SHORTAGE);
nkpg->pindex = kernel_vm_end >> L2_PAGE_SIZE_SHIFT;
paddr = VM_PAGE_TO_PHYS(nkpg);
pde_store(l2e, paddr);
@@ -3602,7 +3602,7 @@ mmu_radix_growkernel(vm_offset_t addr)
nkpg = vm_page_alloc_noobj(VM_ALLOC_INTERRUPT |
VM_ALLOC_NOFREE | VM_ALLOC_WIRED | VM_ALLOC_ZERO);
if (nkpg == NULL)
- panic("pmap_growkernel: no memory to grow kernel");
+ return (KERN_RESOURCE_SHORTAGE);
nkpg->pindex = pmap_l3e_pindex(kernel_vm_end);
paddr = VM_PAGE_TO_PHYS(nkpg);
pde_store(l3e, paddr);
@@ -3614,6 +3614,7 @@ mmu_radix_growkernel(vm_offset_t addr)
}
}
ptesync();
+ return (KERN_SUCCESS);
}
static MALLOC_DEFINE(M_RADIX_PGD, "radix_pgd", "radix page table root directory");
diff --git a/sys/powerpc/include/mmuvar.h b/sys/powerpc/include/mmuvar.h
index 4d0c3d90616f..9cf7a682ddd5 100644
--- a/sys/powerpc/include/mmuvar.h
+++ b/sys/powerpc/include/mmuvar.h
@@ -60,7 +60,7 @@ typedef void (*pmap_enter_object_t)(pmap_t, vm_offset_t, vm_offset_t,
typedef void (*pmap_enter_quick_t)(pmap_t, vm_offset_t, vm_page_t, vm_prot_t);
typedef vm_paddr_t (*pmap_extract_t)(pmap_t, vm_offset_t);
typedef vm_page_t (*pmap_extract_and_hold_t)(pmap_t, vm_offset_t, vm_prot_t);
-typedef void (*pmap_growkernel_t)(vm_offset_t);
+typedef int (*pmap_growkernel_nopanic_t)(vm_offset_t);
typedef void (*pmap_init_t)(void);
typedef bool (*pmap_is_modified_t)(vm_page_t);
typedef bool (*pmap_is_prefaultable_t)(pmap_t, vm_offset_t);
@@ -130,7 +130,7 @@ struct pmap_funcs {
pmap_enter_quick_t enter_quick;
pmap_extract_t extract;
pmap_extract_and_hold_t extract_and_hold;
- pmap_growkernel_t growkernel;
+ pmap_growkernel_nopanic_t growkernel_nopanic;
pmap_init_t init;
pmap_is_modified_t is_modified;
pmap_is_prefaultable_t is_prefaultable;
diff --git a/sys/powerpc/powerpc/pmap_dispatch.c b/sys/powerpc/powerpc/pmap_dispatch.c
index c87e65c5b23e..95806377c03d 100644
--- a/sys/powerpc/powerpc/pmap_dispatch.c
+++ b/sys/powerpc/powerpc/pmap_dispatch.c
@@ -54,6 +54,7 @@
#include <vm/vm.h>
#include <vm/vm_extern.h>
#include <vm/vm_page.h>
+#include <vm/vm_param.h>
#include <machine/dump.h>
#include <machine/ifunc.h>
@@ -85,6 +86,11 @@ int superpages_enabled = 1;
SYSCTL_INT(_vm_pmap, OID_AUTO, superpages_enabled, CTLFLAG_RDTUN,
&superpages_enabled, 0, "Enable support for transparent superpages");
+static int pmap_growkernel_panic = 0;
+SYSCTL_INT(_vm_pmap, OID_AUTO, growkernel_panic, CTLFLAG_RDTUN,
+ &pmap_growkernel_panic, 0,
+ "panic on failure to allocate kernel page table page");
+
#ifdef AIM
int
pvo_vaddr_compare(struct pvo_entry *a, struct pvo_entry *b)
@@ -161,7 +167,7 @@ DEFINE_PMAP_IFUNC(void, copy_page, (vm_page_t, vm_page_t));
DEFINE_PMAP_IFUNC(void, copy_pages,
(vm_page_t ma[], vm_offset_t a_offset, vm_page_t mb[],
vm_offset_t b_offset, int xfersize));
-DEFINE_PMAP_IFUNC(void, growkernel, (vm_offset_t));
+DEFINE_PMAP_IFUNC(int, growkernel_nopanic, (vm_offset_t));
DEFINE_PMAP_IFUNC(void, init, (void));
DEFINE_PMAP_IFUNC(vm_offset_t, map, (vm_offset_t *, vm_paddr_t, vm_paddr_t, int));
DEFINE_PMAP_IFUNC(int, pinit, (pmap_t));
@@ -259,3 +265,14 @@ pmap_active_cpus(pmap_t pmap, cpuset_t *res)
{
*res = pmap->pm_active;
}
+
+int
+pmap_growkernel(vm_offset_t addr)
+{
+ int rv;
+
+ rv = pmap_growkernel_nopanic(addr);
+ if (rv != KERN_SUCCESS && pmap_growkernel_panic)
+ panic("pmap_growkernel: no memory to grow kernel");
+ return (rv);
+}
diff --git a/sys/riscv/riscv/pmap.c b/sys/riscv/riscv/pmap.c
index f756e98335f3..5d15bd671285 100644
--- a/sys/riscv/riscv/pmap.c
+++ b/sys/riscv/riscv/pmap.c
@@ -241,6 +241,11 @@ vm_paddr_t dmap_phys_base; /* The start of the dmap region */
vm_paddr_t dmap_phys_max; /* The limit of the dmap region */
vm_offset_t dmap_max_addr; /* The virtual address limit of the dmap */
+static int pmap_growkernel_panic = 0;
+SYSCTL_INT(_vm_pmap, OID_AUTO, growkernel_panic, CTLFLAG_RDTUN,
+ &pmap_growkernel_panic, 0,
+ "panic on failure to allocate kernel page table page");
+
/* This code assumes all L1 DMAP entries will be used */
CTASSERT((DMAP_MIN_ADDRESS & ~L1_OFFSET) == DMAP_MIN_ADDRESS);
CTASSERT((DMAP_MAX_ADDRESS & ~L1_OFFSET) == DMAP_MAX_ADDRESS);
@@ -1873,8 +1878,8 @@ SYSCTL_PROC(_vm, OID_AUTO, kvm_free, CTLTYPE_LONG | CTLFLAG_RD | CTLFLAG_MPSAFE,
/*
* grow the number of kernel page table entries, if needed
*/
-void
-pmap_growkernel(vm_offset_t addr)
+static int
+pmap_growkernel_nopanic(vm_offset_t addr)
{
vm_paddr_t paddr;
vm_page_t nkpg;
@@ -1894,7 +1899,8 @@ pmap_growkernel(vm_offset_t addr)
nkpg = vm_page_alloc_noobj(VM_ALLOC_INTERRUPT |
VM_ALLOC_NOFREE | VM_ALLOC_WIRED | VM_ALLOC_ZERO);
if (nkpg == NULL)
- panic("%s: no memory to grow kernel", __func__);
+ return (KERN_RESOURCE_SHORTAGE);
+
nkpg->pindex = pmap_l1_pindex(kernel_vm_end);
paddr = VM_PAGE_TO_PHYS(nkpg);
@@ -1920,7 +1926,7 @@ pmap_growkernel(vm_offset_t addr)
nkpg = vm_page_alloc_noobj(VM_ALLOC_INTERRUPT |
VM_ALLOC_NOFREE | VM_ALLOC_WIRED | VM_ALLOC_ZERO);
if (nkpg == NULL)
- panic("%s: no memory to grow kernel", __func__);
+ return (KERN_RESOURCE_SHORTAGE);
nkpg->pindex = pmap_l2_pindex(kernel_vm_end);
paddr = VM_PAGE_TO_PHYS(nkpg);
@@ -1937,6 +1943,19 @@ pmap_growkernel(vm_offset_t addr)
break;
}
}
+
+ return (KERN_SUCCESS);
+}
+
+int
+pmap_growkernel(vm_offset_t addr)
+{
+ int rv;
+
+ rv = pmap_growkernel_nopanic(addr);
+ if (rv != KERN_SUCCESS && pmap_growkernel_panic)
+ panic("pmap_growkernel: no memory to grow kernel");
+ return (rv);
}
/***************************************************
diff --git a/sys/vm/pmap.h b/sys/vm/pmap.h
index 9101201287b2..62da6a5e7ff4 100644
--- a/sys/vm/pmap.h
+++ b/sys/vm/pmap.h
@@ -136,7 +136,7 @@ void pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m,
vm_paddr_t pmap_extract(pmap_t pmap, vm_offset_t va);
vm_page_t pmap_extract_and_hold(pmap_t pmap, vm_offset_t va,
vm_prot_t prot);
-void pmap_growkernel(vm_offset_t);
+int pmap_growkernel(vm_offset_t);
void pmap_init(void);
bool pmap_is_modified(vm_page_t m);
bool pmap_is_prefaultable(pmap_t pmap, vm_offset_t va);
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index c6182f9ce30f..6b09552c5fee 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -1711,8 +1711,13 @@ vm_map_insert1(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
charged:
/* Expand the kernel pmap, if necessary. */
- if (map == kernel_map && end > kernel_vm_end)
- pmap_growkernel(end);
+ if (map == kernel_map && end > kernel_vm_end) {
+ int rv;
+
+ rv = pmap_growkernel(end);
+ if (rv != KERN_SUCCESS)
+ return (rv);
+ }
if (object != NULL) {
/*
* OBJ_ONEMAPPING must be cleared unless this mapping