diff --git a/kernel/src/memory/VMM.cpp b/kernel/src/memory/VMM.cpp index b87a9f26..75e5417f 100644 --- a/kernel/src/memory/VMM.cpp +++ b/kernel/src/memory/VMM.cpp @@ -36,7 +36,17 @@ namespace Paging { 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]; PageTable* PD; @@ -44,7 +54,17 @@ namespace Paging { 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]; PageTable* PT; @@ -52,7 +72,17 @@ namespace Paging { 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.Present = false; @@ -80,7 +110,11 @@ namespace Paging { 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]; PageTable* PD; @@ -88,7 +122,11 @@ namespace Paging { 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]; PageTable* PT; @@ -96,10 +134,15 @@ namespace Paging { 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]; - return PDE.Address << 12; + if (!PDE.Present) return UINT64_MAX; + return PDE.Address << 12 | (virtualAddress & PAGE_SIZE); } uint64_t VirtualMemoryManager::getFlags(uint64_t virtualAddress) @@ -173,7 +216,24 @@ namespace Paging if (flags & User) PDE.UserSuper = true; 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) { PDE.UserSuper = true; @@ -193,7 +253,24 @@ namespace Paging if (flags & User) PDE.UserSuper = true; 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) { PDE.UserSuper = true; @@ -213,7 +290,23 @@ namespace Paging if (flags & User) PDE.UserSuper = true; 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) { PDE.UserSuper = true;