Make the syscall error detector a kernel header (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 27 Jul 2018 20:14:46 +0000 (16:14 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Mon, 30 Jul 2018 20:06:25 +0000 (16:06 -0400)
This information is part of the ABI.  It will help Go userspace determine
whether or not a syscall had an error and thus to extract errno/errstr.

Note that glibc sets errno and errstr based on the syscall->err field
(which is errno).  This means that errno and errstr are set on occasion
even though the syscall didn't have an error.  Glibc apps are expected to
only look at errno/errstr when they know the syscall had an error.

I considered changing glibc (ros_syscall_errno) to use this helper, but it
might be better to have the false positives of copying errno/errstr than to
go through the helper + switch table.  Benchmarks would help here - in lieu
of that I'll leave it as it is.

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/include/ros/syscall.h
kern/src/syscall.c
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/syscall.c

index ea1062d..556299e 100644 (file)
@@ -31,6 +31,89 @@ struct syscall {
        char                                            errstr[MAX_ERRSTR_LEN];
 };
 
+static inline bool syscall_retval_is_error(unsigned int sysc_nr, long retval)
+{
+       switch (sysc_nr) {
+       case SYS_getpcoreid:
+       case SYS_getvcoreid:
+       case SYS_reboot:
+       case SYS_proc_yield:
+       case SYS_vc_entry:
+       case SYS_umask:
+       case SYS_init_arsc:
+               return false;
+       case SYS_abort_sysc:
+       case SYS_abort_sysc_fd:
+               /* These two are a little weird */
+               return false;
+       case SYS_null:
+       case SYS_block:
+       case SYS_nanosleep:
+       case SYS_cache_invalidate:
+       case SYS_proc_run:
+       case SYS_proc_destroy:
+       case SYS_exec:
+       case SYS_munmap:
+       case SYS_mprotect:
+       case SYS_notify:
+       case SYS_self_notify:
+       case SYS_send_event:
+       case SYS_halt_core:
+       case SYS_pop_ctx:
+       case SYS_vmm_poke_guest:
+       case SYS_poke_ksched:
+       case SYS_llseek:
+       case SYS_close:
+       case SYS_fstat:
+       case SYS_stat:
+       case SYS_lstat:
+       case SYS_access:
+       case SYS_link:
+       case SYS_unlink:
+       case SYS_symlink:
+       case SYS_chdir:
+       case SYS_fchdir:
+       case SYS_mkdir:
+       case SYS_rmdir:
+       case SYS_tcgetattr:
+       case SYS_tcsetattr:
+       case SYS_setuid:
+       case SYS_setgid:
+       case SYS_rename:
+       case SYS_nunmount:
+       case SYS_fd2path:
+               return retval != 0;
+       case SYS_proc_create:
+       case SYS_change_vcore:
+       case SYS_fork:
+       case SYS_waitpid:
+       case SYS_shared_page_alloc:
+       case SYS_shared_page_free:
+       case SYS_provision:
+       case SYS_change_to_m:
+       case SYS_vmm_ctl:
+       case SYS_read:
+       case SYS_write:
+       case SYS_openat:
+       case SYS_fcntl:
+       case SYS_readlink:
+       case SYS_getcwd:
+       case SYS_nbind:
+       case SYS_nmount:
+       case SYS_wstat:
+       case SYS_fwstat:
+               return retval < 0;
+       case SYS_mmap:
+               return retval == -1; /* MAP_FAILED */
+       case SYS_vmm_add_gpcs:
+       case SYS_populate_va:
+       case SYS_dup_fds_to:
+       case SYS_tap_fds:
+               return retval <= 0;
+       };
+       return true;
+}
+
 struct childfdmap {
        unsigned int                            parentfd;
        unsigned int                            childfd;
index 79c69b1..4d9287d 100644 (file)
@@ -210,86 +210,7 @@ static bool trace_data_full(struct systrace_record *trace)
 
 static bool systrace_has_error(struct systrace_record *trace)
 {
-       switch (trace->syscallno) {
-       case SYS_getpcoreid:
-       case SYS_getvcoreid:
-       case SYS_reboot:
-       case SYS_proc_yield:
-       case SYS_vc_entry:
-       case SYS_umask:
-       case SYS_init_arsc:
-               return false;
-       case SYS_abort_sysc:
-       case SYS_abort_sysc_fd:
-               /* These two are a little weird */
-               return false;
-       case SYS_null:
-       case SYS_block:
-       case SYS_nanosleep:
-       case SYS_cache_invalidate:
-       case SYS_proc_run:
-       case SYS_proc_destroy:
-       case SYS_exec:
-       case SYS_munmap:
-       case SYS_mprotect:
-       case SYS_notify:
-       case SYS_self_notify:
-       case SYS_send_event:
-       case SYS_halt_core:
-       case SYS_pop_ctx:
-       case SYS_vmm_poke_guest:
-       case SYS_poke_ksched:
-       case SYS_llseek:
-       case SYS_close:
-       case SYS_fstat:
-       case SYS_stat:
-       case SYS_lstat:
-       case SYS_access:
-       case SYS_link:
-       case SYS_unlink:
-       case SYS_symlink:
-       case SYS_chdir:
-       case SYS_fchdir:
-       case SYS_mkdir:
-       case SYS_rmdir:
-       case SYS_tcgetattr:
-       case SYS_tcsetattr:
-       case SYS_setuid:
-       case SYS_setgid:
-       case SYS_rename:
-       case SYS_nunmount:
-       case SYS_fd2path:
-               return trace->retval != 0;
-       case SYS_proc_create:
-       case SYS_change_vcore:
-       case SYS_fork:
-       case SYS_waitpid:
-       case SYS_shared_page_alloc:
-       case SYS_shared_page_free:
-       case SYS_provision:
-       case SYS_change_to_m:
-       case SYS_vmm_ctl:
-       case SYS_read:
-       case SYS_write:
-       case SYS_openat:
-       case SYS_fcntl:
-       case SYS_readlink:
-       case SYS_getcwd:
-       case SYS_nbind:
-       case SYS_nmount:
-       case SYS_wstat:
-       case SYS_fwstat:
-               return (long)trace->retval < 0;
-       case SYS_mmap:
-               return (void*)trace->retval == MAP_FAILED;
-       case SYS_vmm_add_gpcs:
-       case SYS_populate_va:
-       case SYS_dup_fds_to:
-       case SYS_tap_fds:
-               return (long)trace->retval <= 0;
-       };
-       warn_once("Unhandled syscall number %d", trace->syscallno);
-       return true;
+       return syscall_retval_is_error(trace->syscallno, trace->retval);
 }
 
 /* Starts a trace for p running sysc, attaching it to kthread.  Pairs with
index 4d63939..6d69788 100644 (file)
@@ -151,6 +151,8 @@ long __ros_syscall_errno(unsigned int _num, long _a0, long _a1, long _a2,
 {
        struct syscall sysc = __ros_syscall_inline(_num, _a0, _a1, _a2, _a3,
                                                   _a4, _a5);
+
+       /* Consider calling syscall_retval_is_error() */
        if (__builtin_expect(sysc.err, 0)) {
                errno = sysc.err;
                memcpy(errstr(), sysc.errstr, MAX_ERRSTR_LEN);