diff options
| author | Matteo Gmür <matteo.gmuer1@ost.ch> | 2024-10-29 08:05:22 +0000 |
|---|---|---|
| committer | Matteo Gmür <matteo.gmuer1@ost.ch> | 2024-10-29 08:05:22 +0000 |
| commit | 5334a63e7fc3959536f4f443c86f8913f7cb2451 (patch) | |
| tree | cbf24f478785bd4a296057a221451e29546307dc /arch | |
| parent | 4c4479a4b728fd7eaf007649e946f9435ee1e402 (diff) | |
| download | teachos-5334a63e7fc3959536f4f443c86f8913f7cb2451.tar.xz teachos-5334a63e7fc3959536f4f443c86f8913f7cb2451.zip | |
Unmap all empty page tables in unmap function.
Diffstat (limited to 'arch')
3 files changed, 22 insertions, 15 deletions
diff --git a/arch/x86_64/include/arch/memory/allocator/area_frame_allocator.hpp b/arch/x86_64/include/arch/memory/allocator/area_frame_allocator.hpp index 8e971f0..599723f 100644 --- a/arch/x86_64/include/arch/memory/allocator/area_frame_allocator.hpp +++ b/arch/x86_64/include/arch/memory/allocator/area_frame_allocator.hpp @@ -41,6 +41,10 @@ namespace teachos::arch::memory::allocator /** * @brief Deallocates a previously allocated physical_frame. * + * @note Simply does nothing, because the simply area frame + * allocator implementation does not keep track of free or used frames and can therefore not deallocate, because it + * does not know which frames have ben alocated in the first place. + * * @param physical_frame Previously allocated physical_frame that should be allocated. */ auto deallocate_frame(physical_frame physical_frame) -> void; diff --git a/arch/x86_64/include/arch/memory/paging/page_mapper.hpp b/arch/x86_64/include/arch/memory/paging/page_mapper.hpp index 801ccfb..a9f8eb8 100644 --- a/arch/x86_64/include/arch/memory/paging/page_mapper.hpp +++ b/arch/x86_64/include/arch/memory/paging/page_mapper.hpp @@ -158,26 +158,34 @@ namespace teachos::arch::memory::paging "[Page Mapper] Attempted to unmap page, which has not been mapped previously"); auto current_handle = create_or_get(); - - std::array<page_table_handle *, 4> handles{}; + std::array<page_table_handle, 4U> handles{current_handle, current_handle, current_handle, current_handle}; for (auto level = page_table_handle::LEVEL4; level != page_table_handle::LEVEL1; --level) { - handles[level] = *current_handle; - auto const level_index = page.get_level_index(level); auto const next_handle = current_handle.next_table(level_index); // The next table method failed even tough the page has to be mapped already, because translate_page did not 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; } - std::ranges::for_each(handles, [&allocator, page](page_table_handle * handle) { - exception_handling::assert(handle != nullptr, "[Page Mapper] Attempted to unmap page behind nullpointer"); - unmap_page_table_entry(allocator, page, *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; + } + } invalidate_page_cache(page.start_address()); } } // namespace teachos::arch::memory::paging diff --git a/arch/x86_64/src/memory/allocator/area_frame_allocator.cpp b/arch/x86_64/src/memory/allocator/area_frame_allocator.cpp index e79cd8b..1e87147 100644 --- a/arch/x86_64/src/memory/allocator/area_frame_allocator.cpp +++ b/arch/x86_64/src/memory/allocator/area_frame_allocator.cpp @@ -83,10 +83,5 @@ namespace teachos::arch::memory::allocator return allocate_frame(); } - auto area_frame_allocator::deallocate_frame(physical_frame physical_frame) -> void - { - // TODO: Fix create acutal deallocation of frames if it is even possible. Can the area frame allocator even - // deallocate in the first place? - next_free_frame = physical_frame; - } + auto area_frame_allocator::deallocate_frame(physical_frame physical_frame) -> void { (void)physical_frame; } } // namespace teachos::arch::memory::allocator |
