Page MenuHomeFreeBSD

D47935.1789357738.diff
No OneTemporary

Size
15 KB
Referenced Files
None
Subscribers
None

D47935.1789357738.diff

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

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)

Event Timeline