Page MenuHomeFreeBSD

D47935.diff
No OneTemporary

D47935.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
@@ -570,6 +570,11 @@
static vm_pindex_t pti_pg_idx;
static bool pti_finalized;
+static int __read_frequently 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;
@@ -5115,17 +5120,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
@@ -5153,7 +5160,7 @@
end = KERNBASE + nkpt * NBPDR;
if (end == 0) {
TSEXIT();
- return;
+ return (rv);
}
} else {
end = kernel_vm_end;
@@ -5168,7 +5175,7 @@
* nothing to do.
*/
TSEXIT();
- return;
+ return (rv);
}
kasan_shadow_map(end, addr - end);
@@ -5179,8 +5186,12 @@
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) {
+ printf(
+ "pmap_growkernel: no memory to grow kernel");
+ 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);
@@ -5199,8 +5210,12 @@
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) {
+ printf("pmap_growkernel: no memory to grow kernel");
+ 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);
@@ -5217,8 +5232,21 @@
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);
+}
+
+
/***************************************************
* page management routines.
***************************************************/
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
@@ -1709,8 +1709,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
Sat, Feb 22, 5:51 AM (4 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16766580
Default Alt Text
D47935.diff (3 KB)

Event Timeline