git: bf73594fe0bd - stable/14 - pmap_growkernel(): do not panic immediately, optionally return the error
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 26 Jun 2025 02:43:56 UTC
The branch stable/14 has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=bf73594fe0bd3d56b1035478cbbbdf58c05fe80e
commit bf73594fe0bd3d56b1035478cbbbdf58c05fe80e
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-12-05 20:54:35 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-06-26 02:39:40 +0000
pmap_growkernel(): do not panic immediately, optionally return the error
(cherry picked from commit ef9017aa174db96ee741b936b984f2b5d61dff9f)
---
sys/amd64/amd64/pmap.c | 40 +++++++++++++++++++++++++++++--------
sys/arm/arm/pmap-v6.c | 23 ++++++++++++++++++---
sys/arm64/arm64/pmap.c | 26 +++++++++++++++++++-----
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 | 26 ++++++++++++++++++++----
sys/vm/pmap.h | 2 +-
sys/vm/vm_map.c | 9 +++++++--
12 files changed, 147 insertions(+), 37 deletions(-)
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 1456cee62aeb..8e2c2109e7ad 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -581,6 +581,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;
@@ -5120,17 +5125,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
@@ -5158,7 +5165,7 @@ pmap_growkernel(vm_offset_t addr)
end = KERNBASE + nkpt * NBPDR;
if (end == 0) {
TSEXIT();
- return;
+ return (rv);
}
} else {
end = kernel_vm_end;
@@ -5173,7 +5180,7 @@ pmap_growkernel(vm_offset_t addr)
* nothing to do.
*/
TSEXIT();
- return;
+ return (rv);
}
kasan_shadow_map(end, addr - end);
@@ -5184,8 +5191,10 @@ pmap_growkernel(vm_offset_t addr)
nkpg = pmap_alloc_pt_page(kernel_pmap,
pmap_pdpe_pindex(end), VM_ALLOC_WIRED |
VM_ALLOC_INTERRUPT | 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);
@@ -5203,8 +5212,11 @@ pmap_growkernel(vm_offset_t addr)
nkpg = pmap_alloc_pt_page(kernel_pmap, pmap_pde_pindex(end),
VM_ALLOC_WIRED | VM_ALLOC_INTERRUPT | 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);
@@ -5221,6 +5233,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 5cccb44a48f2..95aeba201e4a 100644
--- a/sys/arm/arm/pmap-v6.c
+++ b/sys/arm/arm/pmap-v6.c
@@ -1561,6 +1561,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)
{
@@ -2017,8 +2022,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;
@@ -2071,7 +2076,7 @@ pmap_growkernel(vm_offset_t addr)
m = vm_page_alloc_noobj(VM_ALLOC_INTERRUPT |
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;
/*
@@ -2096,6 +2101,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 a5d037d7b71c..ef33a7339b9e 100644
--- a/sys/arm64/arm64/pmap.c
+++ b/sys/arm64/arm64/pmap.c
@@ -347,6 +347,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");
+
#if PAGE_SIZE == PAGE_SIZE_4K
#define L1_BLOCKS_SUPPORTED 1
#else
@@ -2700,8 +2705,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;
@@ -2724,8 +2729,7 @@ pmap_growkernel(vm_offset_t addr)
/* We need a new PDP entry */
nkpg = vm_page_alloc_noobj(VM_ALLOC_INTERRUPT |
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 >> L1_SHIFT;
/* See the dmb() in _pmap_alloc_l3(). */
dmb(ishst);
@@ -2746,7 +2750,7 @@ pmap_growkernel(vm_offset_t addr)
nkpg = vm_page_alloc_noobj(VM_ALLOC_INTERRUPT | 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_SHIFT;
/* See the dmb() in _pmap_alloc_l3(). */
dmb(ishst);
@@ -2759,6 +2763,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 828e39b58cac..90ea6e3459cf 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -2233,7 +2233,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;
@@ -2257,7 +2257,7 @@ __CONCAT(PMTYPE, growkernel)(vm_offset_t addr)
nkpg = vm_page_alloc_noobj(VM_ALLOC_INTERRUPT | 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++;
@@ -2272,6 +2272,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 50229ee40caa..c3aa0f381763 100644
--- a/sys/i386/i386/pmap_base.c
+++ b/sys/i386/i386/pmap_base.c
@@ -111,6 +111,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>
@@ -254,6 +255,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;
@@ -895,11 +901,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 f346e3bb9532..f10aae64f90b 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 038be6fa828d..a15f686d88fe 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,
@@ -3512,7 +3512,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;
@@ -3523,7 +3523,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))
@@ -3535,7 +3535,7 @@ mmu_radix_growkernel(vm_offset_t addr)
nkpg = vm_page_alloc_noobj(VM_ALLOC_INTERRUPT |
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);
@@ -3554,7 +3554,7 @@ mmu_radix_growkernel(vm_offset_t addr)
nkpg = vm_page_alloc_noobj(VM_ALLOC_INTERRUPT | 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);
@@ -3566,6 +3566,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 4355aa7159fc..f39c7699fd37 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 boolean_t (*pmap_is_modified_t)(vm_page_t);
typedef boolean_t (*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 3f1ac937433f..59a12ead8a37 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 d936cab09dbb..4812f3274e69 100644
--- a/sys/riscv/riscv/pmap.c
+++ b/sys/riscv/riscv/pmap.c
@@ -240,6 +240,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);
@@ -1657,8 +1662,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;
@@ -1678,7 +1683,7 @@ pmap_growkernel(vm_offset_t addr)
nkpg = vm_page_alloc_noobj(VM_ALLOC_INTERRUPT |
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 >> L1_SHIFT;
paddr = VM_PAGE_TO_PHYS(nkpg);
@@ -1704,7 +1709,7 @@ pmap_growkernel(vm_offset_t addr)
nkpg = vm_page_alloc_noobj(VM_ALLOC_INTERRUPT | 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_SHIFT;
paddr = VM_PAGE_TO_PHYS(nkpg);
@@ -1721,6 +1726,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 65e909df9b8f..4f25a386d63a 100644
--- a/sys/vm/pmap.h
+++ b/sys/vm/pmap.h
@@ -138,7 +138,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);
boolean_t pmap_is_modified(vm_page_t m);
boolean_t 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 28cf309f86c3..cf028c0c47ef 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -1719,8 +1719,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