From 5c4e1cee4f522e8d785cb98b2994999f4bf4362f Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 4 Dec 2014 21:38:41 +0100 Subject: [PATCH 1/2] add PG_PRESENT by default --- arch/x86/mm/page.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/x86/mm/page.c b/arch/x86/mm/page.c index fd35fe6..e6d99de 100644 --- a/arch/x86/mm/page.c +++ b/arch/x86/mm/page.c @@ -106,7 +106,7 @@ int page_map(size_t viraddr, size_t phyaddr, size_t npages, size_t bits) goto out; /* Reference the new table within its parent */ - self[lvl][vpn] = phyaddr | bits; + self[lvl][vpn] = phyaddr | bits | PG_PRESENT; /* Fill new table with zeros */ memset(&self[lvl-1][vpn<page_lock); - self[PAGE_LEVELS-1][PAGE_MAP_ENTRIES-2] = dest | PG_PRESENT | PG_SELF | PG_RW; + self[PAGE_LEVELS-1][PAGE_MAP_ENTRIES-2] = dest->page_map | PG_PRESENT | PG_SELF | PG_RW; int ret = traverse(PAGE_LEVELS-1, 0); - other[PAGE_LEVELS-1][PAGE_MAP_ENTRIES-1] = dest | PG_PRESENT | PG_SELF | PG_RW; + other[PAGE_LEVELS-1][PAGE_MAP_ENTRIES-1] = dest->page_map | PG_PRESENT | PG_SELF | PG_RW; self [PAGE_LEVELS-1][PAGE_MAP_ENTRIES-2] = 0; spinlock_irqsave_unlock(¤t_task->page_lock); @@ -248,29 +248,29 @@ int page_init() /* Map kernel */ addr = (size_t) &kernel_start; npages = PAGE_FLOOR((size_t) &kernel_end - (size_t) &kernel_start) >> PAGE_BITS; - page_map(addr, addr, npages, PG_PRESENT | PG_RW | /* PG_USER | */ PG_GLOBAL); + page_map(addr, addr, npages, PG_RW | /* PG_USER | */ PG_GLOBAL); #ifdef CONFIG_VGA /* Map video memory */ - page_map(VIDEO_MEM_ADDR, VIDEO_MEM_ADDR, 1, PG_PRESENT | PG_RW | PG_PCD); + page_map(VIDEO_MEM_ADDR, VIDEO_MEM_ADDR, 1, PG_RW | PG_PCD); #endif /* Map multiboot information and modules */ if (mb_info) { addr = (size_t) mb_info & PAGE_MASK; npages = PAGE_FLOOR(sizeof(*mb_info)) >> PAGE_BITS; - page_map(addr, addr, npages, PG_PRESENT | PG_GLOBAL); + page_map(addr, addr, npages, PG_GLOBAL); if (mb_info->flags & MULTIBOOT_INFO_MODS) { addr = mb_info->mods_addr; npages = PAGE_FLOOR(mb_info->mods_count*sizeof(multiboot_module_t)) >> PAGE_BITS; - page_map(addr, addr, npages, PG_PRESENT | PG_GLOBAL); + page_map(addr, addr, npages, PG_GLOBAL); multiboot_module_t* mmodule = (multiboot_module_t*) ((size_t) mb_info->mods_addr); for(i=0; imods_count; i++) { addr = mmodule[i].mod_start; npages = PAGE_FLOOR(mmodule[i].mod_end - mmodule[i].mod_start) >> PAGE_BITS; - page_map(addr, addr, npages, PG_PRESENT | PG_USER | PG_GLOBAL); + page_map(addr, addr, npages, PG_USER | PG_GLOBAL); } } } From 42571eb4eb9cd6e3e486e332a2f0ba920851aa72 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Thu, 4 Dec 2014 21:44:02 +0100 Subject: [PATCH 2/2] added proper accounting of user used page frames --- arch/x86/include/asm/page.h | 4 +++- arch/x86/mm/page.c | 10 ++++++++-- kernel/tasks.c | 14 +++++++------- 3 files changed, 18 insertions(+), 10 deletions(-) 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;