Cleanup: Moved all l4_ipc_return() calls to uppermost handler routine.

Now all system calls can simply return their final values and they
will be sent to client parties from a single location. Should have had this
simple cleanup a long time ago.
This commit is contained in:
Bahadir Balban
2008-09-16 18:56:18 +03:00
parent 270cead377
commit 2e94a78253
10 changed files with 134 additions and 204 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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

View File

@@ -10,6 +10,7 @@
#include <l4lib/arch/syslib.h>
#include <l4lib/ipcdefs.h>
#include <l4lib/exregs.h>
#include <l4/api/errno.h>
#include <l4/api/thread.h>
#include <utcb.h>
#include <shm.h>
@@ -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;
}

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;