Created
November 14, 2021 12:31
-
-
Save jarlostensen/ebd3689f1332166576415b6f977be955 to your computer and use it in GitHub Desktop.
4 level page table traversal
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// from josx64, but this code is pretty generic. | |
// [kernel] fills in the pagetable entries from the given address | |
// | |
// see for example Intel Dev Guide Vol 3 4.2 | |
_JOS_API_FUNC void pagetables_traverse_tables(void* at, uintptr_t * entries, size_t num_entries) { | |
_JOS_ASSERT(entries &&_4_level_paging && num_entries>=4); | |
memset(entries, 0, 4*sizeof(uintptr_t)); | |
//NOTE: this relies on identity mapping in order to get access to the pagetables themselves | |
// but this is not essential for understanding the traversal. | |
uintptr_t address =(uintptr_t)at; | |
mapping_table_t* cr3 = (mapping_table_t*)x86_64_get_pml4(); | |
uintptr_t pml4e = cr3->entries[PML4_IDX(address)]; | |
entries[0] = pml4e; | |
if ( pml4e & PAGE_BIT_P_PRESENT ) { | |
mapping_table_t* pml4 = (mapping_table_t*)(pml4e & PAGE_ADDR_MASK); | |
uintptr_t pdpte = pml4->entries[PDPT_IDX(address)]; | |
entries[1] = pdpte; | |
if ( (pdpte & PAGE_HUGE)==0 ) { | |
if ( pdpte & PAGE_BIT_P_PRESENT ) { | |
mapping_table_t* pdpt = (mapping_table_t*)(pdpte & PAGE_ADDR_MASK); | |
uintptr_t pde = pdpt->entries[PD_IDX(address)]; | |
entries[2] = pde; | |
if ( (pde & PAGE_HUGE)==0 ) { | |
// 4KB pages | |
mapping_table_t* pd = (mapping_table_t*)(pde & PAGE_ADDR_MASK); | |
uintptr_t pte = pd->entries[PT_IDX(address)]; | |
entries[3] = pte; | |
} | |
// else 2MB pages | |
} | |
} | |
// else 1GB pages | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment