diff --git a/tasks/mm0/include/syscalls.h b/tasks/mm0/include/syscalls.h index e68423b..d2d0daf 100644 --- a/tasks/mm0/include/syscalls.h +++ b/tasks/mm0/include/syscalls.h @@ -22,8 +22,8 @@ struct sys_mmap_args { off_t offset; }; -int sys_mmap(l4id_t sender, void *start, size_t length, int prot, - int flags, int fd, off_t offset); +void *sys_mmap(l4id_t sender, void *start, size_t length, int prot, + int flags, int fd, off_t offset); int sys_munmap(l4id_t sender, void *vaddr, unsigned long size); diff --git a/tasks/mm0/include/utcb.h b/tasks/mm0/include/utcb.h index c50e8a4..d003fed 100644 --- a/tasks/mm0/include/utcb.h +++ b/tasks/mm0/include/utcb.h @@ -8,7 +8,7 @@ int utcb_pool_init(void); /* IPC to send utcb address information to tasks */ -int task_send_utcb_address(l4id_t sender, l4id_t taskid); +void *task_send_utcb_address(l4id_t sender, l4id_t taskid); /* Prefault an *mmaped* utcb */ int utcb_prefault(struct tcb *task, unsigned int vmflags); diff --git a/tasks/mm0/main.c b/tasks/mm0/main.c index e3d03e4..1bdce11 100644 --- a/tasks/mm0/main.c +++ b/tasks/mm0/main.c @@ -28,12 +28,12 @@ void handle_requests(void) u32 mr[MR_UNUSED_TOTAL]; l4id_t sender; u32 tag; - int err; + int ret; // printf("%s: Initiating ipc.\n", __TASKNAME__); - if ((err = l4_receive(L4_ANYTHREAD)) < 0) { + if ((ret = l4_receive(L4_ANYTHREAD)) < 0) { printf("%s: %s: IPC Error: %d. Quitting...\n", __TASKNAME__, - __FUNCTION__, err); + __FUNCTION__, ret); BUG(); } @@ -47,85 +47,82 @@ void handle_requests(void) switch(tag) { case L4_IPC_TAG_WAIT: - /* - * A thread that wants to sync with us would have - * started here. - */ // printf("%s: Synced with waiting thread.\n", __TASKNAME__); - break; + /* This has no receive phase */ + return; case L4_IPC_TAG_PFAULT: /* Handle page fault. */ - page_fault_handler(sender, (fault_kdata_t *)&mr[0]); + ret = page_fault_handler(sender, (fault_kdata_t *)&mr[0]); break; case L4_IPC_TAG_TASKDATA: /* Send runnable task information to fs0 */ - send_task_data(sender); + ret = send_task_data(sender); break; case L4_IPC_TAG_SHMGET: { struct sys_shmget_args *args = (struct sys_shmget_args *)&mr[0]; - sys_shmget(args->key, args->size, args->shmflg); + ret = sys_shmget(args->key, args->size, args->shmflg); break; } case L4_IPC_TAG_SHMAT: { struct sys_shmat_args *args = (struct sys_shmat_args *)&mr[0]; - sys_shmat(sender, args->shmid, args->shmaddr, args->shmflg); + ret = (int)sys_shmat(sender, args->shmid, args->shmaddr, args->shmflg); break; } case L4_IPC_TAG_SHMDT: - sys_shmdt(sender, (void *)mr[0]); + ret = sys_shmdt(sender, (void *)mr[0]); break; case L4_IPC_TAG_UTCB: - task_send_utcb_address(sender, (l4id_t)mr[0]); + ret = (int)task_send_utcb_address(sender, (l4id_t)mr[0]); break; case L4_IPC_TAG_READ: - sys_read(sender, (int)mr[0], (void *)mr[1], (int)mr[2]); + ret = sys_read(sender, (int)mr[0], (void *)mr[1], (int)mr[2]); break; case L4_IPC_TAG_WRITE: - sys_write(sender, (int)mr[0], (void *)mr[1], (int)mr[2]); + ret = sys_write(sender, (int)mr[0], (void *)mr[1], (int)mr[2]); break; case L4_IPC_TAG_CLOSE: - sys_close(sender, (int)mr[0]); + ret = sys_close(sender, (int)mr[0]); break; case L4_IPC_TAG_FSYNC: - sys_fsync(sender, (int)mr[0]); + ret = sys_fsync(sender, (int)mr[0]); break; case L4_IPC_TAG_LSEEK: - sys_lseek(sender, (int)mr[0], (off_t)mr[1], (int)mr[2]); + ret = sys_lseek(sender, (int)mr[0], (off_t)mr[1], (int)mr[2]); break; case L4_IPC_TAG_MMAP2: { struct sys_mmap_args *args = (struct sys_mmap_args *)mr[0]; - sys_mmap(sender, args->start, args->length, args->prot, + ret = (int)sys_mmap(sender, args->start, args->length, args->prot, args->flags, args->fd, args->offset); } case L4_IPC_TAG_MMAP: { struct sys_mmap_args *args = (struct sys_mmap_args *)&mr[0]; - sys_mmap(sender, args->start, args->length, args->prot, + ret = (int)sys_mmap(sender, args->start, args->length, args->prot, args->flags, args->fd, __pfn(args->offset)); break; } case L4_IPC_TAG_FORK: { - sys_fork(sender); + ret = sys_fork(sender); break; } case L4_IPC_TAG_BRK: { -// sys_brk(sender, (void *)mr[0]); +// ret = sys_brk(sender, (void *)mr[0]); // break; } case L4_IPC_TAG_MUNMAP: { - sys_munmap(sender, (void *)mr[0], (unsigned long)mr[1]); + ret = sys_munmap(sender, (void *)mr[0], (unsigned long)mr[1]); break; } case L4_IPC_TAG_MSYNC: { @@ -141,6 +138,12 @@ void handle_requests(void) read_mr(1), read_mr(2), read_mr(3), read_mr(4), read_mr(5)); } + + /* Reply */ + if ((ret = l4_ipc_return(ret)) < 0) { + printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, ret); + BUG(); + } } #if 0 diff --git a/tasks/mm0/src/clone.c b/tasks/mm0/src/clone.c index eec2947..66cea56 100755 --- a/tasks/mm0/src/clone.c +++ b/tasks/mm0/src/clone.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -68,10 +69,8 @@ int do_fork(struct tcb *parent) * kernel stack and kernel-side tcb copied */ if (IS_ERR(child = task_create(parent, &ids, THREAD_COPY_SPACE, - TCB_NO_SHARING))) { - l4_ipc_return((int)child); - return 0; - } + TCB_NO_SHARING))) + return (int)child; /* Set child's fork return value to 0 */ memset(&exregs, 0, sizeof(exregs)); @@ -87,10 +86,9 @@ int do_fork(struct tcb *parent) * available for child to shmat() */ if (IS_ERR(utcb_shm = shm_new((key_t)child->utcb, - __pfn(DEFAULT_UTCB_SIZE)))) { - l4_ipc_return((int)utcb_shm); - return 0; - } + __pfn(DEFAULT_UTCB_SIZE)))) + return (int)utcb_shm; + /* FIXME: Should we munmap() parent's utcb page from child? */ /* @@ -105,26 +103,24 @@ int do_fork(struct tcb *parent) /* Add child to global task list */ task_add_global(child); - printf("%s/%s: Starting forked child.\n", __TASKNAME__, __FUNCTION__); /* Start forked child. */ + printf("%s/%s: Starting forked child.\n", __TASKNAME__, __FUNCTION__); l4_thread_control(THREAD_RUN, &ids); - /* Return back to parent */ - l4_ipc_return(child->tid); - - return 0; + /* Return child tid to parent */ + return child->tid; } int sys_fork(l4id_t sender) { struct tcb *parent; - BUG_ON(!(parent = find_task(sender))); + if (!(parent = find_task(sender))) + return -ESRCH; return do_fork(parent); } - int sys_clone(l4id_t sender, void *child_stack, unsigned int flags) { struct task_ids ids; @@ -138,10 +134,8 @@ int sys_clone(l4id_t sender, void *child_stack, unsigned int flags) ids.tgid = parent->tgid; if (IS_ERR(child = task_create(parent, &ids, THREAD_SAME_SPACE, - TCB_SHARED_VM | TCB_SHARED_FILES))) { - l4_ipc_return((int)child); - return 0; - } + TCB_SHARED_VM | TCB_SHARED_FILES))) + return (int)child; /* Allocate a unique utcb address for child */ child->utcb = utcb_vaddr_new(); @@ -151,10 +145,8 @@ int sys_clone(l4id_t sender, void *child_stack, unsigned int flags) * available for child to shmat() */ if (IS_ERR(utcb_shm = shm_new((key_t)child->utcb, - __pfn(DEFAULT_UTCB_SIZE)))) { - l4_ipc_return((int)utcb_shm); - return 0; - } + __pfn(DEFAULT_UTCB_SIZE)))) + return (int)utcb_shm; /* Map and prefault child's utcb to vfs task */ task_map_prefault_utcb(find_task(VFS_TID), child); @@ -169,14 +161,12 @@ int sys_clone(l4id_t sender, void *child_stack, unsigned int flags) /* Add child to global task list */ task_add_global(child); - printf("%s/%s: Starting forked child.\n", __TASKNAME__, __FUNCTION__); /* Start forked child. */ + printf("%s/%s: Starting forked child.\n", __TASKNAME__, __FUNCTION__); l4_thread_control(THREAD_RUN, &ids); - /* Return back to parent */ - l4_ipc_return(child->tid); - - return 0; + /* Return child tid to parent */ + return child->tid; } diff --git a/tasks/mm0/src/fault.c b/tasks/mm0/src/fault.c index 602fc57..49ce44b 100644 --- a/tasks/mm0/src/fault.c +++ b/tasks/mm0/src/fault.c @@ -711,8 +711,7 @@ int page_fault_handler(l4id_t sender, fault_kdata_t *fkdata) * FIXME: We could kill the thread if there was an error??? * Perhaps via a kill message to kernel? */ - l4_ipc_return(err); - return 0; + return err; } /* Checks if an address range is a validly mapped area for a task */ diff --git a/tasks/mm0/src/file.c b/tasks/mm0/src/file.c index 486a9d1..7126a89 100644 --- a/tasks/mm0/src/file.c +++ b/tasks/mm0/src/file.c @@ -405,45 +405,29 @@ int do_close(struct tcb *task, int fd) int sys_close(l4id_t sender, int fd) { - int retval; + int ret; struct tcb *task; - if (!(task = find_task(sender))) { - l4_ipc_return(-ESRCH); - return 0; - } + if (!(task = find_task(sender))) + return -ESRCH; /* Sync the file and update stats */ - if ((retval = fsync_common(task, fd)) < 0) { - l4_ipc_return(retval); - return 0; - } + if ((ret = fsync_common(task, fd)) < 0) + return ret; /* Close the file descriptor. */ - retval = do_close(task, fd); - printf("%s: Closed fd %d. Returning %d\n", - __TASKNAME__, fd, retval); - l4_ipc_return(retval); - - return 0; + return do_close(task, fd); } int sys_fsync(l4id_t sender, int fd) { struct tcb *task; - int ret; - if (!(task = find_task(sender))) { - ret = -ESRCH; - goto out; - } + if (!(task = find_task(sender))) + return -ESRCH; /* Sync the file and update stats */ - ret = fsync_common(task, fd); - -out: - l4_ipc_return(ret); - return 0; + return fsync_common(task, fd); } /* FIXME: Add error handling to this */ @@ -610,40 +594,33 @@ int sys_read(l4id_t sender, int fd, void *buf, int count) struct tcb *task; int ret = 0; - if (!(task = find_task(sender))) { - ret = -ESRCH; - goto out; - } + if (!(task = find_task(sender))) + return -ESRCH; /* Check fd validity */ if (!task->files->fd[fd].vmfile) if ((ret = file_open(task, fd)) < 0) - goto out; + return ret; /* Check count validity */ - if (count < 0) { - ret = -EINVAL; - goto out; - } else if (!count) { - ret = 0; - goto out; - } + if (count < 0) + return -EINVAL; + else if (!count) + return 0; /* Check user buffer validity. */ if ((ret = validate_task_range(task, (unsigned long)buf, (unsigned long)(buf + count), VM_READ)) < 0) - goto out; + return ret; vmfile = task->files->fd[fd].vmfile; cursor = task->files->fd[fd].cursor; /* If cursor is beyond file end, simply return 0 */ - if (cursor >= vmfile->length) { - ret = 0; - goto out; - } + if (cursor >= vmfile->length) + return 0; /* Start and end pages expected to be read by user */ pfn_start = __pfn(cursor); @@ -659,25 +636,20 @@ int sys_read(l4id_t sender, int fd, void *buf, int count) /* Read the page range into the cache from file */ if ((ret = read_file_pages(vmfile, pfn_start, pfn_end)) < 0) - goto out; + return ret; /* The offset of cursor on first page */ byte_offset = PAGE_MASK & cursor; /* Read it into the user buffer from the cache */ if ((count = read_cache_pages(vmfile, task, buf, pfn_start, pfn_end, - byte_offset, count)) < 0) { - ret = count; - goto out; - } + byte_offset, count)) < 0) + return count; /* Update cursor on success */ task->files->fd[fd].cursor += count; - ret = count; -out: - l4_ipc_return(ret); - return 0; + return count; } /* FIXME: @@ -696,30 +668,26 @@ int sys_write(l4id_t sender, int fd, void *buf, int count) struct tcb *task; int ret = 0; - if (!(task = find_task(sender))) { - ret = -ESRCH; - goto out; - } + if (!(task = find_task(sender))) + return -ESRCH; /* Check fd validity */ if (!task->files->fd[fd].vmfile) if ((ret = file_open(task, fd)) < 0) - goto out; + return ret; /* Check count validity */ - if (count < 0) { - ret = -EINVAL; - goto out; - } else if (!count) { - ret = 0; - goto out; - } + if (count < 0) + return -EINVAL; + else if (!count) + return 0; + /* Check user buffer validity. */ if ((ret = validate_task_range(task, (unsigned long)buf, (unsigned long)(buf + count), VM_WRITE | VM_READ)) < 0) - goto out; + return ret; vmfile = task->files->fd[fd].vmfile; cursor = task->files->fd[fd].cursor; @@ -769,11 +737,11 @@ int sys_write(l4id_t sender, int fd, void *buf, int count) * Read in the portion that's already part of the file. */ if ((ret = read_file_pages(vmfile, pfn_fstart, pfn_fend)) < 0) - goto out; + return ret; /* Create new pages for the part that's new in the file */ if ((ret = new_file_pages(vmfile, pfn_nstart, pfn_nend)) < 0) - goto out; + return ret; /* * At this point be it new or existing file pages, all pages @@ -782,7 +750,7 @@ int sys_write(l4id_t sender, int fd, void *buf, int count) byte_offset = PAGE_MASK & cursor; if ((ret = write_cache_pages(vmfile, task, buf, pfn_wstart, pfn_wend, byte_offset, count)) < 0) - goto out; + return ret; /* * Update the file size, and cursor. vfs will be notified @@ -793,11 +761,8 @@ int sys_write(l4id_t sender, int fd, void *buf, int count) vmfile->length = task->files->fd[fd].cursor + count; task->files->fd[fd].cursor += count; - ret = count; -out: - l4_ipc_return(ret); - return 0; + return count; } /* FIXME: Check for invalid cursor values. Check for total, sometimes negative. */ @@ -807,21 +772,17 @@ int sys_lseek(l4id_t sender, int fd, off_t offset, int whence) int retval = 0; unsigned long long total, cursor; - if (!(task = find_task(sender))) { - retval = -ESRCH; - goto out; - } + if (!(task = find_task(sender))) + return -ESRCH; /* Check fd validity */ if (!task->files->fd[fd].vmfile) if ((retval = file_open(task, fd)) < 0) - goto out; + return retval; /* Offset validity */ - if (offset < 0) { - retval = -EINVAL; - goto out; - } + if (offset < 0) + return -EINVAL; switch (whence) { case SEEK_SET: @@ -848,8 +809,6 @@ int sys_lseek(l4id_t sender, int fd, off_t offset, int whence) break; } -out: - l4_ipc_return(retval); - return 0; + return retval; } diff --git a/tasks/mm0/src/mmap.c b/tasks/mm0/src/mmap.c index 0b33b9b..fa67175 100644 --- a/tasks/mm0/src/mmap.c +++ b/tasks/mm0/src/mmap.c @@ -582,8 +582,8 @@ void *do_mmap(struct vm_file *mapfile, unsigned long file_offset, } /* mmap system call implementation */ -int sys_mmap(l4id_t sender, void *start, size_t length, int prot, - int flags, int fd, unsigned long pfn) +void *sys_mmap(l4id_t sender, void *start, size_t length, int prot, + int flags, int fd, unsigned long pfn) { unsigned long npages = __pfn(page_align_up(length)); unsigned long base = (unsigned long)start; @@ -593,21 +593,21 @@ int sys_mmap(l4id_t sender, void *start, size_t length, int prot, int err; if (!(task = find_task(sender))) - return -ESRCH; + return PTR_ERR(-ESRCH); /* Check fd validity */ if (!(flags & MAP_ANONYMOUS)) if (!task->files->fd[fd].vmfile) if ((err = file_open(task, fd)) < 0) - return err; + return PTR_ERR(err); if (base < task->start || base >= task->end) - return -EINVAL; + return PTR_ERR(-EINVAL); /* Exclude task's stack, text and data from mmappable area in task's space */ if (base < task->map_start || base >= task->map_end || !base) { if (flags & MAP_FIXED) /* Its fixed, we cannot satisfy it */ - return -EINVAL; + return PTR_ERR(-EINVAL); else start = 0; } @@ -643,10 +643,7 @@ int sys_mmap(l4id_t sender, void *start, size_t length, int prot, if (prot & PROT_EXEC) vmflags |= VM_EXEC; - start = do_mmap(file, __pfn_to_addr(pfn), task, base, vmflags, npages); - - l4_ipc_return((int)start); - return 0; + return do_mmap(file, __pfn_to_addr(pfn), task, base, vmflags, npages); } /* Sets the end of data segment for sender */ diff --git a/tasks/mm0/src/shm.c b/tasks/mm0/src/shm.c index 5af4226..2d09be5 100644 --- a/tasks/mm0/src/shm.c +++ b/tasks/mm0/src/shm.c @@ -106,35 +106,31 @@ static void *do_shmat(struct vm_file *shm_file, void *shm_addr, int shmflg, return shm->shm_addr; } -int sys_shmat(l4id_t requester, l4id_t shmid, void *shmaddr, int shmflg) +/* TODO: Do we need this? + * MM0 never needs a task's utcb page. vfs needs it. + * UTCBs get special treatment here. If the task + * is attaching to its utcb, mm0 prefaults it so + * that it can access it later on whether or not + * the task makes a syscall to mm0 without first + * faulting the utcb. + */ +/* + if ((unsigned long)shmaddr == task->utcb_address) + utcb_prefault(task, VM_READ | VM_WRITE); +*/ + +void *sys_shmat(l4id_t requester, l4id_t shmid, void *shmaddr, int shmflg) { struct vm_file *shm_file, *n; struct tcb *task = find_task(requester); list_for_each_entry_safe(shm_file, n, &shm_file_list, list) { - if (shm_file_to_desc(shm_file)->shmid == shmid) { - shmaddr = do_shmat(shm_file, shmaddr, - shmflg, task); - - /* - * UTCBs get special treatment here. If the task - * is attaching to its utcb, mm0 prefaults it so - * that it can access it later on whether or not - * the task makes a syscall to mm0 without first - * faulting the utcb. - */ - /* - if ((unsigned long)shmaddr == task->utcb_address) - utcb_prefault(task, VM_READ | VM_WRITE); - */ - - l4_ipc_return((int)shmaddr); - return 0; - } + if (shm_file_to_desc(shm_file)->shmid == shmid) + return do_shmat(shm_file, shmaddr, + shmflg, task); } - l4_ipc_return(-EINVAL); - return 0; + return PTR_ERR(-EINVAL); } int do_shmdt(struct vm_file *shm, l4id_t tid) @@ -164,16 +160,14 @@ int sys_shmdt(l4id_t requester, const void *shmaddr) list_for_each_entry_safe(shm_file, n, &shm_file_list, list) { if (shm_file_to_desc(shm_file)->shm_addr == shmaddr) { - if ((err = do_shmdt(shm_file, requester) < 0)) { - l4_ipc_return(err); - return 0; - } else + if ((err = do_shmdt(shm_file, requester) < 0)) + return err; + else break; } } - l4_ipc_return(-EINVAL); - return 0; + return -EINVAL; } @@ -248,10 +242,8 @@ int sys_shmget(key_t key, int size, int shmflg) struct vm_file *shm; /* First check argument validity */ - if (npages > SHM_SHMMAX || npages < SHM_SHMMIN) { - l4_ipc_return(-EINVAL); - return 0; - } + if (npages > SHM_SHMMAX || npages < SHM_SHMMIN) + return -EINVAL; /* * IPC_PRIVATE means create a no-key shm area, i.e. private to this @@ -260,10 +252,9 @@ int sys_shmget(key_t key, int size, int shmflg) if (key == IPC_PRIVATE) { key = -1; /* Our meaning of no key */ if (!(shm = shm_new(key, npages))) - l4_ipc_return(-ENOSPC); + return -ENOSPC; else - l4_ipc_return(shm_file_to_desc(shm)->shmid); - return 0; + return shm_file_to_desc(shm)->shmid; } list_for_each_entry(shm, &shm_file_list, list) { @@ -275,26 +266,23 @@ int sys_shmget(key_t key, int size, int shmflg) * on an existing key should fail. */ if ((shmflg & IPC_CREAT) && (shmflg & IPC_EXCL)) - l4_ipc_return(-EEXIST); + return -EEXIST; else /* Found it but do we have a size problem? */ if (shm_desc->npages < npages) - l4_ipc_return(-EINVAL); + return -EINVAL; else /* Return shmid of the existing key */ - l4_ipc_return(shm_desc->shmid); - return 0; + return shm_desc->shmid; } } /* Key doesn't exist and create is set, so we create */ if (shmflg & IPC_CREAT) if (!(shm = shm_new(key, npages))) - l4_ipc_return(-ENOSPC); + return -ENOSPC; else - l4_ipc_return(shm_file_to_desc(shm)->shmid); + return shm_file_to_desc(shm)->shmid; else /* Key doesn't exist, yet create isn't set, its an -ENOENT */ - l4_ipc_return(-ENOENT); - - return 0; + return -ENOENT; } diff --git a/tasks/mm0/src/task.c b/tasks/mm0/src/task.c index 6e69aa2..12720fc 100644 --- a/tasks/mm0/src/task.c +++ b/tasks/mm0/src/task.c @@ -438,7 +438,7 @@ void task_map_prefault_utcb(struct tcb *mapper, struct tcb *owner) */ int send_task_data(l4id_t requester) { - int li = 0, err; + int li = 0; struct tcb *t, *vfs, *self; struct task_data_head *tdata_head; @@ -474,12 +474,6 @@ int send_task_data(l4id_t requester) li++; } - /* Reply */ - if ((err = l4_ipc_return(0)) < 0) { - printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, err); - BUG(); - } - return 0; } diff --git a/tasks/mm0/src/utcb.c b/tasks/mm0/src/utcb.c index df17d77..11c9f9d 100644 --- a/tasks/mm0/src/utcb.c +++ b/tasks/mm0/src/utcb.c @@ -39,7 +39,7 @@ void *utcb_vaddr_new(void) * for its own. The requester then uses this address as a shm key and * maps its own utcb via shmget/shmat. */ -int task_send_utcb_address(l4id_t sender, l4id_t taskid) +void *task_send_utcb_address(l4id_t sender, l4id_t taskid) { struct tcb *task = find_task(taskid); @@ -53,7 +53,7 @@ int task_send_utcb_address(l4id_t sender, l4id_t taskid) BUG_ON(!task->utcb); /* Return it to requester */ - return l4_ipc_return((int)task->utcb); + return task->utcb; /* A task is asking for someone else's utcb */ } else { @@ -64,7 +64,7 @@ int task_send_utcb_address(l4id_t sender, l4id_t taskid) * none allocated so far, requester gets 0. We don't * allocate one here. */ - return l4_ipc_return((int)task->utcb); + return task->utcb; } } return 0;