/** * Allocates one page. * * @param virtAddr The virtual address to which this page maybe mapped in * the future. * * @returns Pointer to the allocated page, NULL on failure. */ static page_t *rtR0MemObjSolPageAlloc(caddr_t virtAddr) { u_offset_t offPage; seg_t KernelSeg; /* * 16777215 terabytes of total memory for all VMs or * restart 8000 1GB VMs 2147483 times until wraparound! */ mutex_enter(&g_OffsetMtx); AssertCompileSize(u_offset_t, sizeof(uint64_t)); NOREF(RTASSERTVAR); g_offPage = RT_ALIGN_64(g_offPage, PAGE_SIZE) + PAGE_SIZE; offPage = g_offPage; mutex_exit(&g_OffsetMtx); KernelSeg.s_as = &kas; page_t *pPage = page_create_va(&g_PageVnode, offPage, PAGE_SIZE, PG_WAIT | PG_NORELOC, &KernelSeg, virtAddr); if (RT_LIKELY(pPage)) { /* * Lock this page into memory "long term" to prevent this page from being paged out * when we drop the page lock temporarily (during free). Downgrade to a shared lock * to prevent page relocation. */ page_pp_lock(pPage, 0 /* COW */, 1 /* Kernel */); page_io_unlock(pPage); page_downgrade(pPage); Assert(PAGE_LOCKED_SE(pPage, SE_SHARED)); } return pPage; }
static void less_pages(uint64_t base, uint64_t len) { uint64_t pa, end = base + len; extern int kcage_on; for (pa = base; pa < end; pa += PAGESIZE) { pfn_t pfnum; page_t *pp; pfnum = (pfn_t)(pa >> PAGESHIFT); if ((pp = page_numtopp_nolock(pfnum)) == NULL) cmn_err(CE_PANIC, "missing pfnum %lx", pfnum); /* * must break up any large pages that may have * constituent pages being utilized for * prom_alloc()'s. page_reclaim() can't handle * large pages. */ if (pp->p_szc != 0) page_boot_demote(pp); if (!PAGE_LOCKED(pp) && pp->p_lckcnt == 0) { /* * Ahhh yes, a prom page, * suck it off the freelist, * lock it, and hashin on prom_pages vp. */ if (page_trylock(pp, SE_EXCL) == 0) cmn_err(CE_PANIC, "prom page locked"); (void) page_reclaim(pp, NULL); /* * vnode offsets on the prom_ppages vnode * are page numbers (gack) for >32 bit * physical memory machines. */ (void) page_hashin(pp, &promvp, (offset_t)pfnum, NULL); if (kcage_on) { ASSERT(pp->p_szc == 0); if (PP_ISNORELOC(pp) == 0) { PP_SETNORELOC(pp); PLCNT_XFER_NORELOC(pp); } } (void) page_pp_lock(pp, 0, 1); } } }