diff --git a/tasks/mm0/include/mmap.h b/tasks/mm0/include/mmap.h index f4615f1..5b5baab 100644 --- a/tasks/mm0/include/mmap.h +++ b/tasks/mm0/include/mmap.h @@ -19,6 +19,7 @@ #define MAP_FIXED 0x10 #define MAP_SHARED 0x01 #define MAP_PRIVATE 0x02 +#define MAP_GROWSDOWN 0x00100 struct vm_area *vma_new(unsigned long pfn_start, unsigned long npages, unsigned int flags, unsigned long file_offset); diff --git a/tasks/mm0/include/vm_area.h b/tasks/mm0/include/vm_area.h index b25ef78..c9ee7fe 100644 --- a/tasks/mm0/include/vm_area.h +++ b/tasks/mm0/include/vm_area.h @@ -36,8 +36,11 @@ #define VMA_PRIVATE (1 << 6) /* For wired pages */ #define VMA_FIXED (1 << 7) +/* For stack, where mmap returns end address */ +#define VMA_GROWSDOWN (1 << 8) + /* Set when the page is dirty in cache but not written to disk */ -#define VM_DIRTY (1 << 8) +#define VM_DIRTY (1 << 9) /* Defines the type of file. A device file? Regular file? One used at boot? */ enum VM_FILE_TYPE { diff --git a/tasks/mm0/main.c b/tasks/mm0/main.c index cb24083..5f8b865 100644 --- a/tasks/mm0/main.c +++ b/tasks/mm0/main.c @@ -20,6 +20,7 @@ #include #include #include +#include void handle_requests(void) { @@ -153,6 +154,7 @@ int self_spawn(void) { struct task_ids ids; struct tcb *self, *self_child; + // void *stack; BUG_ON(!(self = find_task(self_tid()))); @@ -164,9 +166,6 @@ int self_spawn(void) self_child = task_create(self, &ids, THREAD_CREATE_SAMESPC, TCB_SHARED_VM | TCB_SHARED_FILES); - /* Copy self tcb to child. TODO: ??? Not sure about this */ - copy_tcb(self_child, self, TCB_SHARED_VM | TCB_SHARED_FILES); - /* * Create a new utcb. Every pager thread will * need its own utcb to answer calls. @@ -180,6 +179,9 @@ int self_spawn(void) * TODO: Set up a child stack by mmapping an anonymous * region of mmap's choice. TODO: Time to add MAP_GROWSDOWN ??? */ + if (do_mmap(0, 0, self, 0, + VM_READ | VM_WRITE | VMA_ANONYMOUS | VMA_PRIVATE, 1) < 0) + BUG(); /* TODO: Notify vfs ??? */ diff --git a/tasks/mm0/src/mmap.c b/tasks/mm0/src/mmap.c index 0a40f57..b335d63 100644 --- a/tasks/mm0/src/mmap.c +++ b/tasks/mm0/src/mmap.c @@ -11,7 +11,7 @@ #include #include #include - +#include #if 0 /* TODO: This is to be implemented when fs0 is ready. */ @@ -568,7 +568,14 @@ int do_mmap(struct vm_file *mapfile, unsigned long file_offset, map_address, map_address + npages * PAGE_SIZE); task_add_vma(task, new); - return 0; + /* + * If area is going to be used going downwards, (i.e. as a stack) + * we return the *end* of the area as the start address. + */ + if (flags & VMA_GROWSDOWN) + map_address += npages; + + return map_address; } /* mmap system call implementation */ @@ -580,7 +587,6 @@ int sys_mmap(l4id_t sender, void *start, size_t length, int prot, struct vm_file *file = 0; unsigned int vmflags = 0; struct tcb *task; - int err; BUG_ON(!(task = find_task(sender))); @@ -619,6 +625,9 @@ int sys_mmap(l4id_t sender, void *start, size_t length, int prot, else /* This also means COW, if writeable and anonymous */ vmflags |= VMA_SHARED; + if (flags & MAP_GROWSDOWN) + vmflags |= VMA_GROWSDOWN; + if (prot & PROT_READ) vmflags |= VM_READ; if (prot & PROT_WRITE) @@ -626,10 +635,9 @@ int sys_mmap(l4id_t sender, void *start, size_t length, int prot, if (prot & PROT_EXEC) vmflags |= VM_EXEC; - if ((err = do_mmap(file, __pfn_to_addr(pfn), task, - base, vmflags, npages)) < 0) - return err; + base = do_mmap(file, __pfn_to_addr(pfn), task, base, vmflags, npages); + l4_ipc_return(base); return 0; }