VMM: Make it even nicer
This commit is contained in:
parent
b360307f41
commit
57482e4e93
@ -24,4 +24,7 @@ namespace VMM
|
||||
void propagate_user(PageTable* root, uint64_t virtualAddress);
|
||||
|
||||
void flush_tlb(uint64_t addr);
|
||||
|
||||
void decompose_vaddr(uint64_t vaddr, uint64_t& page_index, uint64_t& pt_index, uint64_t& pd_index,
|
||||
uint64_t& pdp_index);
|
||||
};
|
@ -71,34 +71,23 @@ void VMM::map(uint64_t virtualAddress, uint64_t physicalAddress, int flags)
|
||||
|
||||
PageDirectoryEntry* VMM::find_pde(PageTable* root, uint64_t virtualAddress)
|
||||
{
|
||||
virtualAddress >>= 12;
|
||||
uint64_t page_index = virtualAddress & 0x1ff;
|
||||
virtualAddress >>= 9;
|
||||
uint64_t pt_index = virtualAddress & 0x1ff;
|
||||
virtualAddress >>= 9;
|
||||
uint64_t pd_index = virtualAddress & 0x1ff;
|
||||
virtualAddress >>= 9;
|
||||
uint64_t pdp_index = virtualAddress & 0x1ff;
|
||||
uint64_t page_index, pt_index, pd_index, pdp_index;
|
||||
PageDirectoryEntry* pde;
|
||||
PageTable* pt;
|
||||
PageTable* pt = root;
|
||||
|
||||
pde = &root->entries[pdp_index]; // PML4
|
||||
if (!pde->Present) return nullptr;
|
||||
else if (pde->LargerPages)
|
||||
return pde;
|
||||
else { pt = (PageTable*)((uint64_t)pde->Address << 12); }
|
||||
decompose_vaddr(virtualAddress, page_index, pt_index, pd_index, pdp_index);
|
||||
|
||||
pde = &pt->entries[pd_index]; // PDP
|
||||
if (!pde->Present) return nullptr;
|
||||
else if (pde->LargerPages)
|
||||
return pde;
|
||||
else { pt = (PageTable*)((uint64_t)pde->Address << 12); }
|
||||
uint64_t indexes[3] = {pdp_index, pd_index, pt_index};
|
||||
|
||||
pde = &pt->entries[pt_index]; // PD
|
||||
if (!pde->Present) return nullptr;
|
||||
else if (pde->LargerPages)
|
||||
return pde;
|
||||
else { pt = (PageTable*)((uint64_t)pde->Address << 12); }
|
||||
for (int i = 0; i < 3;
|
||||
i++) // Walk through the page map level 4, page directory pointer, and page directory to find the page table.
|
||||
{
|
||||
pde = &pt->entries[indexes[i]];
|
||||
if (!pde->Present) return nullptr;
|
||||
else if (pde->LargerPages)
|
||||
return pde;
|
||||
else { pt = (PageTable*)((uint64_t)pde->Address << 12); }
|
||||
}
|
||||
|
||||
pde = &pt->entries[page_index]; // PT
|
||||
if (!pde->Present) return nullptr;
|
||||
@ -107,99 +96,56 @@ PageDirectoryEntry* VMM::find_pde(PageTable* root, uint64_t virtualAddress)
|
||||
|
||||
PageDirectoryEntry* VMM::create_pde_if_not_exists(PageTable* root, uint64_t virtualAddress)
|
||||
{
|
||||
virtualAddress >>= 12;
|
||||
uint64_t page_index = virtualAddress & 0x1ff;
|
||||
virtualAddress >>= 9;
|
||||
uint64_t pt_index = virtualAddress & 0x1ff;
|
||||
virtualAddress >>= 9;
|
||||
uint64_t pd_index = virtualAddress & 0x1ff;
|
||||
virtualAddress >>= 9;
|
||||
uint64_t pdp_index = virtualAddress & 0x1ff;
|
||||
uint64_t page_index, pt_index, pd_index, pdp_index;
|
||||
PageDirectoryEntry* pde;
|
||||
PageTable* pt;
|
||||
PageTable* pt = root;
|
||||
|
||||
pde = &root->entries[pdp_index]; // PML4
|
||||
if (!pde->Present)
|
||||
{
|
||||
decompose_vaddr(virtualAddress, page_index, pt_index, pd_index, pdp_index);
|
||||
|
||||
auto pde_create_if_not_present = [&]() {
|
||||
pt = (PageTable*)PMM::request_page();
|
||||
ASSERT(!(PMM_DID_FAIL(pt)));
|
||||
memset(pt, 0, PAGE_SIZE);
|
||||
pde->set_address((uint64_t)pt);
|
||||
pde->Present = true;
|
||||
}
|
||||
else if (pde->LargerPages)
|
||||
return pde;
|
||||
else { pt = (PageTable*)((uint64_t)pde->Address << 12); }
|
||||
};
|
||||
|
||||
pde = &pt->entries[pd_index]; // PDP
|
||||
if (!pde->Present)
|
||||
uint64_t indexes[3] = {pdp_index, pd_index, pt_index};
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
pt = (PageTable*)PMM::request_page();
|
||||
ASSERT(!(PMM_DID_FAIL(pt)));
|
||||
memset(pt, 0, PAGE_SIZE);
|
||||
pde->set_address((uint64_t)pt);
|
||||
pde->Present = true;
|
||||
pde = &pt->entries[indexes[i]];
|
||||
if (!pde->Present) { pde_create_if_not_present(); }
|
||||
else if (pde->LargerPages)
|
||||
return pde;
|
||||
else { pt = (PageTable*)((uint64_t)pde->Address << 12); }
|
||||
}
|
||||
else if (pde->LargerPages)
|
||||
return pde;
|
||||
else { pt = (PageTable*)((uint64_t)pde->Address << 12); }
|
||||
|
||||
pde = &pt->entries[pt_index]; // PD
|
||||
if (!pde->Present)
|
||||
{
|
||||
pt = (PageTable*)PMM::request_page();
|
||||
ASSERT(!(PMM_DID_FAIL(pt)));
|
||||
memset(pt, 0, PAGE_SIZE);
|
||||
pde->set_address((uint64_t)pt);
|
||||
pde->Present = true;
|
||||
}
|
||||
else if (pde->LargerPages)
|
||||
return pde;
|
||||
else { pt = (PageTable*)((uint64_t)pde->Address << 12); }
|
||||
|
||||
pde = &pt->entries[page_index]; // PT
|
||||
pde = &pt->entries[page_index];
|
||||
if (!pde->Present) { pde->Present = true; }
|
||||
return pde;
|
||||
}
|
||||
|
||||
void VMM::propagate_read_write(PageTable* root, uint64_t virtualAddress)
|
||||
{
|
||||
virtualAddress >>= 12;
|
||||
uint64_t page_index = virtualAddress & 0x1ff;
|
||||
virtualAddress >>= 9;
|
||||
uint64_t pt_index = virtualAddress & 0x1ff;
|
||||
virtualAddress >>= 9;
|
||||
uint64_t pd_index = virtualAddress & 0x1ff;
|
||||
virtualAddress >>= 9;
|
||||
uint64_t pdp_index = virtualAddress & 0x1ff;
|
||||
uint64_t page_index, pt_index, pd_index, pdp_index;
|
||||
PageDirectoryEntry* pde;
|
||||
PageTable* pt;
|
||||
PageTable* pt = root;
|
||||
|
||||
pde = &root->entries[pdp_index]; // PML4
|
||||
if (!pde->Present) return;
|
||||
else
|
||||
{
|
||||
pde->ReadWrite = true;
|
||||
if (pde->LargerPages) return;
|
||||
pt = (PageTable*)((uint64_t)pde->Address << 12);
|
||||
}
|
||||
decompose_vaddr(virtualAddress, page_index, pt_index, pd_index, pdp_index);
|
||||
|
||||
pde = &pt->entries[pd_index]; // PDP
|
||||
if (!pde->Present) return;
|
||||
else
|
||||
{
|
||||
pde->ReadWrite = true;
|
||||
if (pde->LargerPages) return;
|
||||
pt = (PageTable*)((uint64_t)pde->Address << 12);
|
||||
}
|
||||
uint64_t indexes[3] = {pdp_index, pd_index, pt_index};
|
||||
|
||||
pde = &pt->entries[pt_index]; // PD
|
||||
if (!pde->Present) return;
|
||||
else
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
pde->ReadWrite = true;
|
||||
if (pde->LargerPages) return;
|
||||
pt = (PageTable*)((uint64_t)pde->Address << 12);
|
||||
pde = &pt->entries[indexes[i]];
|
||||
if (!pde->Present) return;
|
||||
else
|
||||
{
|
||||
pde->ReadWrite = true;
|
||||
if (pde->LargerPages) return;
|
||||
pt = (PageTable*)((uint64_t)pde->Address << 12);
|
||||
}
|
||||
}
|
||||
|
||||
pde = &pt->entries[page_index];
|
||||
@ -210,42 +156,24 @@ void VMM::propagate_read_write(PageTable* root, uint64_t virtualAddress)
|
||||
|
||||
void VMM::propagate_user(PageTable* root, uint64_t virtualAddress)
|
||||
{
|
||||
virtualAddress >>= 12;
|
||||
uint64_t page_index = virtualAddress & 0x1ff;
|
||||
virtualAddress >>= 9;
|
||||
uint64_t pt_index = virtualAddress & 0x1ff;
|
||||
virtualAddress >>= 9;
|
||||
uint64_t pd_index = virtualAddress & 0x1ff;
|
||||
virtualAddress >>= 9;
|
||||
uint64_t pdp_index = virtualAddress & 0x1ff;
|
||||
uint64_t page_index, pt_index, pd_index, pdp_index;
|
||||
PageDirectoryEntry* pde;
|
||||
PageTable* pt;
|
||||
PageTable* pt = root;
|
||||
|
||||
pde = &root->entries[pdp_index]; // PML4
|
||||
if (!pde->Present) return;
|
||||
else
|
||||
{
|
||||
pde->UserSuper = true;
|
||||
if (pde->LargerPages) return;
|
||||
pt = (PageTable*)((uint64_t)pde->Address << 12);
|
||||
}
|
||||
decompose_vaddr(virtualAddress, page_index, pt_index, pd_index, pdp_index);
|
||||
|
||||
pde = &pt->entries[pd_index]; // PDP
|
||||
if (!pde->Present) return;
|
||||
else
|
||||
{
|
||||
pde->UserSuper = true;
|
||||
if (pde->LargerPages) return;
|
||||
pt = (PageTable*)((uint64_t)pde->Address << 12);
|
||||
}
|
||||
uint64_t indexes[3] = {pdp_index, pd_index, pt_index};
|
||||
|
||||
pde = &pt->entries[pt_index]; // PD
|
||||
if (!pde->Present) return;
|
||||
else
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
pde->UserSuper = true;
|
||||
if (pde->LargerPages) return;
|
||||
pt = (PageTable*)((uint64_t)pde->Address << 12);
|
||||
pde = &pt->entries[indexes[i]];
|
||||
if (!pde->Present) return;
|
||||
else
|
||||
{
|
||||
pde->UserSuper = true;
|
||||
if (pde->LargerPages) return;
|
||||
pt = (PageTable*)((uint64_t)pde->Address << 12);
|
||||
}
|
||||
}
|
||||
|
||||
pde = &pt->entries[page_index];
|
||||
@ -258,3 +186,16 @@ void VMM::flush_tlb(uint64_t addr)
|
||||
{
|
||||
asm volatile("invlpg (%0)" : : "r"(addr) : "memory");
|
||||
}
|
||||
|
||||
void VMM::decompose_vaddr(uint64_t vaddr, uint64_t& page_index, uint64_t& pt_index, uint64_t& pd_index,
|
||||
uint64_t& pdp_index)
|
||||
{
|
||||
vaddr >>= 12;
|
||||
page_index = vaddr & 0x1ff;
|
||||
vaddr >>= 9;
|
||||
pt_index = vaddr & 0x1ff;
|
||||
vaddr >>= 9;
|
||||
pd_index = vaddr & 0x1ff;
|
||||
vaddr >>= 9;
|
||||
pdp_index = vaddr & 0x1ff;
|
||||
}
|
Loading…
Reference in New Issue
Block a user