mirror of
https://github.com/drasko/codezero.git
synced 2026-07-29 02:20:06 +02:00
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:
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user