VMM: Add support for larger pages
getPhysical() now stops at a larger page, unmap() can unmap a larger page, but map() just transforms it into a normal page. getFlags() larger pages support is still pending. At least now we don't page fault because we're trying to free a larger page.
This commit is contained in:
parent
525d567af6
commit
950f4ef608
@ -36,7 +36,17 @@ namespace Paging
|
|||||||
{
|
{
|
||||||
return; // Already unmapped
|
return; // Already unmapped
|
||||||
}
|
}
|
||||||
else { PDP = (PageTable*)((uint64_t)PDE.Address << 12); }
|
else
|
||||||
|
{
|
||||||
|
if (PDE.LargerPages)
|
||||||
|
{
|
||||||
|
PDE.Present = false;
|
||||||
|
PDE.LargerPages = false;
|
||||||
|
PML4->entries[PDP_i] = PDE;
|
||||||
|
goto invalidate;
|
||||||
|
}
|
||||||
|
PDP = (PageTable*)((uint64_t)PDE.Address << 12);
|
||||||
|
}
|
||||||
|
|
||||||
PDE = PDP->entries[PD_i];
|
PDE = PDP->entries[PD_i];
|
||||||
PageTable* PD;
|
PageTable* PD;
|
||||||
@ -44,7 +54,17 @@ namespace Paging
|
|||||||
{
|
{
|
||||||
return; // Already unmapped
|
return; // Already unmapped
|
||||||
}
|
}
|
||||||
else { PD = (PageTable*)((uint64_t)PDE.Address << 12); }
|
else
|
||||||
|
{
|
||||||
|
if (PDE.LargerPages)
|
||||||
|
{
|
||||||
|
PDE.Present = false;
|
||||||
|
PDE.LargerPages = false;
|
||||||
|
PDP->entries[PD_i] = PDE;
|
||||||
|
goto invalidate;
|
||||||
|
}
|
||||||
|
PD = (PageTable*)((uint64_t)PDE.Address << 12);
|
||||||
|
}
|
||||||
|
|
||||||
PDE = PD->entries[PT_i];
|
PDE = PD->entries[PT_i];
|
||||||
PageTable* PT;
|
PageTable* PT;
|
||||||
@ -52,7 +72,17 @@ namespace Paging
|
|||||||
{
|
{
|
||||||
return; // Already unmapped
|
return; // Already unmapped
|
||||||
}
|
}
|
||||||
else { PT = (PageTable*)((uint64_t)PDE.Address << 12); }
|
else
|
||||||
|
{
|
||||||
|
if (PDE.LargerPages)
|
||||||
|
{
|
||||||
|
PDE.LargerPages = false;
|
||||||
|
PDE.Present = false;
|
||||||
|
PD->entries[PT_i] = PDE;
|
||||||
|
goto invalidate;
|
||||||
|
}
|
||||||
|
PT = (PageTable*)((uint64_t)PDE.Address << 12);
|
||||||
|
}
|
||||||
|
|
||||||
PDE = PT->entries[P_i];
|
PDE = PT->entries[P_i];
|
||||||
PDE.Present = false;
|
PDE.Present = false;
|
||||||
@ -80,7 +110,11 @@ namespace Paging
|
|||||||
{
|
{
|
||||||
return UINT64_MAX; // Not mapped
|
return UINT64_MAX; // Not mapped
|
||||||
}
|
}
|
||||||
else { PDP = (PageTable*)((uint64_t)PDE.Address << 12); }
|
else
|
||||||
|
{
|
||||||
|
if (PDE.LargerPages) return PDE.Address << 12 | (virtualAddress & PAGE_SIZE);
|
||||||
|
PDP = (PageTable*)((uint64_t)PDE.Address << 12);
|
||||||
|
}
|
||||||
|
|
||||||
PDE = PDP->entries[PD_i];
|
PDE = PDP->entries[PD_i];
|
||||||
PageTable* PD;
|
PageTable* PD;
|
||||||
@ -88,7 +122,11 @@ namespace Paging
|
|||||||
{
|
{
|
||||||
return UINT64_MAX; // Not mapped
|
return UINT64_MAX; // Not mapped
|
||||||
}
|
}
|
||||||
else { PD = (PageTable*)((uint64_t)PDE.Address << 12); }
|
else
|
||||||
|
{
|
||||||
|
if (PDE.LargerPages) return PDE.Address << 12 | (virtualAddress & PAGE_SIZE);
|
||||||
|
PD = (PageTable*)((uint64_t)PDE.Address << 12);
|
||||||
|
}
|
||||||
|
|
||||||
PDE = PD->entries[PT_i];
|
PDE = PD->entries[PT_i];
|
||||||
PageTable* PT;
|
PageTable* PT;
|
||||||
@ -96,10 +134,15 @@ namespace Paging
|
|||||||
{
|
{
|
||||||
return UINT64_MAX; // Not mapped
|
return UINT64_MAX; // Not mapped
|
||||||
}
|
}
|
||||||
else { PT = (PageTable*)((uint64_t)PDE.Address << 12); }
|
else
|
||||||
|
{
|
||||||
|
if (PDE.LargerPages) return PDE.Address << 12 | (virtualAddress & PAGE_SIZE);
|
||||||
|
PT = (PageTable*)((uint64_t)PDE.Address << 12);
|
||||||
|
}
|
||||||
|
|
||||||
PDE = PT->entries[P_i];
|
PDE = PT->entries[P_i];
|
||||||
return PDE.Address << 12;
|
if (!PDE.Present) return UINT64_MAX;
|
||||||
|
return PDE.Address << 12 | (virtualAddress & PAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t VirtualMemoryManager::getFlags(uint64_t virtualAddress)
|
uint64_t VirtualMemoryManager::getFlags(uint64_t virtualAddress)
|
||||||
@ -173,7 +216,24 @@ namespace Paging
|
|||||||
if (flags & User) PDE.UserSuper = true;
|
if (flags & User) PDE.UserSuper = true;
|
||||||
PML4->entries[PDP_i] = PDE;
|
PML4->entries[PDP_i] = PDE;
|
||||||
}
|
}
|
||||||
else { PDP = (PageTable*)((uint64_t)PDE.Address << 12); }
|
else
|
||||||
|
{
|
||||||
|
if (PDE.LargerPages)
|
||||||
|
{
|
||||||
|
unmap(virtualAddress);
|
||||||
|
PDE.LargerPages = false;
|
||||||
|
PML4->entries[PDP_i] = PDE;
|
||||||
|
PDP = (PageTable*)PMM::request_page();
|
||||||
|
ASSERT(!(PMM_DID_FAIL(PDP)));
|
||||||
|
memset(PDP, 0, PAGE_SIZE);
|
||||||
|
PDE.set_address((uint64_t)PDP);
|
||||||
|
PDE.Present = true;
|
||||||
|
PDE.ReadWrite = true;
|
||||||
|
if (flags & User) PDE.UserSuper = true;
|
||||||
|
return map(virtualAddress, physicalAddress, flags);
|
||||||
|
}
|
||||||
|
PDP = (PageTable*)((uint64_t)PDE.Address << 12);
|
||||||
|
}
|
||||||
if ((flags & User) && !PDE.UserSuper)
|
if ((flags & User) && !PDE.UserSuper)
|
||||||
{
|
{
|
||||||
PDE.UserSuper = true;
|
PDE.UserSuper = true;
|
||||||
@ -193,7 +253,24 @@ namespace Paging
|
|||||||
if (flags & User) PDE.UserSuper = true;
|
if (flags & User) PDE.UserSuper = true;
|
||||||
PDP->entries[PD_i] = PDE;
|
PDP->entries[PD_i] = PDE;
|
||||||
}
|
}
|
||||||
else { PD = (PageTable*)((uint64_t)PDE.Address << 12); }
|
else
|
||||||
|
{
|
||||||
|
if (PDE.LargerPages)
|
||||||
|
{
|
||||||
|
unmap(virtualAddress);
|
||||||
|
PDE.LargerPages = false;
|
||||||
|
PDP->entries[PD_i] = PDE;
|
||||||
|
PD = (PageTable*)PMM::request_page();
|
||||||
|
ASSERT(!(PMM_DID_FAIL(PD)));
|
||||||
|
memset(PD, 0, PAGE_SIZE);
|
||||||
|
PDE.set_address((uint64_t)PD);
|
||||||
|
PDE.Present = true;
|
||||||
|
PDE.ReadWrite = true;
|
||||||
|
if (flags & User) PDE.UserSuper = true;
|
||||||
|
return map(virtualAddress, physicalAddress, flags);
|
||||||
|
}
|
||||||
|
PD = (PageTable*)((uint64_t)PDE.Address << 12);
|
||||||
|
}
|
||||||
if ((flags & User) && !PDE.UserSuper)
|
if ((flags & User) && !PDE.UserSuper)
|
||||||
{
|
{
|
||||||
PDE.UserSuper = true;
|
PDE.UserSuper = true;
|
||||||
@ -213,7 +290,23 @@ namespace Paging
|
|||||||
if (flags & User) PDE.UserSuper = true;
|
if (flags & User) PDE.UserSuper = true;
|
||||||
PD->entries[PT_i] = PDE;
|
PD->entries[PT_i] = PDE;
|
||||||
}
|
}
|
||||||
else { PT = (PageTable*)((uint64_t)PDE.Address << 12); }
|
else
|
||||||
|
{
|
||||||
|
if (PDE.LargerPages)
|
||||||
|
{
|
||||||
|
unmap(virtualAddress);
|
||||||
|
PDE.LargerPages = false;
|
||||||
|
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.ReadWrite = true;
|
||||||
|
if (flags & User) PDE.UserSuper = true;
|
||||||
|
PD->entries[PT_i] = PDE;
|
||||||
|
}
|
||||||
|
PT = (PageTable*)((uint64_t)PDE.Address << 12);
|
||||||
|
}
|
||||||
if ((flags & User) && !PDE.UserSuper)
|
if ((flags & User) && !PDE.UserSuper)
|
||||||
{
|
{
|
||||||
PDE.UserSuper = true;
|
PDE.UserSuper = true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user