From cadacc24aed06c1a90af5e8d693c7726049f4b50 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sun, 27 Nov 2016 23:21:47 +0100 Subject: [PATCH] reserve at boot time a region for the heap => no race between stack und heap creation --- include/hermit/config.h | 3 ++- kernel/main.c | 5 ++++- kernel/syscall.c | 23 +++++++++++++++++++---- mm/vma.c | 6 ++++++ 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/include/hermit/config.h b/include/hermit/config.h index 2e103436f..82a1862d6 100644 --- a/include/hermit/config.h +++ b/include/hermit/config.h @@ -42,7 +42,8 @@ extern "C" { #define CACHE_LINE 64 #define KERNEL_STACK_SIZE (8*1024) #define DEFAULT_STACK_SIZE (256*1024) -#define HEAP_START (1ULL << 34) +#define HEAP_START (PAGE_2M_FLOOR((size_t)&kernel_end) + 4*PAGE_SIZE) +#define HEAP_SIZE (1ULL << 32) #define KMSG_SIZE (4*1024) #define INT_SYSCALL 0x80 #define MAILBOX_SIZE 128 diff --git a/kernel/main.c b/kernel/main.c index 221c7c04a..f268ef8d6 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -392,7 +392,9 @@ static int initd(void* arg) curr_task->heap->start = PAGE_FLOOR(heap); curr_task->heap->end = PAGE_FLOOR(heap); - // reserve VMA region + // region is already reserved for the heap, we have to change the + // property of the first page + vma_free(curr_task->heap->start, curr_task->heap->start+PAGE_SIZE); vma_add(curr_task->heap->start, curr_task->heap->start+PAGE_SIZE, VMA_HEAP|VMA_USER); //create_kernel_task(NULL, foo, "foo1", NORMAL_PRIO); @@ -595,6 +597,7 @@ int hermit_main(void) PAUSE; print_status(); + //vma_dump(); create_kernel_task_on_core(NULL, initd, NULL, NORMAL_PRIO, boot_processor); diff --git a/kernel/syscall.c b/kernel/syscall.c index f738cb264..daf7c5ff9 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -43,6 +43,13 @@ #include #include +/* + * 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; + //TODO: don't use one big kernel lock to comminicate with all proxies static spinlock_irqsave_t lwip_lock = SPINLOCK_IRQSAVE_INIT; @@ -244,11 +251,19 @@ ssize_t sys_sbrk(ssize_t incr) spinlock_lock(&heap_lock); ret = heap->end; - heap->end += incr; - // reserve VMA regions - if (PAGE_CEIL(heap->end) > PAGE_CEIL(ret)) - vma_add(PAGE_CEIL(ret), PAGE_FLOOR(heap->end), VMA_HEAP|VMA_USER); + // check heapp boundaries + if ((heap->end >= HEAP_START) && (heap->end+incr < HEAP_START + HEAP_SIZE)) { + heap->end += incr; + + // reserve VMA regions + if (PAGE_CEIL(heap->end) > PAGE_CEIL(ret)) { + // region is already reserved for the heap, we have to change the + // property + vma_free(PAGE_CEIL(ret), PAGE_FLOOR(heap->end)); + vma_add(PAGE_CEIL(ret), PAGE_FLOOR(heap->end), VMA_HEAP|VMA_USER); + } + } else ret = -ENOMEM; // allocation and mapping of new pages for the heap // is catched by the pagefault handler diff --git a/mm/vma.c b/mm/vma.c index c1652794a..435ba0977 100644 --- a/mm/vma.c +++ b/mm/vma.c @@ -68,6 +68,11 @@ int vma_init(void) if (BUILTIN_EXPECT(ret, 0)) goto out; + // reserve space for the heap + ret = vma_add(HEAP_START, HEAP_START+HEAP_SIZE, VMA_NO_ACCESS); + if (BUILTIN_EXPECT(ret, 0)) + goto out; + #ifdef CONFIG_VGA // add VGA video memory ret = vma_add(VIDEO_MEM_ADDR, VIDEO_MEM_ADDR + PAGE_SIZE, VMA_READ|VMA_WRITE); @@ -141,6 +146,7 @@ found: new->flags = flags; new->next = succ; new->prev = pred; + LOG_DEBUG("vma_alloc: create new vma, new->start 0x%zx, new->end 0x%zx\n", new->start, new->end); if (succ) succ->prev = new;