MCPcopy Create free account
hub / github.com/F-Stack/f-stack / pmap_growkernel

Function pmap_growkernel

freebsd/amd64/amd64/pmap.c:4755–4829  ·  view source on GitHub ↗

* grow the number of kernel page table entries, if needed */

Source from the content-addressed store, hash-verified

4753 * grow the number of kernel page table entries, if needed
4754 */
4755void
4756pmap_growkernel(vm_offset_t addr)
4757{
4758 vm_paddr_t paddr;
4759 vm_page_t nkpg;
4760 pd_entry_t *pde, newpdir;
4761 pdp_entry_t *pdpe;
4762
4763 mtx_assert(&kernel_map->system_mtx, MA_OWNED);
4764
4765 /*
4766 * Return if "addr" is within the range of kernel page table pages
4767 * that were preallocated during pmap bootstrap. Moreover, leave
4768 * "kernel_vm_end" and the kernel page table as they were.
4769 *
4770 * The correctness of this action is based on the following
4771 * argument: vm_map_insert() allocates contiguous ranges of the
4772 * kernel virtual address space. It calls this function if a range
4773 * ends after "kernel_vm_end". If the kernel is mapped between
4774 * "kernel_vm_end" and "addr", then the range cannot begin at
4775 * "kernel_vm_end". In fact, its beginning address cannot be less
4776 * than the kernel. Thus, there is no immediate need to allocate
4777 * any new kernel page table pages between "kernel_vm_end" and
4778 * "KERNBASE".
4779 */
4780 if (KERNBASE < addr && addr <= KERNBASE + nkpt * NBPDR)
4781 return;
4782
4783 addr = roundup2(addr, NBPDR);
4784 if (addr - 1 >= vm_map_max(kernel_map))
4785 addr = vm_map_max(kernel_map);
4786 while (kernel_vm_end < addr) {
4787 pdpe = pmap_pdpe(kernel_pmap, kernel_vm_end);
4788 if ((*pdpe & X86_PG_V) == 0) {
4789 /* We need a new PDP entry */
4790 nkpg = vm_page_alloc(NULL, kernel_vm_end >> PDPSHIFT,
4791 VM_ALLOC_INTERRUPT | VM_ALLOC_NOOBJ |
4792 VM_ALLOC_WIRED | VM_ALLOC_ZERO);
4793 if (nkpg == NULL)
4794 panic("pmap_growkernel: no memory to grow kernel");
4795 if ((nkpg->flags & PG_ZERO) == 0)
4796 pmap_zero_page(nkpg);
4797 paddr = VM_PAGE_TO_PHYS(nkpg);
4798 *pdpe = (pdp_entry_t)(paddr | X86_PG_V | X86_PG_RW |
4799 X86_PG_A | X86_PG_M);
4800 continue; /* try again */
4801 }
4802 pde = pmap_pdpe_to_pde(pdpe, kernel_vm_end);
4803 if ((*pde & X86_PG_V) != 0) {
4804 kernel_vm_end = (kernel_vm_end + NBPDR) & ~PDRMASK;
4805 if (kernel_vm_end - 1 >= vm_map_max(kernel_map)) {
4806 kernel_vm_end = vm_map_max(kernel_map);
4807 break;
4808 }
4809 continue;
4810 }
4811
4812 nkpg = vm_page_alloc(NULL, pmap_pde_pindex(kernel_vm_end),

Callers

nothing calls this directly

Calls 8

mtx_assertFunction · 0.85
vm_map_maxFunction · 0.85
pmap_pdpeFunction · 0.85
vm_page_allocFunction · 0.85
pmap_pde_pindexFunction · 0.85
pmap_zero_pageFunction · 0.70
pmap_pdpe_to_pdeFunction · 0.70
panicFunction · 0.50

Tested by

no test coverage detected