fix: various kernel bug fixes

This commit is contained in:
2026-04-10 23:16:02 +02:00
parent 0433274244
commit fd7fcbbbc8
12 changed files with 282 additions and 163 deletions
+47
View File
@@ -363,6 +363,53 @@ namespace Memory::VMM {
}
}
bool Paging::IsUserRangeAccessible(std::uint64_t pml4Phys, std::uint64_t virtualAddress,
std::uint64_t size, bool requireWrite) {
static constexpr uint64_t USER_SPACE_END = 0x0000800000000000ULL;
if (size == 0) return true;
if (virtualAddress >= USER_SPACE_END) return false;
if (virtualAddress + size < virtualAddress) return false;
if (virtualAddress + size > USER_SPACE_END) return false;
auto pageAccessible = [&](uint64_t pageVa) -> bool {
VirtualAddress va(pageVa);
PageTable* pml4 = (PageTable*)pml4Phys;
PageTableEntry* pml4e = (PageTableEntry*)Memory::HHDM(&pml4->entries[va.GetL4Index()]);
if (!pml4e->Present || !pml4e->Supervisor) return false;
if (requireWrite && !pml4e->Writable) return false;
PageTable* pml3 = (PageTable*)(pml4e->Address << 12);
PageTableEntry* pml3e = (PageTableEntry*)Memory::HHDM(&pml3->entries[va.GetL3Index()]);
if (!pml3e->Present || !pml3e->Supervisor) return false;
if (requireWrite && !pml3e->Writable) return false;
if (pml3e->LargerPages) return true;
PageTable* pml2 = (PageTable*)(pml3e->Address << 12);
PageTableEntry* pml2e = (PageTableEntry*)Memory::HHDM(&pml2->entries[va.GetL2Index()]);
if (!pml2e->Present || !pml2e->Supervisor) return false;
if (requireWrite && !pml2e->Writable) return false;
if (pml2e->LargerPages) return true;
PageTable* pml1 = (PageTable*)(pml2e->Address << 12);
PageTableEntry* pte = (PageTableEntry*)Memory::HHDM(&pml1->entries[va.GetPageIndex()]);
if (!pte->Present || !pte->Supervisor) return false;
if (requireWrite && !pte->Writable) return false;
return true;
};
uint64_t page = virtualAddress & ~0xFFFULL;
uint64_t lastPage = (virtualAddress + size - 1) & ~0xFFFULL;
for (;;) {
if (!pageAccessible(page)) return false;
if (page == lastPage) break;
page += 0x1000;
}
return true;
}
// Mask to extract only the 40-bit physical address from a PTE Address field
// (bits 12-51 of the PTE). The PageTableEntry::Address field is 52 bits wide
// and includes NX, PK, and software-available bits that must be stripped.
+6
View File
@@ -117,6 +117,12 @@ public:
// Skips MMIO/WC pages (WriteThrough or CacheDisabled set in PTE).
static void FreeUserHalf(std::uint64_t pml4Phys);
// Validate that every page in the given user range is mapped with
// user permissions. If requireWrite is true, all pages must also be
// writable.
static bool IsUserRangeAccessible(std::uint64_t pml4Phys, std::uint64_t virtualAddress,
std::uint64_t size, bool requireWrite = false);
// Identity-map EFI runtime service regions so firmware code can
// reference its own data at physical addresses.
void MapEfiRuntime(limine_efi_memmap_response* efiMemmap);