mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 08:24:32 -08:00
[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:
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user