[kernel] Move page mapping into vm_space

vm_space no longer relies on page_manager to map pages during a page
fault. Other changes that come with this commit:

- C++ standard has been changed to C++17
- enum bitfield operators became constexpr
- enum bifrield operators can take a mix of ints and enum arguments
- added page table flags enum instead of relying on ints
- remove page_table::unmap_table and page_table::unmap_pages
This commit is contained in:
2020-09-20 10:52:57 -07:00
parent deb2fa0a09
commit 1b392a0551
7 changed files with 107 additions and 143 deletions

View File

@@ -76,84 +76,6 @@ page_manager::map_pages(uintptr_t address, size_t count, bool user, page_table *
return ret;
}
void
page_manager::unmap_table(page_table *table, page_table::level lvl, bool free, page_table_indices index)
{
const int max =
lvl == page_table::level::pml4
? pml4e_kernel
: table_entries;
uintptr_t free_start = 0;
uintptr_t free_start_virt = 0;
uintptr_t free_count = 0;
size_t size =
lvl == page_table::level::pdp ? (1<<30) :
lvl == page_table::level::pd ? (1<<21) :
lvl == page_table::level::pt ? (1<<12) :
0;
for (int i = 0; i < max; ++i) {
if (!table->is_present(i)) continue;
index[lvl] = i;
bool is_page =
lvl == page_table::level::pt ||
table->is_large_page(lvl, i);
if (is_page) {
uintptr_t frame = table->entries[i] & ~0xfffull;
if (!free_count || frame != free_start + free_count * size) {
if (free_count && free) {
log::debug(logs::paging,
" freeing v:%016lx-%016lx p:%016lx-%016lx",
free_start_virt, free_start_virt + free_count * frame_size,
free_start, free_start + free_count * frame_size);
m_frames.free(free_start, (free_count * size) / frame_size);
free_count = 0;
}
if (!free_count) {
free_start = frame;
free_start_virt = index.addr();
}
}
free_count += 1;
} else {
page_table *next = table->get(i);
unmap_table(next, page_table::deeper(lvl), free, index);
}
}
if (free_count && free) {
log::debug(logs::paging,
" freeing v:%016lx-%016lx p:%016lx-%016lx",
free_start_virt, free_start_virt + free_count * frame_size,
free_start, free_start + free_count * frame_size);
m_frames.free(free_start, (free_count * size) / frame_size);
}
page_table::free_table_page(table);
log::debug(logs::paging, "Unmapped%s lv %d table at %016lx",
free ? " (and freed)" : "", lvl, table);
}
void
page_manager::unmap_pages(void* address, size_t count, page_table *pml4)
{
if (!pml4)
pml4 = get_pml4();
uintptr_t iaddr = reinterpret_cast<uintptr_t>(address);
page_out(pml4, iaddr, count, true);
}
void
page_manager::check_needs_page(page_table *table, unsigned index, bool user)
{