Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F149005479
D47935.1789357738.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
15 KB
Referenced Files
None
Subscribers
None
D47935.1789357738.diff
View Options
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -578,6 +578,11 @@
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 @@
/*
* 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 @@
end = KERNBASE + nkpt * NBPDR;
if (end == 0) {
TSEXIT();
- return;
+ return (rv);
}
} else {
end = kernel_vm_end;
@@ -5177,7 +5184,7 @@
* nothing to do.
*/
TSEXIT();
- return;
+ return (rv);
}
kasan_shadow_map(end, addr - end);
@@ -5188,8 +5195,10 @@
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 @@
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 @@
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
--- a/sys/arm/arm/pmap-v6.c
+++ b/sys/arm/arm/pmap-v6.c
@@ -1577,6 +1577,11 @@
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 @@
/*
* 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 @@
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 @@
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
--- a/sys/arm64/arm64/pmap.c
+++ b/sys/arm64/arm64/pmap.c
@@ -357,6 +357,11 @@
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 @@
/*
* 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 @@
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 @@
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 @@
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
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -2234,7 +2234,7 @@
/*
* 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 @@
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 @@
break;
}
}
+
+ return (KERN_SUCCESS);
}
/***************************************************
diff --git a/sys/i386/i386/pmap_base.c b/sys/i386/i386/pmap_base.c
--- a/sys/i386/i386/pmap_base.c
+++ b/sys/i386/i386/pmap_base.c
@@ -109,6 +109,7 @@
#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 @@
"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_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
--- a/sys/i386/include/pmap_base.h
+++ b/sys/i386/include/pmap_base.h
@@ -107,7 +107,7 @@
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
--- a/sys/powerpc/aim/mmu_radix.c
+++ b/sys/powerpc/aim/mmu_radix.c
@@ -480,7 +480,7 @@
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 @@
.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 @@
return (m);
}
-static void
+static int
mmu_radix_growkernel(vm_offset_t addr)
{
vm_paddr_t paddr;
@@ -3571,7 +3571,7 @@
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 @@
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 @@
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 @@
}
}
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
--- a/sys/powerpc/include/mmuvar.h
+++ b/sys/powerpc/include/mmuvar.h
@@ -60,7 +60,7 @@
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 @@
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
--- 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 @@
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_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 @@
{
*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
--- a/sys/riscv/riscv/pmap.c
+++ b/sys/riscv/riscv/pmap.c
@@ -241,6 +241,11 @@
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 @@
/*
* 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 @@
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 @@
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 @@
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
--- a/sys/vm/pmap.h
+++ b/sys/vm/pmap.h
@@ -136,7 +136,7 @@
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
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -1711,8 +1711,13 @@
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
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Sep 14, 3:48 AM (11 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29613560
Default Alt Text
D47935.1789357738.diff (15 KB)
Attached To
Mode
D47935: pmap_growkernel(): do not panic immediately, return error
Attached
Detach File
Event Timeline
Log In to Comment