#include #include #include struct leaflet * dup_leaflet(struct leaflet *leaflet) { ptr_t dest_va, src_va; struct leaflet *new_leaflet; new_leaflet = alloc_leaflet(leaflet_order(leaflet)); src_va = leaflet_mount(leaflet); dest_va = vmap(new_leaflet, KERNEL_DATA); memcpy((void *)dest_va, (void *)src_va, PAGE_SIZE); leaflet_unmount(leaflet); vunmap(dest_va, new_leaflet); return new_leaflet; } static inline struct ppage* __setup_pmem_map(ptr_t start, size_t plist_size) { pte_t pte, *ptep; unsigned int nr_pages; pte = mkpte(start, KERNEL_DATA); ptep = mkl2tep_va(VMS_SELF, PMAP); nr_pages = page_count(plist_size, L2T_SIZE); vmm_set_ptes_contig(ptep, pte, L2T_SIZE, nr_pages); return (struct ppage*)PMAP; } ptr_t pmm_arch_init_remap(struct pmem *memory, struct boot_handoff *bctx) { unsigned long plist_len, plist_size, nr_huges; struct boot_mmapent *ment; plist_len = leaf_count(bctx->mem.size); plist_size = plist_len * sizeof(struct ppage); nr_huges = page_count(plist_size, lnt_page_size(2)); ptr_t pkernel_end = to_kphysical(kernel_end); pkernel_end = napot_upaligned(pkernel_end, L2T_SIZE); pkernel_end += plist_size; for (int i = 0; i < bctx->mem.mmap_len; i++) { ment = &bctx->mem.mmap[i]; if (ment->type != BOOT_MMAP_FREE) { continue; } if (pkernel_end >= ment->start + ment->size) { continue; } memory->pplist = __setup_pmem_map(pkernel_end, plist_size);; memory->list_len = plist_len; return pkernel_end; } fail("no_mem, unable to map plist"); return NULL; }