bool ArchMemory::checkAddressValid(uint64 vaddress_to_check) { ArchMemoryMapping m = resolveMapping(page_map_level_4_, vaddress_to_check / PAGE_SIZE); if (m.page != 0) { debug(A_MEMORY,"checkAddressValid %x and %x -> true\n", page_map_level_4_, vaddress_to_check); return true; } else { debug(A_MEMORY,"checkAddressValid %x and %x -> false\n", page_map_level_4_, vaddress_to_check); return false; } if (m.pml4 && m.pml4[m.pml4i].present) { if (m.pdpt && m.pdpt[m.pdpti].pd.present && !m.pdpt[m.pdpti].pd.size) // 1gb page ? { if (m.pd && m.pd[m.pdi].pt.present && !m.pd[m.pdi].pt.size && m.pt[m.pti].present) // 2mb page ? return true; else if (m.pd && m.pd[m.pdi].page.present) return true; } else if (m.pdpt && m.pdpt[m.pdpti].page.present) return true; } }
bool ArchMemory::unmapPage(uint64 virtual_page) { ArchMemoryMapping m = resolveMapping(page_map_level_4_, virtual_page); assert(m.page_ppn != 0 && m.page_size == PAGE_SIZE && m.pt[m.pti].present); m.pt[m.pti].present = 0; PageManager::instance()->freePPN(m.page_ppn, PAGE_SIZE); ((uint64*)m.pt)[m.pti] = 0; // for easier debugging bool empty = checkAndRemove<PageTableEntry>(getIdentAddressOfPPN(m.pt_ppn), m.pti); if (empty) { PageManager::instance()->freePPN(m.pt_ppn, PAGE_SIZE); empty = checkAndRemove<PageDirPageTableEntry>(getIdentAddressOfPPN(m.pd_ppn), m.pdi); } if (empty) { PageManager::instance()->freePPN(m.pd_ppn, PAGE_SIZE); empty = checkAndRemove<PageDirPointerTablePageDirEntry>(getIdentAddressOfPPN(m.pdpt_ppn), m.pdpti); } if (empty) { PageManager::instance()->freePPN(m.pdpt_ppn, PAGE_SIZE); empty = checkAndRemove<PageMapLevel4Entry>(getIdentAddressOfPPN(m.pml4_ppn), m.pml4i); } return true; }
bool ArchMemory::mapPage(uint64 virtual_page, uint64 physical_page, uint64 user_access) { debug(A_MEMORY, "%zx %zx %zx %zx\n", page_map_level_4_, virtual_page, physical_page, user_access); ArchMemoryMapping m = resolveMapping(page_map_level_4_, virtual_page); assert((m.page_size == 0) || (m.page_size == PAGE_SIZE)); if (m.pdpt_ppn == 0) { m.pdpt_ppn = PageManager::instance()->allocPPN(); insert<PageMapLevel4Entry>((pointer) m.pml4, m.pml4i, m.pdpt_ppn, 1, 0, 1, 1); } if (m.pd_ppn == 0) { m.pd_ppn = PageManager::instance()->allocPPN(); insert<PageDirPointerTablePageDirEntry>(getIdentAddressOfPPN(m.pdpt_ppn), m.pdpti, m.pd_ppn, 1, 0, 1, 1); } if (m.pt_ppn == 0) { m.pt_ppn = PageManager::instance()->allocPPN(); insert<PageDirPageTableEntry>(getIdentAddressOfPPN(m.pd_ppn), m.pdi, m.pt_ppn, 1, 0, 1, 1); } if (m.page_ppn == 0) { return insert<PageTableEntry>(getIdentAddressOfPPN(m.pt_ppn), m.pti, physical_page, 0, 0, user_access, 1); } assert(false); // you should never get here return false; }
size_t ArchMemory::get_PPN_Of_VPN_In_KernelMapping(size_t virtual_page, size_t *physical_page, size_t *physical_pte_page) { ArchMemoryMapping m = resolveMapping(PML4_KERNEL_PAGE, virtual_page); if (physical_page) *physical_page = m.page_ppn; if (physical_pte_page) *physical_pte_page = m.pt_ppn; return m.page_size; }
void meshRemapTool::completeAction() { if( resolveMapping() != MStatus::kSuccess ) { reset(); return; } executeCmd(); }
size_t ArchMemory::get_PPN_Of_VPN_In_KernelMapping(size_t virtual_page, size_t *physical_page, size_t *physical_pte_page) { ArchMemoryMapping m = resolveMapping(((uint64) VIRTUAL_TO_PHYSICAL_BOOT(kernel_page_map_level_4) / PAGE_SIZE), virtual_page); if (physical_page) *physical_page = m.page_ppn; if (physical_pte_page) *physical_pte_page = m.pt_ppn; return m.page_size; }
pointer ArchMemory::checkAddressValid(uint64 vaddress_to_check) { ArchMemoryMapping m = resolveMapping(page_map_level_4_, vaddress_to_check / PAGE_SIZE); if (m.page != 0) { debug(A_MEMORY, "checkAddressValid %zx and %zx -> true\n", page_map_level_4_, vaddress_to_check); return m.page | (vaddress_to_check % m.page_size); } else { debug(A_MEMORY, "checkAddressValid %zx and %zx -> false\n", page_map_level_4_, vaddress_to_check); return 0; } }
bool ArchMemory::unmapPage(uint64 virtual_page) { ArchMemoryMapping m = resolveMapping(page_map_level_4_, virtual_page); assert(m.page_ppn != 0 && m.page_size == PAGE_SIZE); bool empty = checkAndRemove<PageTableEntry>(getIdentAddressOfPPN(m.pt_ppn), m.pti); if (empty) empty = checkAndRemove<PageDirPageEntry>(getIdentAddressOfPPN(m.pd_ppn), m.pdi); if (empty) empty = checkAndRemove<PageDirPointerTablePageDirEntry>(getIdentAddressOfPPN(m.pdpt_ppn), m.pdpti); if (empty) empty = checkAndRemove<PageMapLevel4Entry>(getIdentAddressOfPPN(m.pml4_ppn), m.pml4i); return true; }
void ArchMemory::unmapKernelPage(size_t virtual_page) { ArchMemoryMapping mapping = resolveMapping(((uint64) VIRTUAL_TO_PHYSICAL_BOOT(kernel_page_map_level_4) / PAGE_SIZE), virtual_page); PageMapLevel4Entry* pml4 = kernel_page_map_level_4; assert(pml4[mapping.pml4i].present); PageDirPointerTableEntry *pdpt = (PageDirPointerTableEntry*) getIdentAddressOfPPN(pml4[mapping.pml4i].page_ppn); assert(pdpt[mapping.pdpti].pd.present); PageDirEntry *pd = (PageDirEntry*) getIdentAddressOfPPN(pdpt[mapping.pdpti].pd.page_ppn); assert(pd[mapping.pdi].pt.present); PageTableEntry *pt = (PageTableEntry*) getIdentAddressOfPPN(pd[mapping.pdi].pt.page_ppn); assert(pt[mapping.pti].present); pt[mapping.pti].present = 0; pt[mapping.pti].writeable = 0; PageManager::instance()->freePPN(pt[mapping.pti].page_ppn); asm volatile ("movq %%cr3, %%rax; movq %%rax, %%cr3;" ::: "%rax"); }
bool ArchMemory::mapPage(uint64 virtual_page, uint64 physical_page, uint64 user_access, uint64 page_size) { debug(A_MEMORY,"%x %x %x %x %x\n",page_map_level_4_, virtual_page, physical_page, user_access, page_size); PageMapLevel4Entry* pml4p = (PageMapLevel4Entry*) getIdentAddressOfPPN(page_map_level_4_); ArchMemoryMapping m = resolveMapping(page_map_level_4_, virtual_page); if (m.pdpt_ppn == 0) { m.pdpt_ppn = PageManager::instance()->getFreePhysicalPage(); insert<PageMapLevel4Entry>((pointer) m.pml4, m.pml4i, m.pdpt_ppn, 1, 0, 1, 1); } if (m.pd_ppn == 0) { if (page_size == PAGE_SIZE * PAGE_TABLE_ENTRIES * PAGE_DIR_ENTRIES) { return insert<PageDirPointerTablePageEntry>(getIdentAddressOfPPN(m.pdpt_ppn), m.pdi, physical_page, 0, 1, user_access, 1); } else { m.pd_ppn = PageManager::instance()->getFreePhysicalPage(); insert<PageDirPointerTablePageDirEntry>(getIdentAddressOfPPN(m.pdpt_ppn), m.pdpti, m.pd_ppn, 1, 0, 1, 1); } } if (m.pt_ppn == 0) { if (page_size == PAGE_SIZE * PAGE_TABLE_ENTRIES) { return insert<PageDirPageEntry>(getIdentAddressOfPPN(m.pd_ppn), m.pdi, physical_page, 0, 1, user_access, 1); } else// if (m.pd == 0) { m.pt_ppn = PageManager::instance()->getFreePhysicalPage(); insert<PageDirPageTableEntry>(getIdentAddressOfPPN(m.pd_ppn), m.pdi, m.pt_ppn, 1, 0, 1, 1); } } if (m.page_ppn == 0 && page_size == PAGE_SIZE) { return insert<PageTableEntry>(getIdentAddressOfPPN(m.pt_ppn), m.pti, physical_page, 0, 0, user_access, 1); } assert(false); // you should never get here return false; }
const ArchMemoryMapping ArchMemory::resolveMapping(uint64 vpage) { return resolveMapping(page_map_level_4_, vpage); }