diff --git a/arch/x86/mm/page64.c b/arch/x86/mm/page64.c index 00907459..25efb01a 100644 --- a/arch/x86/mm/page64.c +++ b/arch/x86/mm/page64.c @@ -101,6 +101,35 @@ static inline size_t map_to_virt(size_t addr) { return canonicalize(addr << (map_to_level(addr) * PAGE_MAP_SHIFT)); } +int create_page_map(task_t* task, int copy) +{ + size_t phys; + uint32_t ret; + + // fixed mapping for paging structures + page_map_t *current = (page_map_t*) PAGE_PML4; + page_map_t *new = (page_map_t*) (PAGE_PML4 - 0x1000); + + // get new pml4 table + phys = get_page(); + if (!phys) return -ENOMEM; + + current->entries[PAGE_MAP_ENTRIES-2] = phys|KERN_TABLE; + new->entries[PAGE_MAP_ENTRIES-1] = phys|KERN_TABLE; + + tlb_flush(); // ouch :( + + spinlock_lock(&kslock); + ret = copy_page_map(current, new, copy); + spinlock_unlock(&kslock); + + new->entries[PAGE_MAP_ENTRIES-1] = phys|KERN_TABLE; + current->entries[PAGE_MAP_ENTRIES-2] = 0; + + task->page_map = (page_map_t*) phys; + + kprintf("create_page_map: allocated %u page tables\n", ret); + return ret; } int drop_page_map(void)