From 750fff5230b8e2900e4599b64e3bae006659b421 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Fri, 1 Jan 2016 17:48:31 +0100 Subject: [PATCH] page fault handler maps on demand pages for the BSS section --- hermit/arch/x86/mm/page.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/hermit/arch/x86/mm/page.c b/hermit/arch/x86/mm/page.c index 41ea16c6f..8e1dc60ad 100644 --- a/hermit/arch/x86/mm/page.c +++ b/hermit/arch/x86/mm/page.c @@ -47,7 +47,7 @@ /* Note that linker symbols are not variables, they have no memory * allocated for maintaining a value, rather their address is their value. */ extern const void kernel_start; -//extern const void kernel_end; +extern const void kernel_end; /// This page is reserved for copying #define PAGE_TMP (PAGE_FLOOR((size_t) &kernel_start) - PAGE_SIZE) @@ -288,8 +288,33 @@ void page_fault_handler(struct state *s) size_t viraddr = read_cr2(); task_t* task = per_core(current_task); - // on demand userspace heap mapping - if ((task->heap) && (viraddr >= task->heap->start) && (viraddr < task->heap->end)) { + // do we got a pagefault within the kernel? => BSS is not initialized + if ((viraddr >= (size_t) &kernel_start) && (viraddr < (size_t) &kernel_end)) + { + kprintf("Pagefault within the kernel: 0x%llx\n", viraddr); + + viraddr &= PAGE_MASK; + + size_t phyaddr = get_page(); + if (BUILTIN_EXPECT(!phyaddr, 0)) { + kprintf("out of memory: task = %u\n", task->id); + goto default_handler; + } + + int ret = page_map(viraddr, phyaddr, 1, PG_RW); + if (BUILTIN_EXPECT(ret, 0)) { + kprintf("map_region: could not map %#lx to %#lx, task = %u\n", phyaddr, viraddr, task->id); + put_page(phyaddr); + + goto default_handler; + } + + memset((void*) viraddr, 0x00, PAGE_SIZE); // fill with zeros + + return; + } else if ((task->heap) && (viraddr >= task->heap->start) && (viraddr < task->heap->end)) { + // on demand userspace heap mapping + viraddr &= PAGE_MASK; size_t phyaddr = get_page();