From 664c824bc0509a4213c79b218c7cc91b78ae40a2 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Sat, 4 Apr 2026 22:27:00 +0300 Subject: [PATCH] Kernel: Keep fast page always reserved There was a bug where 32 bit target's reserve_free_page was allocating the fast page address --- kernel/arch/i686/PageTable.cpp | 7 ++++++- kernel/arch/x86_64/PageTable.cpp | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/kernel/arch/i686/PageTable.cpp b/kernel/arch/i686/PageTable.cpp index 9d5db99f..8714f68b 100644 --- a/kernel/arch/i686/PageTable.cpp +++ b/kernel/arch/i686/PageTable.cpp @@ -198,6 +198,7 @@ namespace Kernel { constexpr uint64_t pdpte = (fast_page() >> 30) & 0x1FF; constexpr uint64_t pde = (fast_page() >> 21) & 0x1FF; + constexpr uint64_t pte = (fast_page() >> 12) & 0x1FF; const uint64_t* pdpt = P2V(m_highest_paging_struct); ASSERT(pdpt[pdpte] & Flags::Present); @@ -205,6 +206,10 @@ namespace Kernel uint64_t* pd = P2V(pdpt[pdpte] & s_page_addr_mask); ASSERT(!(pd[pde] & Flags::Present)); pd[pde] = V2P(allocate_zeroed_page_aligned_page()) | Flags::ReadWrite | Flags::Present; + + uint64_t* pt = P2V(pd[pde] & s_page_addr_mask); + ASSERT(pt[pte] == 0); + pt[pte] = Flags::Reserved; } void PageTable::map_fast_page(paddr_t paddr) @@ -244,7 +249,7 @@ namespace Kernel uint64_t* pt = P2V(pd[pde] & s_page_addr_mask); ASSERT(pt[pte] & Flags::Present); - pt[pte] = 0; + pt[pte] = Flags::Reserved; asm volatile("invlpg (%0)" :: "r"(fast_page()) : "memory"); } diff --git a/kernel/arch/x86_64/PageTable.cpp b/kernel/arch/x86_64/PageTable.cpp index 22fdeadc..ba4d1a57 100644 --- a/kernel/arch/x86_64/PageTable.cpp +++ b/kernel/arch/x86_64/PageTable.cpp @@ -485,6 +485,7 @@ namespace Kernel constexpr uint64_t pml4e = (uc_vaddr >> 39) & 0x1FF; constexpr uint64_t pdpte = (uc_vaddr >> 30) & 0x1FF; constexpr uint64_t pde = (uc_vaddr >> 21) & 0x1FF; + constexpr uint64_t pte = (uc_vaddr >> 12) & 0x1FF; uint64_t* pml4 = P2V(m_highest_paging_struct); ASSERT(!(pml4[pml4e] & Flags::Present)); @@ -497,6 +498,10 @@ namespace Kernel uint64_t* pd = P2V(pdpt[pdpte] & s_page_addr_mask); ASSERT(!(pd[pde] & Flags::Present)); pd[pde] = allocate_zeroed_page_aligned_page() | Flags::ReadWrite | Flags::Present; + + uint64_t* pt = P2V(pd[pde] & s_page_addr_mask); + ASSERT(pt[pte] == 0); + pt[pte] = Flags::Reserved; } void PageTable::map_fast_page(paddr_t paddr) @@ -542,7 +547,7 @@ namespace Kernel uint64_t* pt = P2V(pd[pde] & s_page_addr_mask); ASSERT(pt[pte] & Flags::Present); - pt[pte] = 0; + pt[pte] = Flags::Reserved; asm volatile("invlpg (%0)" :: "r"(fast_page()) : "memory"); }