Fixing syscalls to new seterrno and setretval.
authorDavid Zhu <yuzhu@cs.berkeley.edu>
Wed, 11 Aug 2010 23:17:12 +0000 (16:17 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:51 +0000 (17:35 -0700)
14 files changed:
kern/arch/i686/process.c
kern/arch/i686/ros/syscall.h
kern/arch/i686/trap.h
kern/arch/sparc/process.c
kern/arch/sparc/trap.h
kern/include/process.h
kern/include/syscall.h
kern/src/frontend.c
kern/src/kfs.c
kern/src/mm.c
kern/src/resource.c
kern/src/syscall.c
kern/src/umem.c
kern/src/vfs.c

index 70c6fea..86ae4d6 100644 (file)
@@ -49,14 +49,6 @@ void proc_secure_trapframe(struct trapframe *tf)
        tf->tf_eflags |= 0x00000200; // bit 9 is the interrupts-enabled
 }
 
-/* For cases that we won't return from a syscall via the normal path, and need
- * to set the syscall return value in the registers manually.  Like in a syscall
- * moving to RUNNING_M */
-void proc_set_syscall_retval(trapframe_t *SAFE tf, intreg_t value)
-{
-       tf->tf_regs.reg_eax = value;
-}
-
 /* Called when we are currently running an address space on our core and want to
  * abandon it.  We need a known good pgdir before releasing the old one.  We
  * decref, since current no longer tracks the proc (and current no longer
index 891df14..eb10265 100644 (file)
@@ -6,7 +6,6 @@
 #ifndef ROS_KERNEL
 
 #include <ros/arch/bits/syscall.h>
-#include <errno.h>
 
 static inline intreg_t syscall_sysenter(uint16_t num, intreg_t a1,
                                   intreg_t a2, intreg_t a3,
index 39ea036..6af0cac 100644 (file)
 
 #include <ros/common.h>
 #include <arch/mmu.h>
-#include <ros/arch/trapframe.h>
+#include <arch/ros/trapframe.h>
 
 /* The kernel's interrupt descriptor table */
 extern gatedesc_t idt[];
 extern taskstate_t ts;
 
-/* the struct trapframe and friends are in ros/arch/trapframe.h */
-
-static inline void set_errno(trapframe_t* tf, uint32_t errno)
-{
-       if (tf)
-               tf->tf_regs.reg_esi = errno;
-}
-
 /* Determines if the given TF was in the kernel or not. */
 static inline bool in_kernel(struct trapframe *tf)
 {
index 1a00388..65dc46d 100644 (file)
@@ -34,14 +34,6 @@ void proc_secure_trapframe(struct trapframe *tf)
        tf->psr = (tf->psr & PSR_ICC) | PSR_S;
 }
 
-/* For cases that we won't return from a syscall via the normal path, and need
- * to set the syscall return value in the registers manually.  Like in a syscall
- * moving to RUNNING_M */
-void proc_set_syscall_retval(trapframe_t *SAFE tf, intreg_t value)
-{
-       tf->gpr[8] = value;
-}
-
 /* Called when we are currently running an address space on our core and want to
  * abandon it.  We need a known good pgdir before releasing the old one.  We
  * decref, since current no longer tracks the proc (and current no longer
index f6cf003..03cf352 100644 (file)
@@ -21,12 +21,6 @@ void save_fp_state(ancillary_state_t* silly);
 void restore_fp_state(ancillary_state_t* silly);
 void emulate_fpu(trapframe_t* state, ancillary_state_t* astate);
 
-static inline void set_errno(trapframe_t* tf, uint32_t errno)
-{
-       if (tf)
-               tf->gpr[9] = errno;
-}
-
 static inline bool in_kernel(struct trapframe *tf)
 {
        return tf->psr & PSR_PS;
index 22b8e04..d125b1f 100644 (file)
@@ -160,7 +160,6 @@ void __tlbshootdown(struct trapframe *tf, uint32_t srcid, void *a0, void *a1,
 void proc_init_trapframe(trapframe_t *SAFE tf, uint32_t vcoreid,
                          uint32_t entryp, uint32_t stack_top);
 void proc_secure_trapframe(struct trapframe *tf);
-void proc_set_syscall_retval(trapframe_t *SAFE tf, intreg_t value);
 void __abandon_core(void);
 
 /* Degubbing */
index 6711456..cbab190 100644 (file)
@@ -41,4 +41,7 @@ int systrace_dereg(bool all, struct proc *p);
 void systrace_print(bool all, struct proc *p);
 void systrace_clear_buffer(void);
 
+/* direct returnval and errno handling */
+void set_errno(uint32_t errno);
+void set_retval(uint32_t retval);
 #endif /* !ROS_KERN_SYSCALL_H */
index 970f22d..fee839e 100644 (file)
@@ -136,7 +136,7 @@ int frontend_syscall_errno(struct proc* p, int n, int a0, int a1, int a2, int a3
 {
        int errno, ret = frontend_syscall(p->pid,n,a0,a1,a2,a3,&errno);
        if(errno && p)
-               set_errno(current_tf,errno);
+               set_errno(errno);
        return ret;
 }
 
index 024818a..71fed7f 100644 (file)
@@ -482,7 +482,7 @@ off_t kfs_llseek(struct file *file, off_t offset, int whence)
                        temp_off = file->f_dentry->d_inode->i_size + offset;
                        break;
                default:
-                       set_errno(current_tf, EINVAL);
+                       set_errno(EINVAL);
                        warn("Unknown 'whence' in llseek()!\n");
                        return -1;
        }
@@ -521,7 +521,7 @@ int kfs_readdir(struct file *dir, struct dirent *dirent)
        /* some of this error handling can be done by the VFS.  The syscall should
         * handle EBADF, EFAULT, and EINVAL (TODO, memory related). */
        if (!(dir_d->d_inode->i_type & FS_I_DIR)) {
-               set_errno(current_tf, ENOTDIR);
+               set_errno(ENOTDIR);
                return -1;
        }
 
@@ -532,7 +532,7 @@ int kfs_readdir(struct file *dir, struct dirent *dirent)
                check_entry();
 
        if (!found) {
-               set_errno(current_tf, ENOENT);
+               set_errno(ENOENT);
                return -1;
        }
        if (count - 1 == dirent->d_off)         /* found the last dir in the list */
index f6ebdaf..312d9f2 100644 (file)
@@ -292,21 +292,21 @@ void *mmap(struct proc *p, uintptr_t addr, size_t len, int prot, int flags,
        printd("mmap(addr %x, len %x, prot %x, flags %x, fd %x, off %x)\n", addr,
               len, prot, flags, fd, offset);
        if (fd >= 0 && (flags & MAP_ANON)) {
-               set_errno(current_tf, EBADF);
+               set_errno(EBADF);
                return MAP_FAILED;
        }
        if ((addr + len > UMAPTOP) || (PGOFF(addr))) {
-               set_errno(current_tf, EINVAL);
+               set_errno(EINVAL);
                return MAP_FAILED;
        }
        if (!len) {
-               set_errno(current_tf, EINVAL);
+               set_errno(EINVAL);
                return MAP_FAILED;
        }
        if (fd != -1) {
                file = get_file_from_fd(&p->open_files, fd);
                if (!file) {
-                       set_errno(current_tf, EBADF);
+                       set_errno(EBADF);
                        return MAP_FAILED;
                }
        }
@@ -346,7 +346,7 @@ void *__do_mmap(struct proc *p, uintptr_t addr, size_t len, int prot, int flags,
        vmr = create_vmr(p, addr, len);
        if (!vmr) {
                printk("[kernel] do_mmap() aborted for %08p + %d!\n", addr, len);
-               set_errno(current_tf, ENOMEM);
+               set_errno(ENOMEM);
                return MAP_FAILED;              /* TODO: error propagation for mmap() */
        }
        vmr->vm_prot = prot;
@@ -359,7 +359,7 @@ void *__do_mmap(struct proc *p, uintptr_t addr, size_t len, int prot, int flags,
         * they will have a hole in their VM now. */
        if (file && file->f_op->mmap(file, vmr)) {
                destroy_vmr(vmr);
-               set_errno(current_tf, EACCES);  /* not quite */
+               set_errno(EACCES);      /* not quite */
                return MAP_FAILED;
        }
        addr = vmr->vm_base;            /* so we know which pages to populate later */
@@ -383,12 +383,12 @@ int mprotect(struct proc *p, uintptr_t addr, size_t len, int prot)
        if (!len)
                return 0;
        if ((addr % PGSIZE) || (addr < MMAP_LOWEST_VA)) {
-               set_errno(current_tf, EINVAL);
+               set_errno(EINVAL);
                return -1;
        }
        uintptr_t end = ROUNDUP(addr + len, PGSIZE);
        if (end > UMAPTOP || addr > end) {
-               set_errno(current_tf, ENOMEM);
+               set_errno(ENOMEM);
                return -1;
        }
        spin_lock(&p->proc_lock);
@@ -424,7 +424,7 @@ int __do_mprotect(struct proc *p, uintptr_t addr, size_t len, int prot)
                                        /* at this point, we have a file opened in the wrong mode,
                                         * but we may be allowed to access it still. */
                                        if (check_perms(vmr->vm_file->f_dentry->d_inode, S_IWUSR)) {
-                                               set_errno(current_tf, EACCES);
+                                               set_errno(EACCES);
                                                return -1;
                                        } else {
                                                /* it is okay, though we need to change the file mode.
@@ -443,7 +443,7 @@ int __do_mprotect(struct proc *p, uintptr_t addr, size_t len, int prot)
                                 * start having weird issues with libc overwriting itself (since
                                 * procs mprotect that W), then change this. */
                                if (check_perms(vmr->vm_file->f_dentry->d_inode, S_IWUSR)) {
-                                       set_errno(current_tf, EACCES);
+                                       set_errno(EACCES);
                                        return -1;
                                }
                        }
@@ -470,12 +470,12 @@ int munmap(struct proc *p, uintptr_t addr, size_t len)
        if (!len)
                return 0;
        if ((addr % PGSIZE) || (addr < MMAP_LOWEST_VA)) {
-               set_errno(current_tf, EINVAL);
+               set_errno(EINVAL);
                return -1;
        }
        uintptr_t end = ROUNDUP(addr + len, PGSIZE);
        if (end > UMAPTOP || addr > end) {
-               set_errno(current_tf, EINVAL);
+               set_errno(EINVAL);
                return -1;
        }
        spin_lock(&p->proc_lock);
index 772cd49..266f80c 100644 (file)
@@ -51,7 +51,7 @@ ssize_t core_request(struct proc *p)
                // save the context, to be restarted in _S mode
                p->env_tf = *current_tf;
                env_push_ancillary_state(p); // TODO: (HSS)
-               proc_set_syscall_retval(&p->env_tf, ESUCCESS);
+               set_retval(ESUCCESS);
                /* sending death, since it's not our job to save contexts or anything in
                 * this case.  also, if this returns true, we will not return down
                 * below, and need to eat the reference to p */
@@ -193,7 +193,7 @@ error_t resource_req(struct proc *p, int type, size_t amt_wanted,
                        retval = core_request(p);
                        // i don't like this retval hackery
                        if (retval < 0) {
-                               set_errno(current_tf, -retval);
+                               set_errno(-retval);
                                return -1;
                        }
                        else
index 934b354..4ad2fcf 100644 (file)
@@ -276,12 +276,12 @@ static error_t sys_proc_destroy(struct proc *p, pid_t pid, int exitcode)
        struct proc *p_to_die = pid2proc(pid);
 
        if (!p_to_die) {
-               set_errno(current_tf, ESRCH);
+               set_errno(ESRCH);
                return -1;
        }
        if (!proc_controls(p, p_to_die)) {
                kref_put(&p_to_die->kref);
-               set_errno(current_tf, EPERM);
+               set_errno(EPERM);
                return -1;
        }
        if (p_to_die == p) {
@@ -308,7 +308,7 @@ static ssize_t sys_fork(env_t* e)
        // TODO: right now we only support fork for single-core processes
        if(e->state != PROC_RUNNING_S)
        {
-               set_errno(current_tf,EINVAL);
+               set_errno(EINVAL);
                return -1;
        }
 
@@ -368,7 +368,7 @@ static ssize_t sys_fork(env_t* e)
         * address space. */
        if (env_user_mem_walk(e, 0, UMAPTOP, &copy_page, env)) {
                proc_destroy(env);      /* this is prob what you want, not decref by 2 */
-               set_errno(current_tf,ENOMEM);
+               set_errno(ENOMEM);
                return -1;
        }
        clone_files(&e->open_files, &env->open_files);
@@ -462,13 +462,13 @@ static ssize_t sys_trywait(env_t* e, pid_t pid, int* status)
                        }
                        else // not dead yet
                        {
-                               set_errno(current_tf,0);
+                               set_errno(ESUCCESS);
                                ret = -1;
                        }
                }
                else // not a child of the calling process
                {
-                       set_errno(current_tf,1);
+                       set_errno(EPERM);
                        ret = -1;
                }
 
@@ -479,7 +479,7 @@ static ssize_t sys_trywait(env_t* e, pid_t pid, int* status)
                return ret;
        }
 
-       set_errno(current_tf,1);
+       set_errno(EPERM);
        return -1;
 }
 
@@ -565,19 +565,19 @@ static int sys_notify(struct proc *p, int target_pid, unsigned int notif,
        struct proc *target = pid2proc(target_pid);
 
        if (!target) {
-               set_errno(current_tf, EBADPROC);
+               set_errno(EBADPROC);
                return -1;
        }
        if (!proc_controls(p, target)) {
                kref_put(&target->kref);
-               set_errno(current_tf, EPERM);
+               set_errno(EPERM);
                return -1;
        }
        /* if the user provided a notif_event, copy it in and use that */
        if (u_ne) {
                if (memcpy_from_user(p, &local_ne, u_ne, sizeof(struct notif_event))) {
                        kref_put(&target->kref);
-                       set_errno(current_tf, EINVAL);
+                       set_errno(EINVAL);
                        return -1;
                }
                proc_notify(target, local_ne.ne_type, &local_ne);
@@ -600,7 +600,7 @@ static int sys_self_notify(struct proc *p, uint32_t vcoreid, unsigned int notif,
        /* if the user provided a notif_event, copy it in and use that */
        if (u_ne) {
                if (memcpy_from_user(p, &local_ne, u_ne, sizeof(struct notif_event))) {
-                       set_errno(current_tf, EINVAL);
+                       set_errno(EINVAL);
                        return -1;
                }
                do_notify(p, vcoreid, local_ne.ne_type, &local_ne);
@@ -770,7 +770,7 @@ static intreg_t sys_read(struct proc *p, int fd, void *buf, int len)
        ssize_t ret;
        struct file *file = get_file_from_fd(&p->open_files, fd);
        if (!file) {
-               set_errno(current_tf, EBADF);
+               set_errno(EBADF);
                return -1;
        }
        /* TODO: (UMEM) currently, read() handles user memcpy issues, but we
@@ -795,7 +795,7 @@ static intreg_t sys_write(struct proc *p, int fd, const void *buf, int len)
        ssize_t ret;
        struct file *file = get_file_from_fd(&p->open_files, fd);
        if (!file) {
-               set_errno(current_tf, EBADF);
+               set_errno(EBADF);
                return -1;
        }
        /* TODO: (UMEM) */
@@ -835,7 +835,7 @@ static intreg_t sys_close(struct proc *p, int fd)
 {
        struct file *file = put_file_from_fd(&p->open_files, fd);
        if (!file) {
-               set_errno(current_tf, EBADF);
+               set_errno(EBADF);
                return -1;
        }
        return 0;
@@ -851,13 +851,13 @@ static intreg_t sys_fstat(struct proc *p, int fd, struct kstat *u_stat)
        struct kstat *kbuf;
        struct file *file = get_file_from_fd(&p->open_files, fd);
        if (!file) {
-               set_errno(current_tf, EBADF);
+               set_errno(EBADF);
                return -1;
        }
        kbuf = kmalloc(sizeof(struct kstat), 0);
        if (!kbuf) {
                kref_put(&file->f_kref);
-               set_errno(current_tf, ENOMEM);
+               set_errno(ENOMEM);
                return -1;
        }
        stat_inode(file->f_dentry->d_inode, kbuf);
@@ -865,7 +865,7 @@ static intreg_t sys_fstat(struct proc *p, int fd, struct kstat *u_stat)
        /* TODO: UMEM: pin the memory, copy directly, and skip the kernel buffer */
        if (memcpy_to_user_errno(p, u_stat, kbuf, sizeof(struct kstat))) {
                kfree(kbuf);
-               set_errno(current_tf, EINVAL);
+               set_errno(EINVAL);
                return -1;
        }
        kfree(kbuf);
@@ -889,7 +889,7 @@ static intreg_t stat_helper(struct proc *p, const char *path, size_t path_l,
                return -1;
        kbuf = kmalloc(sizeof(struct kstat), 0);
        if (!kbuf) {
-               set_errno(current_tf, ENOMEM);
+               set_errno(ENOMEM);
                kref_put(&path_i->i_kref);
                return -1;
        }
@@ -898,7 +898,7 @@ static intreg_t stat_helper(struct proc *p, const char *path, size_t path_l,
        /* TODO: UMEM: pin the memory, copy directly, and skip the kernel buffer */
        if (memcpy_to_user_errno(p, u_stat, kbuf, sizeof(struct kstat))) {
                kfree(kbuf);
-               set_errno(current_tf, EINVAL);
+               set_errno(EINVAL);
                return -1;
        }
        kfree(kbuf);
@@ -936,7 +936,7 @@ static intreg_t sys_access(struct proc *p, const char *path, size_t path_l,
        user_memdup_free(p, t_path);
        printd("Access for path: %s retval: %d\n", path, retval);
        if (retval < 0) {
-               set_errno(current_tf, -retval);
+               set_errno(-retval);
                return -1;
        }
        return retval;
@@ -962,7 +962,7 @@ static intreg_t sys_lseek(struct proc *p, int fd, off_t offset, int whence)
        off_t ret;
        struct file *file = get_file_from_fd(&p->open_files, fd);
        if (!file) {
-               set_errno(current_tf, EBADF);
+               set_errno(EBADF);
                return -1;
        }
        ret = file->f_op->llseek(file, offset, whence);
@@ -1086,8 +1086,8 @@ intreg_t syscall(struct proc *p, uintreg_t syscallno, uintreg_t a1,
 {
        // Initialize the return value and error code returned to 0
        if(current_tf != NULL){
-               proc_set_syscall_retval(&p->env_tf, ESUCCESS);
-               set_errno(current_tf,0);
+               set_retval(ESUCCESS);
+               set_errno(ESUCCESS);
        }
 
        typedef intreg_t (*syscall_t)(struct proc*,uintreg_t,uintreg_t,
@@ -1289,3 +1289,14 @@ void systrace_clear_buffer(void)
        memset(systrace_buffer, 0, sizeof(struct systrace_record)*MAX_NUM_TRACED);
        spin_unlock_irqsave(&systrace_lock);
 }
+
+void set_retval(uint32_t retval)
+{
+       struct per_cpu_info* coreinfo = &per_cpu_info[core_id()];
+       *(coreinfo->cur_ret.returnloc) = retval;
+}
+void set_errno(uint32_t errno)
+{
+       struct per_cpu_info* coreinfo = &per_cpu_info[core_id()];
+       *(coreinfo->cur_ret.errno_loc) = errno;
+}
index d1f7e81..ab00b74 100644 (file)
@@ -191,7 +191,7 @@ int memcpy_from_user(struct proc *p, void *dest, const void *DANGEROUS va,
 int memcpy_from_user_errno(struct proc *p, void *dst, const void *src, int len)
 {
        if (memcpy_from_user(p, dst, src, len)) {
-               set_errno(current_tf, EINVAL);
+               set_errno(EINVAL);
                return -1;
        }
        return 0;
@@ -255,7 +255,7 @@ int memcpy_to_user(struct proc *p, void *va, const void *src, size_t len)
 int memcpy_to_user_errno(struct proc *p, void *dst, const void *src, int len)
 {
        if (memcpy_to_user(p, dst, src, len)) {
-               set_errno(current_tf, EINVAL);
+               set_errno(EINVAL);
                return -1;
        }
        return 0;
@@ -280,7 +280,7 @@ void *user_memdup_errno(struct proc *p, const void *va, int len)
 {
        void *kva = user_memdup(p, va, len);
        if (IS_ERR(kva)) {
-               set_errno(current_tf, -PTR_ERR(kva));
+               set_errno(-PTR_ERR(kva));
                return NULL;
        }
        return kva;
@@ -309,7 +309,7 @@ char *user_strdup_errno(struct proc *p, const char *u_string, size_t strlen)
 {
        void *k_string = user_strdup(p, u_string, strlen);
        if (IS_ERR(k_string)) {
-               set_errno(current_tf, -PTR_ERR(k_string));
+               set_errno(-PTR_ERR(k_string));
                return NULL;
        }
        return k_string;
@@ -319,6 +319,6 @@ void *kmalloc_errno(int len)
 {
        void *kva = NULL;
        if (len < 0 || (kva = kmalloc(len, 0)) == NULL)
-               set_errno(current_tf, ENOMEM);
+               set_errno(ENOMEM);
        return kva;
 }
index 11f0657..45851f2 100644 (file)
@@ -525,7 +525,7 @@ struct inode *get_inode(struct dentry *dentry)
         * specific stuff. */
        struct inode *inode = sb->s_op->alloc_inode(sb);
        if (!inode) {
-               set_errno(current_tf, ENOMEM);
+               set_errno(ENOMEM);
                return 0;
        }
        TAILQ_INSERT_HEAD(&sb->s_inodes, inode, i_sb_list);             /* weak inode ref */
@@ -651,7 +651,7 @@ struct inode *lookup_inode(char *path, int flags)
        error = path_lookup(path, flags, nd);
        if (error) {
                path_release(nd);
-               set_errno(current_tf, -error);
+               set_errno(-error);
                return 0;
        }
        inode = nd->dentry->d_inode;
@@ -802,7 +802,7 @@ struct file *do_file_open(char *path, int flags, int mode)
        error = path_lookup(path, lookup_flags, nd);
        if (error) {
                path_release(nd);
-               set_errno(current_tf, -error);
+               set_errno(-error);
                return 0;
        }
        /* see if the target is there, handle accordingly */
@@ -810,7 +810,7 @@ struct file *do_file_open(char *path, int flags, int mode)
        if (!file_d) {
                if (!(flags & O_CREAT)) {
                        path_release(nd);
-                       set_errno(current_tf, ENOENT);
+                       set_errno(ENOENT);
                        return 0;
                }
                /* Create the inode/file.  get a fresh dentry too: */
@@ -829,7 +829,7 @@ struct file *do_file_open(char *path, int flags, int mode)
                        /* wanted to create, not open, bail out */
                        kref_put(&file_d->d_kref);
                        path_release(nd);
-                       set_errno(current_tf, EACCES);
+                       set_errno(EACCES);
                        return 0;
                }
        }
@@ -871,7 +871,7 @@ struct file *dentry_open(struct dentry *dentry, int flags)
        int desired_mode;
        struct file *file = kmem_cache_alloc(file_kcache, 0);
        if (!file) {
-               set_errno(current_tf, ENOMEM);
+               set_errno(ENOMEM);
                return 0;
        }
        inode = dentry->d_inode;
@@ -915,7 +915,7 @@ struct file *dentry_open(struct dentry *dentry, int flags)
        file->f_op->open(inode, file);
        return file;
 error_access:
-       set_errno(current_tf, EACCES);
+       set_errno(EACCES);
        kmem_cache_free(file_kcache, file);
        return 0;
 }