aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86_64/include/arch/memory/paging/active_page_table.hpp23
-rw-r--r--arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp23
2 files changed, 14 insertions, 32 deletions
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 a60b3ad..8b12800 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
@@ -136,7 +136,6 @@ namespace teachos::arch::memory::paging
"[Page Mapper] Attempted to unmap page, which has not been mapped previously");
auto current_handle = active_handle;
- std::array<page_table_handle, 3U> handles{current_handle, current_handle, current_handle};
for (auto level = page_table_handle::LEVEL4; level != page_table_handle::LEVEL1; --level)
{
@@ -146,28 +145,10 @@ namespace teachos::arch::memory::paging
// fail. This can only mean that we attempted to unmap a huge page, which is not supported in the first place.
exception_handling::assert(next_handle.has_value(), "[Page Mapper] Unable to unmap huge pages");
current_handle = next_handle.value();
- // The level is used as the index, because it ensures the first level is the lowest one and then the remaining
- // levels in ascending order. This is required, because we first have to clear the Level 1 page entry to check
- // if the Level 1 page is now empty, to clear the Level 2 page entry, which will then also check if the Level 2
- // page is empty and clear the Level 3 page entry and so on.
- handles.at(level - 1U) = current_handle;
}
- // Unmaps all entries starting from the Level 1 page table, and unmaps higher levels as well if that entry was the
- // last one. We check if it was the last one using is empty on the page table handle, when we have removed the
- // page to be unmapped.
- for (auto & handle : handles)
- {
- unmap_page_table_entry(allocator, page, handle);
- if (!handle.is_empty())
- {
- break;
- }
- }
- // Uses flush all instead of cpu::tlb_flush(page.start_address());, because when we unmap the active page and
- // only flush one page, the rest of the page which is huge still exist in the cache and
- // can therefore still be accessed. But because they are huge pages the new mapping can not be accessed correctly.
- cpu::tlb_flush_all();
+ unmap_page_table_entry(allocator, page, current_handle);
+ cpu::tlb_flush(page.start_address());
}
private:
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 bcc3eba..f980451 100644
--- a/arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp
+++ b/arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp
@@ -40,17 +40,17 @@ namespace teachos::arch::memory::paging
*/
auto remap_kernel() -> active_page_table &
{
- /*temporary_page temporary_page{virtual_page{0xCAFEBABE}, allocator};*/
+ temporary_page temporary_page{virtual_page{0xCAFEBABE}, allocator};
auto & active_table = active_page_table::create_or_get();
- /*auto const frame = allocator.allocate_frame();
+ auto const frame = allocator.allocate_frame();
exception_handling::assert(frame.has_value(),
"[Kernel Mapper] Frame could not be allocated and therefore kernel not mapped");
- inactive_page_table new_table{frame.value(), active_table, temporary_page};*/
- remap_elf_kernel_sections(active_table);
- /*auto const old_table = switch_active_page_table(new_table);
+ inactive_page_table new_table{frame.value(), active_table, temporary_page};
+ remap_elf_kernel_sections(new_table, temporary_page, active_table);
+ auto const old_table = switch_active_page_table(new_table);
auto const old_level_4_page =
virtual_page::containing_address(old_table.page_table_level_4_frame.start_address());
- active_table.unmap_page(allocator, old_level_4_page);*/
+ active_table.unmap_page(allocator, old_level_4_page);
return active_table;
}
@@ -72,19 +72,20 @@ namespace teachos::arch::memory::paging
* @param active_table Active level 4 page table that has its recursive mapping overwritten temporarily and then
* restored once the process is finished.
*/
- auto remap_elf_kernel_sections(active_page_table & active_table) -> void
+ auto remap_elf_kernel_sections(inactive_page_table & inactive_table, temporary_page & temporary_page,
+ active_page_table & active_table) -> void
{
- /*auto const backup =
+ auto const backup =
allocator::physical_frame::containing_address(cpu::read_control_register(cpu::control_register::CR3));
auto page_table_level4 = temporary_page.map_table_frame(backup, active_table);
- active_table[511].set_entry(inactive_table.page_table_level_4_frame, entry::PRESENT | entry::WRITABLE);*/
+ active_table[511].set_entry(inactive_table.page_table_level_4_frame, entry::PRESENT | entry::WRITABLE);
cpu::tlb_flush_all();
map_elf_kernel_sections(active_table);
- /*page_table_level4[511].set_entry(backup, entry::PRESENT | entry::WRITABLE);*/
+ page_table_level4[511].set_entry(backup, entry::PRESENT | entry::WRITABLE);
cpu::tlb_flush_all();
- /*temporary_page.unmap_page(active_table);*/
+ temporary_page.unmap_page(active_table);
}
/**