From 6fcb191ca0b2667364f4f615b02704517ce7dbef Mon Sep 17 00:00:00 2001 From: Bananymous Date: Sun, 6 Aug 2023 23:59:30 +0300 Subject: [PATCH] Kernel: Add PageTable::Flags::CacheDisable Also fix multiple places where we were using uint8_t as page table flags instead of PageTable::flags_t which we promoted to uint16_t while back. --- kernel/arch/x86_64/PageTable.cpp | 25 ++++++++++++++++---- kernel/include/kernel/Memory/PageTable.h | 11 +++++---- kernel/include/kernel/Memory/VirtualRange.h | 8 +++---- kernel/kernel/Memory/FixedWidthAllocator.cpp | 2 +- kernel/kernel/Memory/GeneralAllocator.cpp | 2 +- kernel/kernel/Memory/VirtualRange.cpp | 4 ++-- kernel/kernel/Process.cpp | 2 +- 7 files changed, 36 insertions(+), 18 deletions(-) diff --git a/kernel/arch/x86_64/PageTable.cpp b/kernel/arch/x86_64/PageTable.cpp index 7a551ca7..e1aa88f7 100644 --- a/kernel/arch/x86_64/PageTable.cpp +++ b/kernel/arch/x86_64/PageTable.cpp @@ -48,7 +48,22 @@ namespace Kernel static inline PageTable::flags_t parse_flags(uint64_t entry) { - return (s_has_nxe && !(entry & (1ull << 63)) ? PageTable::Flags::Execute : 0) | (entry & 0b100000111); + using Flags = PageTable::Flags; + + PageTable::flags_t result = 0; + if (s_has_nxe && !(entry & (1ull << 63))) + result |= Flags::Execute; + if (entry & Flags::Reserved) + result |= Flags::Reserved; + if (entry & Flags::CacheDisable) + result |= Flags::CacheDisable; + if (entry & Flags::UserSupervisor) + result |= Flags::UserSupervisor; + if (entry & Flags::ReadWrite) + result |= Flags::ReadWrite; + if (entry & Flags::Present) + result |= Flags::Present; + return result; } void PageTable::initialize() @@ -258,13 +273,15 @@ namespace Kernel uint64_t pte = (uc_vaddr >> 12) & 0x1FF; uint64_t extra_flags = 0; + if (s_has_pge && pml4e == 511) // Map kernel memory as global + extra_flags |= 1ull << 8; if (s_has_nxe && !(flags & Flags::Execute)) extra_flags |= 1ull << 63; - if (s_has_pge && pml4e == 511) - extra_flags |= 1ull << 8; if (flags & Flags::Reserved) extra_flags |= Flags::Reserved; - + if (flags & Flags::CacheDisable) + extra_flags |= Flags::CacheDisable; + // NOTE: we add present here, since it has to be available in higher level structures flags_t uwr_flags = (flags & (Flags::UserSupervisor | Flags::ReadWrite)) | Flags::Present; diff --git a/kernel/include/kernel/Memory/PageTable.h b/kernel/include/kernel/Memory/PageTable.h index 1cdd7f26..55456df7 100644 --- a/kernel/include/kernel/Memory/PageTable.h +++ b/kernel/include/kernel/Memory/PageTable.h @@ -13,12 +13,13 @@ namespace Kernel using flags_t = uint16_t; enum Flags : flags_t { - Present = 1, - ReadWrite = 2, - UserSupervisor = 4, - Execute = 8, - Reserved = 256, + Present = (1 << 0), + ReadWrite = (1 << 1), + UserSupervisor = (1 << 2), + CacheDisable = (1 << 4), + Reserved = (1 << 9), + Execute = (1 << 15), Used = Present | Reserved, }; diff --git a/kernel/include/kernel/Memory/VirtualRange.h b/kernel/include/kernel/Memory/VirtualRange.h index 21f598bc..c402294e 100644 --- a/kernel/include/kernel/Memory/VirtualRange.h +++ b/kernel/include/kernel/Memory/VirtualRange.h @@ -15,9 +15,9 @@ namespace Kernel public: // Create virtual range to fixed virtual address - static BAN::ErrorOr> create_to_vaddr(PageTable&, vaddr_t, size_t, uint8_t flags); + static BAN::ErrorOr> create_to_vaddr(PageTable&, vaddr_t, size_t, PageTable::flags_t flags); // Create virtual range to virtual address range - static BAN::ErrorOr> create_to_vaddr_range(PageTable&, vaddr_t vaddr_start, vaddr_t vaddr_end, size_t, uint8_t flags); + static BAN::ErrorOr> create_to_vaddr_range(PageTable&, vaddr_t vaddr_start, vaddr_t vaddr_end, size_t, PageTable::flags_t flags); // Create virtual range in kernel memory with kmalloc static BAN::ErrorOr> create_kmalloc(size_t); ~VirtualRange(); @@ -26,7 +26,7 @@ namespace Kernel vaddr_t vaddr() const { return m_vaddr; } size_t size() const { return m_size; } - uint8_t flags() const { return m_flags; } + PageTable::flags_t flags() const { return m_flags; } void set_zero(); void copy_from(size_t offset, const uint8_t* buffer, size_t bytes); @@ -39,7 +39,7 @@ namespace Kernel bool m_kmalloc { false }; vaddr_t m_vaddr { 0 }; size_t m_size { 0 }; - uint8_t m_flags { 0 }; + PageTable::flags_t m_flags { 0 }; BAN::Vector m_physical_pages; }; diff --git a/kernel/kernel/Memory/FixedWidthAllocator.cpp b/kernel/kernel/Memory/FixedWidthAllocator.cpp index 648ad43a..a77f2df2 100644 --- a/kernel/kernel/Memory/FixedWidthAllocator.cpp +++ b/kernel/kernel/Memory/FixedWidthAllocator.cpp @@ -263,7 +263,7 @@ namespace Kernel vaddr_t vaddr = address_of_node(node); vaddr_t page_begin = vaddr & PAGE_ADDR_MASK; - uint8_t flags = m_page_table.get_page_flags(page_begin); + PageTable::flags_t flags = m_page_table.get_page_flags(page_begin); // Allocate and copy all data from this allocation to the new one if (allocator->allocate_page_if_needed(page_begin, flags)) diff --git a/kernel/kernel/Memory/GeneralAllocator.cpp b/kernel/kernel/Memory/GeneralAllocator.cpp index 54b076dc..fd6d95d2 100644 --- a/kernel/kernel/Memory/GeneralAllocator.cpp +++ b/kernel/kernel/Memory/GeneralAllocator.cpp @@ -97,7 +97,7 @@ namespace Kernel new_allocation.address = allocation.address; MUST(new_allocation.pages.reserve(allocation.pages.size())); - uint8_t flags = m_page_table.get_page_flags(allocation.address); + PageTable::flags_t flags = m_page_table.get_page_flags(allocation.address); for (size_t i = 0; i < allocation.pages.size(); i++) { paddr_t paddr = Heap::get().take_free_page(); diff --git a/kernel/kernel/Memory/VirtualRange.cpp b/kernel/kernel/Memory/VirtualRange.cpp index 1f0b936f..a33c4090 100644 --- a/kernel/kernel/Memory/VirtualRange.cpp +++ b/kernel/kernel/Memory/VirtualRange.cpp @@ -6,7 +6,7 @@ namespace Kernel { - BAN::ErrorOr> VirtualRange::create_to_vaddr(PageTable& page_table, vaddr_t vaddr, size_t size, uint8_t flags) + BAN::ErrorOr> VirtualRange::create_to_vaddr(PageTable& page_table, vaddr_t vaddr, size_t size, PageTable::flags_t flags) { ASSERT(size % PAGE_SIZE == 0); ASSERT(vaddr % PAGE_SIZE == 0); @@ -45,7 +45,7 @@ namespace Kernel return result; } - BAN::ErrorOr> VirtualRange::create_to_vaddr_range(PageTable& page_table, vaddr_t vaddr_start, vaddr_t vaddr_end, size_t size, uint8_t flags) + BAN::ErrorOr> VirtualRange::create_to_vaddr_range(PageTable& page_table, vaddr_t vaddr_start, vaddr_t vaddr_end, size_t size, PageTable::flags_t flags) { ASSERT(size % PAGE_SIZE == 0); ASSERT(vaddr_start > 0); diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index 95714f67..16b89c90 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -499,7 +499,7 @@ namespace Kernel break; case LibELF::PT_LOAD: { - uint8_t flags = PageTable::Flags::UserSupervisor | PageTable::Flags::Present; + PageTable::flags_t flags = PageTable::Flags::UserSupervisor | PageTable::Flags::Present; if (elf_program_header.p_flags & LibELF::PF_W) flags |= PageTable::Flags::ReadWrite; if (elf_program_header.p_flags & LibELF::PF_X)