aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatteo Gmür <matteo.gmuer1@ost.ch>2025-05-16 13:27:16 +0000
committerMatteo Gmür <matteo.gmuer1@ost.ch>2025-05-16 13:27:16 +0000
commit5c314eef566df2732973e8cb35974ec49748adba (patch)
treefff3f587c7c5c32fd30362dc92c4b07cc68603e7
parentd4cc546df6eba2dd287785f1a63fbcce4a1b9bc0 (diff)
downloadteachos-5c314eef566df2732973e8cb35974ec49748adba.tar.xz
teachos-5c314eef566df2732973e8cb35974ec49748adba.zip
Fix bug where level 4 to level 2 entries are not mapped user accesible.
-rw-r--r--arch/x86_64/include/arch/memory/heap/user_heap_allocator.hpp3
-rw-r--r--arch/x86_64/include/arch/memory/paging/active_page_table.hpp5
-rw-r--r--arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp5
-rw-r--r--arch/x86_64/include/arch/memory/paging/page_entry.hpp2
-rw-r--r--arch/x86_64/include/arch/memory/paging/page_table.hpp11
-rw-r--r--arch/x86_64/scripts/kernel.ld2
-rw-r--r--arch/x86_64/src/memory/paging/page_entry.cpp2
-rw-r--r--arch/x86_64/src/user/main.cpp16
8 files changed, 15 insertions, 31 deletions
diff --git a/arch/x86_64/include/arch/memory/heap/user_heap_allocator.hpp b/arch/x86_64/include/arch/memory/heap/user_heap_allocator.hpp
index 9c04718..42af23f 100644
--- a/arch/x86_64/include/arch/memory/heap/user_heap_allocator.hpp
+++ b/arch/x86_64/include/arch/memory/heap/user_heap_allocator.hpp
@@ -32,6 +32,9 @@ namespace teachos::arch::memory::heap
[[gnu::section(".user_text")]]
auto allocate(std::size_t size) -> void *;
+ /**
+ * @copybrief heap_allocator::deallocate
+ */
[[gnu::section(".user_text")]]
auto deallocate(void * pointer) noexcept -> void;
diff --git a/arch/x86_64/include/arch/memory/paging/active_page_table.hpp b/arch/x86_64/include/arch/memory/paging/active_page_table.hpp
index d77b76c..f68d8b6 100644
--- a/arch/x86_64/include/arch/memory/paging/active_page_table.hpp
+++ b/arch/x86_64/include/arch/memory/paging/active_page_table.hpp
@@ -82,10 +82,7 @@ namespace teachos::arch::memory::paging
for (auto level = page_table_handle::LEVEL4; level != page_table_handle::LEVEL1; --level)
{
- // Ignore all bits passed besides the entry::USER_ACCESSIBLE bit, because for the entry into the Level 4 up to
- // Level 2 page, we always have to set the entry::PRESENT and entry::WRITABLE bit anyway.
- current_handle = current_handle.next_table_or_create(allocator, page.get_level_index(level),
- flags.to_ulong() & entry::USER_ACCESSIBLE);
+ current_handle = current_handle.next_table_or_create(allocator, page.get_level_index(level), flags);
}
auto & level1_entry = current_handle[page.get_level_index(page_table_handle::LEVEL1)];
diff --git a/arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp b/arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp
index 94c937d..5bf14fb 100644
--- a/arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp
+++ b/arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp
@@ -142,17 +142,14 @@ namespace teachos::arch::memory::paging
entry entry{section.flags};
// Required to be accessible in User Mode:
- // - .boot_rodata (Contains constant data stored in ROM)
// - .boot_bss (Contains statically allocated variables)
// - .user_text (Contains the actual user code executed)
// - .user_data (Contains static user variables)
// - .stl_text (Contains code for custom std implementations and standard library code)
- if (section.physical_address == 0x100000 /* .boot_rodata */ ||
- section.physical_address == 0x102000 /* .boot_bss */ ||
+ if (section.physical_address == 0x102000 /* .boot_bss */ ||
section.physical_address == 0x209000 /* .stl_text */)
{
entry.set_user_accessible();
- entry.set_global();
}
// TODO: Can be removed once stl has been completly mapped into stl text
diff --git a/arch/x86_64/include/arch/memory/paging/page_entry.hpp b/arch/x86_64/include/arch/memory/paging/page_entry.hpp
index 03cdb1a..8147c5c 100644
--- a/arch/x86_64/include/arch/memory/paging/page_entry.hpp
+++ b/arch/x86_64/include/arch/memory/paging/page_entry.hpp
@@ -77,8 +77,6 @@ namespace teachos::arch::memory::paging
*/
auto set_user_accessible() -> void;
- auto set_global() -> void;
-
/**
* @brief Calculates the physical frame this entry is pointing too, can be null if the page is not present in
* memory.
diff --git a/arch/x86_64/include/arch/memory/paging/page_table.hpp b/arch/x86_64/include/arch/memory/paging/page_table.hpp
index 7b7e29e..b972337 100644
--- a/arch/x86_64/include/arch/memory/paging/page_table.hpp
+++ b/arch/x86_64/include/arch/memory/paging/page_table.hpp
@@ -95,13 +95,20 @@ namespace teachos::arch::memory::paging
{
auto const allocated_frame = allocator.allocate_frame();
exception_handling::assert(allocated_frame.has_value(), "[Page mapper] Unable to allocate frame");
- this->operator[](table_index)
- .set_entry(allocated_frame.value(), flags.to_ulong() | entry::PRESENT | entry::WRITABLE);
+ this->operator[](table_index).set_entry(allocated_frame.value(), entry::PRESENT | entry::WRITABLE);
// There should now be an entry at the previously not existent index, therefore we can simply access it again.
next_handle = next_table(table_index);
exception_handling::assert(next_handle.has_value(), "[Page mapper] Unable to create new entry into page table");
next_handle.value().zero_entries();
}
+
+ // Check if the now created or previously created level 4, level 3 or level 2 page entry is used by user
+ // accessible code. If it is that page entry needs to be user accesible as well.
+ entry entry{flags.to_ulong()};
+ if (entry.contains_flags(entry::USER_ACCESSIBLE))
+ {
+ this->operator[](table_index).set_user_accessible();
+ }
return next_handle.value();
}
diff --git a/arch/x86_64/scripts/kernel.ld b/arch/x86_64/scripts/kernel.ld
index e5cbc73..23f9681 100644
--- a/arch/x86_64/scripts/kernel.ld
+++ b/arch/x86_64/scripts/kernel.ld
@@ -89,7 +89,7 @@ SECTIONS
{
*(.stl_text)
KEEP(*libstdc++.a:*(.text .text.*))
- KEEP(*libatomic.a:*(.text .text.*)) /* Attempt to move atomic stl into stl_text as well, doesn't work */
+ KEEP(*libatomic.a:*(.text .text.*)) /* TODO: Attempt to move atomic stl into stl_text as well, doesn't work */
}
.text ALIGN(4K) : AT(ADDR (.text))
diff --git a/arch/x86_64/src/memory/paging/page_entry.cpp b/arch/x86_64/src/memory/paging/page_entry.cpp
index a5b44fa..57045ca 100644
--- a/arch/x86_64/src/memory/paging/page_entry.cpp
+++ b/arch/x86_64/src/memory/paging/page_entry.cpp
@@ -39,8 +39,6 @@ namespace teachos::arch::memory::paging
auto entry::set_user_accessible() -> void { flags |= entry::USER_ACCESSIBLE; }
- auto entry::set_global() -> void { flags |= entry::GLOBAL; }
-
auto entry::calculate_pointed_to_frame() const -> std::optional<allocator::physical_frame>
{
if (contains_flags(PRESENT))
diff --git a/arch/x86_64/src/user/main.cpp b/arch/x86_64/src/user/main.cpp
index a435a41..747a8a4 100644
--- a/arch/x86_64/src/user/main.cpp
+++ b/arch/x86_64/src/user/main.cpp
@@ -6,10 +6,6 @@
#include <algorithm>
#include <atomic>
-// TODO: Disallow these imports
-#include "arch/kernel/cpu/if.hpp"
-#include "arch/video/vga/text.hpp"
-
namespace teachos::arch::user
{
auto main() -> void
@@ -18,8 +14,6 @@ namespace teachos::arch::user
context_switching::syscall::syscall(context_switching::syscall::type::WRITE,
{reinterpret_cast<uint64_t>(&syscall_message)});
- // kernel::cpu::clear_interrupt_flag(); // Causes crash Kernel Code (.text) is not mapped in User mMde
-
int test = std::max(5, 10);
(void)test;
@@ -29,16 +23,6 @@ namespace teachos::arch::user
auto address = memory::heap::global_heap_allocator::malloc(8U);
(void)address;
- // auto test = new int{20}; // Causes crash Heap is not mapped in User Mode
- // (void)test;
-
- // if (!error)
- // {
- // // Causes crash vga is not mapped in User Mode
- // video::vga::text::write("Successfully made a SYSCALL and returned with SYSRETQ!",
- // video::vga::text::common_attributes::green_on_black);
- // }
-
for (;;)
{
}