FreeBSD/sys/i386/i386/pmap.c
/*
 * grow the number of kernel page table entries, if needed
 */
grow the number of kernel page table entries, if needed
grow the number of kernel page table entries if needed
void
pmap_growkernel(vm_offset_t addr)
{
	vm_paddr_t ptppaddr;
	vm_page_t nkpg;
	pd_entry_t newpdir;
	mtx_assert(&kernel_map->system_mtx, MA_OWNED);
	addr = roundup2(addr, NBPDR);
	if (addr - 1 >= kernel_map->max_offset)
		addr = kernel_map->max_offset;
	while (kernel_vm_end < addr) {
		if (pdir_pde(PTD, kernel_vm_end)) {
			kernel_vm_end = (kernel_vm_end + NBPDR) & ~PDRMASK;
			if (kernel_vm_end - 1 >= kernel_map->max_offset) {
				kernel_vm_end = kernel_map->max_offset;
				break;
			}
			continue;
		}
		nkpg = vm_page_alloc(NULL, kernel_vm_end >> PDRSHIFT,
		    VM_ALLOC_INTERRUPT | VM_ALLOC_NOOBJ | VM_ALLOC_WIRED |
		    VM_ALLOC_ZERO);
		if (nkpg == NULL)
			panic("pmap_growkernel: no memory to grow kernel");
		nkpt++;
		if ((nkpg->flags & PG_ZERO) == 0)
			pmap_zero_page(nkpg);
		ptppaddr = VM_PAGE_TO_PHYS(nkpg);
		newpdir = (pd_entry_t) (ptppaddr | PG_V | PG_RW | PG_A | PG_M);
		pdir_pde(KPTD, kernel_vm_end) = pgeflag | newpdir;
		pmap_kenter_pde(kernel_vm_end, newpdir);
		kernel_vm_end = (kernel_vm_end + NBPDR) & ~PDRMASK;
		if (kernel_vm_end - 1 >= kernel_map->max_offset) {
			kernel_vm_end = kernel_map->max_offset;
			break;
		}
	}
}
void pmap_growkernel ( vm_offset_t addr ) { vm_paddr_t ptppaddr ; vm_page_t nkpg ; pd_entry_t newpdir ; mtx_assert ( & kernel_map -> system_mtx , MA_OWNED ) ; addr = roundup2 ( addr , NBPDR ) ; if ( addr - 1 >= kernel_map -> max_offset ) addr = kernel_map -> max_offset ; while ( kernel_vm_end < addr ) { if ( pdir_pde ( PTD , kernel_vm_end ) ) { kernel_vm_end = ( kernel_vm_end + NBPDR ) & ~ PDRMASK ; if ( kernel_vm_end - 1 >= kernel_map -> max_offset ) { kernel_vm_end = kernel_map -> max_offset ; break ; } continue ; } nkpg = vm_page_alloc ( NULL , kernel_vm_end >> PDRSHIFT , VM_ALLOC_INTERRUPT | VM_ALLOC_NOOBJ | VM_ALLOC_WIRED | VM_ALLOC_ZERO ) ; if ( nkpg == NULL ) panic ( " " ) ; nkpt ++ ; if ( ( nkpg -> flags & PG_ZERO ) == 0 ) pmap_zero_page ( nkpg ) ; ptppaddr = VM_PAGE_TO_PHYS ( nkpg ) ; newpdir = ( pd_entry_t ) ( ptppaddr | PG_V | PG_RW | PG_A | PG_M ) ; pdir_pde ( KPTD , kernel_vm_end ) = pgeflag | newpdir ; pmap_kenter_pde ( kernel_vm_end , newpdir ) ; kernel_vm_end = ( kernel_vm_end + NBPDR ) & ~ PDRMASK ; if ( kernel_vm_end - 1 >= kernel_map -> max_offset ) { kernel_vm_end = kernel_map -> max_offset ; break ; } } }
grow the number of kernel page table entries, if needed
grow the number of kernel page table entries if needed