diff --git a/tasks/mm0/src/fault.c b/tasks/mm0/src/fault.c index c37b5c5..9949e8c 100644 --- a/tasks/mm0/src/fault.c +++ b/tasks/mm0/src/fault.c @@ -697,6 +697,8 @@ int __do_page_fault(struct fault_data *fault) */ } else if ((vma_flags & VMA_SHARED)) { file_offset = fault_to_file_offset(fault); + + /* Don't traverse, just take the first object */ BUG_ON(!(vmo_link = vma_next_link(&vma->vm_obj_list, &vma->vm_obj_list))); diff --git a/tasks/mm0/src/mmap.c b/tasks/mm0/src/mmap.c index 478c512..610749b 100644 --- a/tasks/mm0/src/mmap.c +++ b/tasks/mm0/src/mmap.c @@ -17,6 +17,7 @@ #include #include #include +#include struct vm_area *vma_new(unsigned long pfn_start, unsigned long npages, unsigned int flags, unsigned long file_offset) @@ -370,6 +371,27 @@ void *__sys_mmap(struct tcb *task, void *start, size_t length, int prot, if (prot & PROT_EXEC) vmflags |= VM_EXEC; + /* + * Currently MAP_SHARED && MAP_ANONYMOUS mappings use the + * shm interface to create virtual shared memory files and + * do_mmap is internally called through this interface. + * + * FIXME: A common method of creating virtual shm files + * should be used by both sys_mmap and sys_shmget. With the + * current method, a task that guesses the shmid of an + * anonymous shared mmap can attach to it via shmat. + */ + if ((flags & MAP_ANONYMOUS) && + (flags & MAP_SHARED)) { + /* Create a new shared memory virtual file */ + l4id_t shmid = sys_shmget(IPC_PRIVATE, + page_align_up(length), + 0); + + /* Find and mmap the file via do_shmat() */ + return sys_shmat(task, shmid, 0, 0); + } + return do_mmap(file, file_offset, task, (unsigned long)start, vmflags, __pfn(page_align_up(length))); }