aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2025-12-03 20:40:54 +0100
committerFelix Morgner <felix.morgner@ost.ch>2025-12-03 20:40:54 +0100
commitf3dd2b2f5bd1b5dd4d4309a30db3c7733b8f63bb (patch)
treee8f6008c359f5c67fd0aeed47063356483c99203
parent448632c3c9c919e8eda44e8a83082f60983057b7 (diff)
downloadteachos-f3dd2b2f5bd1b5dd4d4309a30db3c7733b8f63bb.tar.xz
teachos-f3dd2b2f5bd1b5dd4d4309a30db3c7733b8f63bb.zip
x86_64/memory: only deallocate allocated frames
-rw-r--r--arch/x86_64/include/x86_64/memory/scoped_mapping.hpp1
-rw-r--r--arch/x86_64/src/memory/scoped_mapping.cpp39
2 files changed, 28 insertions, 12 deletions
diff --git a/arch/x86_64/include/x86_64/memory/scoped_mapping.hpp b/arch/x86_64/include/x86_64/memory/scoped_mapping.hpp
index dff54ec..99585bc 100644
--- a/arch/x86_64/include/x86_64/memory/scoped_mapping.hpp
+++ b/arch/x86_64/include/x86_64/memory/scoped_mapping.hpp
@@ -57,6 +57,7 @@ namespace teachos::memory::x86_64
page m_page;
frame_allocator * m_allocator;
bool m_mapped;
+ std::uint8_t m_allocated;
};
} // namespace teachos::memory::x86_64
diff --git a/arch/x86_64/src/memory/scoped_mapping.cpp b/arch/x86_64/src/memory/scoped_mapping.cpp
index 6e2328d..be15330 100644
--- a/arch/x86_64/src/memory/scoped_mapping.cpp
+++ b/arch/x86_64/src/memory/scoped_mapping.cpp
@@ -18,12 +18,14 @@ namespace teachos::memory::x86_64
: m_page{std::exchange(other.m_page, page{})}
, m_allocator{std::exchange(other.m_allocator, nullptr)}
, m_mapped{std::exchange(other.m_mapped, false)}
+ , m_allocated{std::exchange(other.m_allocated, 0)}
{}
scoped_mapping::scoped_mapping(page page, frame_allocator & allocator)
: m_page{page}
, m_allocator{&allocator}
, m_mapped{false}
+ , m_allocated{}
{
if (paging_root::get().translate(page))
{
@@ -52,6 +54,7 @@ namespace teachos::memory::x86_64
swap(m_page, other.m_page);
swap(m_allocator, other.m_allocator);
swap(m_mapped, other.m_mapped);
+ swap(m_allocated, other.m_allocated);
return *this;
}
@@ -65,6 +68,7 @@ namespace teachos::memory::x86_64
auto new_frame = m_allocator->allocate();
pml4[pml4_index].frame(*new_frame, page_table::entry::flags::present | flags);
std::construct_at(pml4.next(pml4_index).value());
+ m_allocated |= 1uz << 2;
}
auto pml3 = pml4.next(pml4_index).value();
@@ -74,6 +78,7 @@ namespace teachos::memory::x86_64
auto new_frame = m_allocator->allocate();
(*pml3)[pml3_index].frame(*new_frame, page_table::entry::flags::present | flags);
std::construct_at((*pml3).next(pml3_index).value());
+ m_allocated |= 1uz << 1;
}
auto pml2 = (*pml3).next(pml3_index).value();
@@ -83,6 +88,7 @@ namespace teachos::memory::x86_64
auto new_frame = m_allocator->allocate();
(*pml2)[pml2_index].frame(*new_frame, page_table::entry::flags::present | flags);
std::construct_at((*pml2).next(pml2_index).value());
+ m_allocated |= 1uz << 0;
}
auto pml1 = (*pml2).next(pml2_index).value();
@@ -105,25 +111,34 @@ namespace teachos::memory::x86_64
auto pml2 = pml3->next(pml_index<3>(m_page)).value();
auto pml1 = pml2->next(pml_index<2>(m_page)).value();
- auto pml1_entry = (*pml1)[pml_index<1>(m_page)];
- (*pml1)[pml_index<1>(m_page)].clear();
- if (pml1->empty())
+ if (m_allocated & 1uz << 0)
{
- m_allocator->release(pml1_entry.frame().value());
+ auto pml1_entry = (*pml1)[pml_index<1>(m_page)];
+ (*pml1)[pml_index<1>(m_page)].clear();
+ if (pml1->empty())
+ {
+ m_allocator->release(pml1_entry.frame().value());
+ }
}
- auto pml2_entry = (*pml2)[pml_index<2>(m_page)];
- (*pml2)[pml_index<2>(m_page)].clear();
- if (pml2->empty())
+ if (m_allocated & 1uz << 1)
{
- m_allocator->release(pml2_entry.frame().value());
+ auto pml2_entry = (*pml2)[pml_index<2>(m_page)];
+ (*pml2)[pml_index<2>(m_page)].clear();
+ if (pml2->empty())
+ {
+ m_allocator->release(pml2_entry.frame().value());
+ }
}
- auto pml3_entry = (*pml3)[pml_index<3>(m_page)];
- (*pml3)[pml_index<3>(m_page)].clear();
- if (pml3->empty())
+ if (m_allocated & 1uz << 2)
{
- m_allocator->release(pml3_entry.frame().value());
+ auto pml3_entry = (*pml3)[pml_index<3>(m_page)];
+ (*pml3)[pml_index<3>(m_page)].clear();
+ if (pml3->empty())
+ {
+ m_allocator->release(pml3_entry.frame().value());
+ }
}
m_mapped = false;