diff --git a/arch/x86/include/asm/page.h b/arch/x86/include/asm/page.h index 271b269..38ac8d5 100644 --- a/arch/x86/include/asm/page.h +++ b/arch/x86/include/asm/page.h @@ -33,6 +33,8 @@ * This file contains the several functions to manage the page tables */ +#include + #ifndef __PAGE_H__ #define __PAGE_H__ @@ -135,7 +137,7 @@ int page_unmap(size_t viraddr, size_t npages); * @retval 0 Success. Everything went fine. * @retval <0 Error. Something went wrong. */ -int page_map_copy(size_t dest); +int page_map_copy(task_t *dest); /** @brief Free a whole page map tree */ int page_map_drop(); diff --git a/arch/x86/mm/page.c b/arch/x86/mm/page.c index e6d99de..fa4e95b 100644 --- a/arch/x86/mm/page.c +++ b/arch/x86/mm/page.c @@ -104,6 +104,9 @@ int page_map(size_t viraddr, size_t phyaddr, size_t npages, size_t bits) size_t phyaddr = get_pages(1); if (BUILTIN_EXPECT(!phyaddr, 0)) goto out; + + if (bits & PG_USER) + atomic_int32_inc(¤t_task->user_usage); /* Reference the new table within its parent */ self[lvl][vpn] = phyaddr | bits | PG_PRESENT; @@ -158,12 +161,13 @@ int page_map_drop() void traverse(int lvl, long vpn) { long stop; for (stop=vpn+PAGE_MAP_ENTRIES; vpnuser_usage); } } } @@ -177,7 +181,7 @@ int page_map_drop() return 0; } -int page_map_copy(size_t dest) +int page_map_copy(task_t *dest) { int traverse(int lvl, long vpn) { long stop; @@ -187,6 +191,8 @@ int page_map_copy(size_t dest) size_t phyaddr = get_pages(1); if (BUILTIN_EXPECT(!phyaddr, 0)) return -ENOMEM; + + atomic_int32_inc(&dest->user_usage); other[lvl][vpn] = phyaddr | (self[lvl][vpn] & ~PAGE_MASK); if (lvl) /* PML4, PDPT, PGD */ diff --git a/kernel/tasks.c b/kernel/tasks.c index b5573ca..4c92990 100644 --- a/kernel/tasks.c +++ b/kernel/tasks.c @@ -122,7 +122,7 @@ static void NORETURN do_exit(int arg) kprintf("Terminate task: %u, return value %d\n", curr_task->id, arg); - page_map_drop(); + page_map_drop(); curr_task->status = TASK_FINISHED; reschedule(); @@ -204,13 +204,13 @@ static int create_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio) spinlock_irqsave_init(&task_table[i].page_lock); atomic_int32_set(&task_table[i].user_usage, 0); - /* Allocated new PGD or PML4 and copy page table */ - size_t map = get_pages(1); - if (BUILTIN_EXPECT(!map, 0)) - goto out; + /* Allocated new PGD or PML4 and copy page table */ + task_table[i].page_map = get_pages(1); + if (BUILTIN_EXPECT(!task_table[i].page_map, 0)) + goto out; - page_map_copy(map); - task_table[i].page_map = map; + /* Copy page tables & user frames of current task to new one */ + page_map_copy(&task_table[i]); if (id) *id = i;