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; off_t offset;
}; };
int sys_mmap(l4id_t sender, void *start, size_t length, int prot, void *sys_mmap(l4id_t sender, void *start, size_t length, int prot,
int flags, int fd, off_t offset); int flags, int fd, off_t offset);
int sys_munmap(l4id_t sender, void *vaddr, unsigned long size); 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 */ /* 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 */ /* Prefault an *mmaped* utcb */
int utcb_prefault(struct tcb *task, unsigned int vmflags); int utcb_prefault(struct tcb *task, unsigned int vmflags);

View File

@@ -28,12 +28,12 @@ void handle_requests(void)
u32 mr[MR_UNUSED_TOTAL]; u32 mr[MR_UNUSED_TOTAL];
l4id_t sender; l4id_t sender;
u32 tag; u32 tag;
int err; int ret;
// printf("%s: Initiating ipc.\n", __TASKNAME__); // 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__, printf("%s: %s: IPC Error: %d. Quitting...\n", __TASKNAME__,
__FUNCTION__, err); __FUNCTION__, ret);
BUG(); BUG();
} }
@@ -47,85 +47,82 @@ void handle_requests(void)
switch(tag) { switch(tag) {
case L4_IPC_TAG_WAIT: 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__); // printf("%s: Synced with waiting thread.\n", __TASKNAME__);
break; /* This has no receive phase */
return;
case L4_IPC_TAG_PFAULT: case L4_IPC_TAG_PFAULT:
/* Handle page fault. */ /* Handle page fault. */
page_fault_handler(sender, (fault_kdata_t *)&mr[0]); ret = page_fault_handler(sender, (fault_kdata_t *)&mr[0]);
break; break;
case L4_IPC_TAG_TASKDATA: case L4_IPC_TAG_TASKDATA:
/* Send runnable task information to fs0 */ /* Send runnable task information to fs0 */
send_task_data(sender); ret = send_task_data(sender);
break; break;
case L4_IPC_TAG_SHMGET: { case L4_IPC_TAG_SHMGET: {
struct sys_shmget_args *args = (struct sys_shmget_args *)&mr[0]; 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; break;
} }
case L4_IPC_TAG_SHMAT: { case L4_IPC_TAG_SHMAT: {
struct sys_shmat_args *args = (struct sys_shmat_args *)&mr[0]; 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; break;
} }
case L4_IPC_TAG_SHMDT: case L4_IPC_TAG_SHMDT:
sys_shmdt(sender, (void *)mr[0]); ret = sys_shmdt(sender, (void *)mr[0]);
break; break;
case L4_IPC_TAG_UTCB: 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; break;
case L4_IPC_TAG_READ: 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; break;
case L4_IPC_TAG_WRITE: 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; break;
case L4_IPC_TAG_CLOSE: case L4_IPC_TAG_CLOSE:
sys_close(sender, (int)mr[0]); ret = sys_close(sender, (int)mr[0]);
break; break;
case L4_IPC_TAG_FSYNC: case L4_IPC_TAG_FSYNC:
sys_fsync(sender, (int)mr[0]); ret = sys_fsync(sender, (int)mr[0]);
break; break;
case L4_IPC_TAG_LSEEK: 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; break;
case L4_IPC_TAG_MMAP2: { case L4_IPC_TAG_MMAP2: {
struct sys_mmap_args *args = (struct sys_mmap_args *)mr[0]; 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); args->flags, args->fd, args->offset);
} }
case L4_IPC_TAG_MMAP: { case L4_IPC_TAG_MMAP: {
struct sys_mmap_args *args = (struct sys_mmap_args *)&mr[0]; 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)); args->flags, args->fd, __pfn(args->offset));
break; break;
} }
case L4_IPC_TAG_FORK: { case L4_IPC_TAG_FORK: {
sys_fork(sender); ret = sys_fork(sender);
break; break;
} }
case L4_IPC_TAG_BRK: { case L4_IPC_TAG_BRK: {
// sys_brk(sender, (void *)mr[0]); // ret = sys_brk(sender, (void *)mr[0]);
// break; // break;
} }
case L4_IPC_TAG_MUNMAP: { 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; break;
} }
case L4_IPC_TAG_MSYNC: { 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(1), read_mr(2), read_mr(3), read_mr(4),
read_mr(5)); read_mr(5));
} }
/* Reply */
if ((ret = l4_ipc_return(ret)) < 0) {
printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, ret);
BUG();
}
} }
#if 0 #if 0

View File

@@ -10,6 +10,7 @@
#include <l4lib/arch/syslib.h> #include <l4lib/arch/syslib.h>
#include <l4lib/ipcdefs.h> #include <l4lib/ipcdefs.h>
#include <l4lib/exregs.h> #include <l4lib/exregs.h>
#include <l4/api/errno.h>
#include <l4/api/thread.h> #include <l4/api/thread.h>
#include <utcb.h> #include <utcb.h>
#include <shm.h> #include <shm.h>
@@ -68,10 +69,8 @@ int do_fork(struct tcb *parent)
* kernel stack and kernel-side tcb copied * kernel stack and kernel-side tcb copied
*/ */
if (IS_ERR(child = task_create(parent, &ids, THREAD_COPY_SPACE, if (IS_ERR(child = task_create(parent, &ids, THREAD_COPY_SPACE,
TCB_NO_SHARING))) { TCB_NO_SHARING)))
l4_ipc_return((int)child); return (int)child;
return 0;
}
/* Set child's fork return value to 0 */ /* Set child's fork return value to 0 */
memset(&exregs, 0, sizeof(exregs)); memset(&exregs, 0, sizeof(exregs));
@@ -87,10 +86,9 @@ int do_fork(struct tcb *parent)
* available for child to shmat() * available for child to shmat()
*/ */
if (IS_ERR(utcb_shm = shm_new((key_t)child->utcb, if (IS_ERR(utcb_shm = shm_new((key_t)child->utcb,
__pfn(DEFAULT_UTCB_SIZE)))) { __pfn(DEFAULT_UTCB_SIZE))))
l4_ipc_return((int)utcb_shm); return (int)utcb_shm;
return 0;
}
/* FIXME: Should we munmap() parent's utcb page from child? */ /* 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 */ /* Add child to global task list */
task_add_global(child); task_add_global(child);
printf("%s/%s: Starting forked child.\n", __TASKNAME__, __FUNCTION__);
/* Start forked child. */ /* Start forked child. */
printf("%s/%s: Starting forked child.\n", __TASKNAME__, __FUNCTION__);
l4_thread_control(THREAD_RUN, &ids); l4_thread_control(THREAD_RUN, &ids);
/* Return back to parent */ /* Return child tid to parent */
l4_ipc_return(child->tid); return child->tid;
return 0;
} }
int sys_fork(l4id_t sender) int sys_fork(l4id_t sender)
{ {
struct tcb *parent; struct tcb *parent;
BUG_ON(!(parent = find_task(sender))); if (!(parent = find_task(sender)))
return -ESRCH;
return do_fork(parent); return do_fork(parent);
} }
int sys_clone(l4id_t sender, void *child_stack, unsigned int flags) int sys_clone(l4id_t sender, void *child_stack, unsigned int flags)
{ {
struct task_ids ids; struct task_ids ids;
@@ -138,10 +134,8 @@ int sys_clone(l4id_t sender, void *child_stack, unsigned int flags)
ids.tgid = parent->tgid; ids.tgid = parent->tgid;
if (IS_ERR(child = task_create(parent, &ids, THREAD_SAME_SPACE, if (IS_ERR(child = task_create(parent, &ids, THREAD_SAME_SPACE,
TCB_SHARED_VM | TCB_SHARED_FILES))) { TCB_SHARED_VM | TCB_SHARED_FILES)))
l4_ipc_return((int)child); return (int)child;
return 0;
}
/* Allocate a unique utcb address for child */ /* Allocate a unique utcb address for child */
child->utcb = utcb_vaddr_new(); 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() * available for child to shmat()
*/ */
if (IS_ERR(utcb_shm = shm_new((key_t)child->utcb, if (IS_ERR(utcb_shm = shm_new((key_t)child->utcb,
__pfn(DEFAULT_UTCB_SIZE)))) { __pfn(DEFAULT_UTCB_SIZE))))
l4_ipc_return((int)utcb_shm); return (int)utcb_shm;
return 0;
}
/* Map and prefault child's utcb to vfs task */ /* Map and prefault child's utcb to vfs task */
task_map_prefault_utcb(find_task(VFS_TID), child); 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 */ /* Add child to global task list */
task_add_global(child); task_add_global(child);
printf("%s/%s: Starting forked child.\n", __TASKNAME__, __FUNCTION__);
/* Start forked child. */ /* Start forked child. */
printf("%s/%s: Starting forked child.\n", __TASKNAME__, __FUNCTION__);
l4_thread_control(THREAD_RUN, &ids); l4_thread_control(THREAD_RUN, &ids);
/* Return back to parent */ /* Return child tid to parent */
l4_ipc_return(child->tid); return child->tid;
return 0;
} }

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??? * FIXME: We could kill the thread if there was an error???
* Perhaps via a kill message to kernel? * Perhaps via a kill message to kernel?
*/ */
l4_ipc_return(err); return err;
return 0;
} }
/* Checks if an address range is a validly mapped area for a task */ /* 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 sys_close(l4id_t sender, int fd)
{ {
int retval; int ret;
struct tcb *task; struct tcb *task;
if (!(task = find_task(sender))) { if (!(task = find_task(sender)))
l4_ipc_return(-ESRCH); return -ESRCH;
return 0;
}
/* Sync the file and update stats */ /* Sync the file and update stats */
if ((retval = fsync_common(task, fd)) < 0) { if ((ret = fsync_common(task, fd)) < 0)
l4_ipc_return(retval); return ret;
return 0;
}
/* Close the file descriptor. */ /* Close the file descriptor. */
retval = do_close(task, fd); return do_close(task, fd);
printf("%s: Closed fd %d. Returning %d\n",
__TASKNAME__, fd, retval);
l4_ipc_return(retval);
return 0;
} }
int sys_fsync(l4id_t sender, int fd) int sys_fsync(l4id_t sender, int fd)
{ {
struct tcb *task; struct tcb *task;
int ret;
if (!(task = find_task(sender))) { if (!(task = find_task(sender)))
ret = -ESRCH; return -ESRCH;
goto out;
}
/* Sync the file and update stats */ /* Sync the file and update stats */
ret = fsync_common(task, fd); return fsync_common(task, fd);
out:
l4_ipc_return(ret);
return 0;
} }
/* FIXME: Add error handling to this */ /* 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; struct tcb *task;
int ret = 0; int ret = 0;
if (!(task = find_task(sender))) { if (!(task = find_task(sender)))
ret = -ESRCH; return -ESRCH;
goto out;
}
/* Check fd validity */ /* Check fd validity */
if (!task->files->fd[fd].vmfile) if (!task->files->fd[fd].vmfile)
if ((ret = file_open(task, fd)) < 0) if ((ret = file_open(task, fd)) < 0)
goto out; return ret;
/* Check count validity */ /* Check count validity */
if (count < 0) { if (count < 0)
ret = -EINVAL; return -EINVAL;
goto out; else if (!count)
} else if (!count) { return 0;
ret = 0;
goto out;
}
/* Check user buffer validity. */ /* Check user buffer validity. */
if ((ret = validate_task_range(task, (unsigned long)buf, if ((ret = validate_task_range(task, (unsigned long)buf,
(unsigned long)(buf + count), (unsigned long)(buf + count),
VM_READ)) < 0) VM_READ)) < 0)
goto out; return ret;
vmfile = task->files->fd[fd].vmfile; vmfile = task->files->fd[fd].vmfile;
cursor = task->files->fd[fd].cursor; cursor = task->files->fd[fd].cursor;
/* If cursor is beyond file end, simply return 0 */ /* If cursor is beyond file end, simply return 0 */
if (cursor >= vmfile->length) { if (cursor >= vmfile->length)
ret = 0; return 0;
goto out;
}
/* Start and end pages expected to be read by user */ /* Start and end pages expected to be read by user */
pfn_start = __pfn(cursor); 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 */ /* Read the page range into the cache from file */
if ((ret = read_file_pages(vmfile, pfn_start, pfn_end)) < 0) if ((ret = read_file_pages(vmfile, pfn_start, pfn_end)) < 0)
goto out; return ret;
/* The offset of cursor on first page */ /* The offset of cursor on first page */
byte_offset = PAGE_MASK & cursor; byte_offset = PAGE_MASK & cursor;
/* Read it into the user buffer from the cache */ /* Read it into the user buffer from the cache */
if ((count = read_cache_pages(vmfile, task, buf, pfn_start, pfn_end, if ((count = read_cache_pages(vmfile, task, buf, pfn_start, pfn_end,
byte_offset, count)) < 0) { byte_offset, count)) < 0)
ret = count; return count;
goto out;
}
/* Update cursor on success */ /* Update cursor on success */
task->files->fd[fd].cursor += count; task->files->fd[fd].cursor += count;
ret = count;
out: return count;
l4_ipc_return(ret);
return 0;
} }
/* FIXME: /* FIXME:
@@ -696,30 +668,26 @@ int sys_write(l4id_t sender, int fd, void *buf, int count)
struct tcb *task; struct tcb *task;
int ret = 0; int ret = 0;
if (!(task = find_task(sender))) { if (!(task = find_task(sender)))
ret = -ESRCH; return -ESRCH;
goto out;
}
/* Check fd validity */ /* Check fd validity */
if (!task->files->fd[fd].vmfile) if (!task->files->fd[fd].vmfile)
if ((ret = file_open(task, fd)) < 0) if ((ret = file_open(task, fd)) < 0)
goto out; return ret;
/* Check count validity */ /* Check count validity */
if (count < 0) { if (count < 0)
ret = -EINVAL; return -EINVAL;
goto out; else if (!count)
} else if (!count) { return 0;
ret = 0;
goto out;
}
/* Check user buffer validity. */ /* Check user buffer validity. */
if ((ret = validate_task_range(task, (unsigned long)buf, if ((ret = validate_task_range(task, (unsigned long)buf,
(unsigned long)(buf + count), (unsigned long)(buf + count),
VM_WRITE | VM_READ)) < 0) VM_WRITE | VM_READ)) < 0)
goto out; return ret;
vmfile = task->files->fd[fd].vmfile; vmfile = task->files->fd[fd].vmfile;
cursor = task->files->fd[fd].cursor; 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. * Read in the portion that's already part of the file.
*/ */
if ((ret = read_file_pages(vmfile, pfn_fstart, pfn_fend)) < 0) 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 */ /* Create new pages for the part that's new in the file */
if ((ret = new_file_pages(vmfile, pfn_nstart, pfn_nend)) < 0) 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 * 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; byte_offset = PAGE_MASK & cursor;
if ((ret = write_cache_pages(vmfile, task, buf, pfn_wstart, if ((ret = write_cache_pages(vmfile, task, buf, pfn_wstart,
pfn_wend, byte_offset, count)) < 0) pfn_wend, byte_offset, count)) < 0)
goto out; return ret;
/* /*
* Update the file size, and cursor. vfs will be notified * 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; vmfile->length = task->files->fd[fd].cursor + count;
task->files->fd[fd].cursor += count; task->files->fd[fd].cursor += count;
ret = count;
out: return count;
l4_ipc_return(ret);
return 0;
} }
/* FIXME: Check for invalid cursor values. Check for total, sometimes negative. */ /* 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; int retval = 0;
unsigned long long total, cursor; unsigned long long total, cursor;
if (!(task = find_task(sender))) { if (!(task = find_task(sender)))
retval = -ESRCH; return -ESRCH;
goto out;
}
/* Check fd validity */ /* Check fd validity */
if (!task->files->fd[fd].vmfile) if (!task->files->fd[fd].vmfile)
if ((retval = file_open(task, fd)) < 0) if ((retval = file_open(task, fd)) < 0)
goto out; return retval;
/* Offset validity */ /* Offset validity */
if (offset < 0) { if (offset < 0)
retval = -EINVAL; return -EINVAL;
goto out;
}
switch (whence) { switch (whence) {
case SEEK_SET: case SEEK_SET:
@@ -848,8 +809,6 @@ int sys_lseek(l4id_t sender, int fd, off_t offset, int whence)
break; break;
} }
out: return retval;
l4_ipc_return(retval);
return 0;
} }

View File

@@ -582,8 +582,8 @@ void *do_mmap(struct vm_file *mapfile, unsigned long file_offset,
} }
/* mmap system call implementation */ /* mmap system call implementation */
int sys_mmap(l4id_t sender, void *start, size_t length, int prot, void *sys_mmap(l4id_t sender, void *start, size_t length, int prot,
int flags, int fd, unsigned long pfn) int flags, int fd, unsigned long pfn)
{ {
unsigned long npages = __pfn(page_align_up(length)); unsigned long npages = __pfn(page_align_up(length));
unsigned long base = (unsigned long)start; 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; int err;
if (!(task = find_task(sender))) if (!(task = find_task(sender)))
return -ESRCH; return PTR_ERR(-ESRCH);
/* Check fd validity */ /* Check fd validity */
if (!(flags & MAP_ANONYMOUS)) if (!(flags & MAP_ANONYMOUS))
if (!task->files->fd[fd].vmfile) if (!task->files->fd[fd].vmfile)
if ((err = file_open(task, fd)) < 0) if ((err = file_open(task, fd)) < 0)
return err; return PTR_ERR(err);
if (base < task->start || base >= task->end) 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 */ /* 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 (base < task->map_start || base >= task->map_end || !base) {
if (flags & MAP_FIXED) /* Its fixed, we cannot satisfy it */ if (flags & MAP_FIXED) /* Its fixed, we cannot satisfy it */
return -EINVAL; return PTR_ERR(-EINVAL);
else else
start = 0; start = 0;
} }
@@ -643,10 +643,7 @@ int sys_mmap(l4id_t sender, void *start, size_t length, int prot,
if (prot & PROT_EXEC) if (prot & PROT_EXEC)
vmflags |= VM_EXEC; vmflags |= VM_EXEC;
start = do_mmap(file, __pfn_to_addr(pfn), task, base, vmflags, npages); return do_mmap(file, __pfn_to_addr(pfn), task, base, vmflags, npages);
l4_ipc_return((int)start);
return 0;
} }
/* Sets the end of data segment for sender */ /* 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; 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 vm_file *shm_file, *n;
struct tcb *task = find_task(requester); struct tcb *task = find_task(requester);
list_for_each_entry_safe(shm_file, n, &shm_file_list, list) { list_for_each_entry_safe(shm_file, n, &shm_file_list, list) {
if (shm_file_to_desc(shm_file)->shmid == shmid) { if (shm_file_to_desc(shm_file)->shmid == shmid)
shmaddr = do_shmat(shm_file, shmaddr, return do_shmat(shm_file, shmaddr,
shmflg, task); 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;
}
} }
l4_ipc_return(-EINVAL); return PTR_ERR(-EINVAL);
return 0;
} }
int do_shmdt(struct vm_file *shm, l4id_t tid) 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) { list_for_each_entry_safe(shm_file, n, &shm_file_list, list) {
if (shm_file_to_desc(shm_file)->shm_addr == shmaddr) { if (shm_file_to_desc(shm_file)->shm_addr == shmaddr) {
if ((err = do_shmdt(shm_file, requester) < 0)) { if ((err = do_shmdt(shm_file, requester) < 0))
l4_ipc_return(err); return err;
return 0; else
} else
break; break;
} }
} }
l4_ipc_return(-EINVAL); return -EINVAL;
return 0;
} }
@@ -248,10 +242,8 @@ int sys_shmget(key_t key, int size, int shmflg)
struct vm_file *shm; struct vm_file *shm;
/* First check argument validity */ /* First check argument validity */
if (npages > SHM_SHMMAX || npages < SHM_SHMMIN) { if (npages > SHM_SHMMAX || npages < SHM_SHMMIN)
l4_ipc_return(-EINVAL); return -EINVAL;
return 0;
}
/* /*
* IPC_PRIVATE means create a no-key shm area, i.e. private to this * 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) { if (key == IPC_PRIVATE) {
key = -1; /* Our meaning of no key */ key = -1; /* Our meaning of no key */
if (!(shm = shm_new(key, npages))) if (!(shm = shm_new(key, npages)))
l4_ipc_return(-ENOSPC); return -ENOSPC;
else else
l4_ipc_return(shm_file_to_desc(shm)->shmid); return shm_file_to_desc(shm)->shmid;
return 0;
} }
list_for_each_entry(shm, &shm_file_list, list) { 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. * on an existing key should fail.
*/ */
if ((shmflg & IPC_CREAT) && (shmflg & IPC_EXCL)) if ((shmflg & IPC_CREAT) && (shmflg & IPC_EXCL))
l4_ipc_return(-EEXIST); return -EEXIST;
else else
/* Found it but do we have a size problem? */ /* Found it but do we have a size problem? */
if (shm_desc->npages < npages) if (shm_desc->npages < npages)
l4_ipc_return(-EINVAL); return -EINVAL;
else /* Return shmid of the existing key */ else /* Return shmid of the existing key */
l4_ipc_return(shm_desc->shmid); return shm_desc->shmid;
return 0;
} }
} }
/* Key doesn't exist and create is set, so we create */ /* Key doesn't exist and create is set, so we create */
if (shmflg & IPC_CREAT) if (shmflg & IPC_CREAT)
if (!(shm = shm_new(key, npages))) if (!(shm = shm_new(key, npages)))
l4_ipc_return(-ENOSPC); return -ENOSPC;
else 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 */ else /* Key doesn't exist, yet create isn't set, its an -ENOENT */
l4_ipc_return(-ENOENT); return -ENOENT;
return 0;
} }

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 send_task_data(l4id_t requester)
{ {
int li = 0, err; int li = 0;
struct tcb *t, *vfs, *self; struct tcb *t, *vfs, *self;
struct task_data_head *tdata_head; struct task_data_head *tdata_head;
@@ -474,12 +474,6 @@ int send_task_data(l4id_t requester)
li++; li++;
} }
/* Reply */
if ((err = l4_ipc_return(0)) < 0) {
printf("%s: L4 IPC Error: %d.\n", __FUNCTION__, err);
BUG();
}
return 0; 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 * for its own. The requester then uses this address as a shm key and
* maps its own utcb via shmget/shmat. * 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); 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); BUG_ON(!task->utcb);
/* Return it to requester */ /* Return it to requester */
return l4_ipc_return((int)task->utcb); return task->utcb;
/* A task is asking for someone else's utcb */ /* A task is asking for someone else's utcb */
} else { } 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 * none allocated so far, requester gets 0. We don't
* allocate one here. * allocate one here.
*/ */
return l4_ipc_return((int)task->utcb); return task->utcb;
} }
} }
return 0; return 0;