Make errno and return value work for async syscalls.
authorDavid Zhu <yuzhu@cs.berkeley.edu>
Wed, 11 Aug 2010 06:08:23 +0000 (23:08 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:51 +0000 (17:35 -0700)
Added a level of indirection so that sparc/i386/async call can
change where to put errno and return value at run time.
Widespread seterrno changes forthcoming after merge.

15 files changed:
kern/arch/i686/env.c
kern/arch/i686/trap.c
kern/arch/sparc/trap.c
kern/include/process.h
kern/include/ros/ring_syscall.h
kern/include/smp.h
kern/include/syscall.h
kern/src/arsc.c
kern/src/elf.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 7f5f4e8..16ac1ec 100644 (file)
@@ -7,6 +7,7 @@
 #include <env.h>
 #include <assert.h>
 #include <pmap.h>
+#include <smp.h>
 
 //
 // This exits the kernel and starts executing some environment's code.
index 889564a..f1604a4 100644 (file)
@@ -191,14 +191,16 @@ trap_dispatch(trapframe_t *tf)
                case T_SYSCALL:
                        // check for userspace, for now
                        assert(tf->tf_cs != GD_KT);
-
+                       struct per_cpu_info* coreinfo = &per_cpu_info[core_id()];
+                       coreinfo->cur_ret.returnloc = &(tf->tf_regs.reg_eax);
+                       coreinfo->cur_ret.errno_loc = &(tf->tf_regs.reg_esi);
                        // syscall code wants an edible reference for current
-                       kref_get(&current->kref, 1);
+                       kref_get(&coreinfo->cur_proc->kref, 1);
                        tf->tf_regs.reg_eax =
-                               syscall(current, tf->tf_regs.reg_eax, tf->tf_regs.reg_edx,
+                               syscall(coreinfo->cur_proc, tf->tf_regs.reg_eax, tf->tf_regs.reg_edx,
                                        tf->tf_regs.reg_ecx, tf->tf_regs.reg_ebx,
                                        tf->tf_regs.reg_edi, tf->tf_regs.reg_esi);
-                       kref_put(&current->kref);
+                       kref_put(&coreinfo->cur_proc->kref);
                        break;
                default:
                        // Unexpected trap: The user process or the kernel has a bug.
@@ -367,8 +369,11 @@ void sysenter_init(void)
 /* This is called from sysenter's asm, with the tf on the kernel stack. */
 void sysenter_callwrapper(struct trapframe *tf)
 {
+       struct per_cpu_info* coreinfo = &per_cpu_info[core_id()];
        if (!in_kernel(tf))
-               set_current_tf(tf);
+               coreinfo->cur_tf = tf;
+       coreinfo->cur_ret.returnloc = &(tf->tf_regs.reg_eax);
+       coreinfo->cur_ret.errno_loc = &(tf->tf_regs.reg_esi);
 
        // syscall code wants an edible reference for current
        kref_get(&current->kref, 1);
index 7ed17a6..b9a4246 100644 (file)
@@ -419,13 +419,17 @@ handle_syscall(trapframe_t* state)
 
        advance_pc(state);
        enable_irq();
+       struct per_cpu_info* coreinfo = per_cpu_info[core_id()];
 
        set_current_tf(state);
 
+       coreinfo->cur_ret.returnloc = &(state->gpr[8]);
+       coreinfo->cur_ret.errno_loc = &(state->gpr[9]);
+
        // syscall code wants an edible reference for current
-       kref_get(&current->kref, 1);
+       kref_get(&coreinfo->cur_proc->kref, 1);
        state->gpr[8] = syscall(current,num,a1,a2,a3,a4,a5);
-       kref_put(&current->kref);
+       kref_put(&coreinfo->cur_proc->kref);
 
        proc_restartcore(current,state);
 }
index 8237d10..22b8e04 100644 (file)
@@ -129,7 +129,6 @@ void proc_preempt_all(struct proc *p, uint64_t usec);
 /* Allows the kernel to figure out what process is running on this core.  Can be
  * used just like a pointer to a struct proc.  Need these to be macros due to
  * some circular dependencies with smp.h. */
-#include <smp.h>
 #define current per_cpu_info[core_id()].cur_proc
 #define set_current_proc(p) per_cpu_info[core_id()].cur_proc = (p)
 
index 42d193e..6fd2e8a 100644 (file)
@@ -12,7 +12,8 @@ typedef struct syscall_req {
 } syscall_req_t;
 
 typedef struct syscall_rsp {
-        int32_t retval;
+        uint32_t retval;
+               uint32_t errno;
 } syscall_rsp_t;
 
 // Generic Syscall Ring Buffer
index 7c1a52c..61bd4e5 100644 (file)
@@ -15,6 +15,7 @@
 #include <trap.h>
 #include <atomic.h>
 #include <process.h>
+#include <syscall.h>
 
 #ifdef __SHARC__
 typedef sharC_env_t;
@@ -22,8 +23,10 @@ typedef sharC_env_t;
 
 struct per_cpu_info {
        spinlock_t lock;
+       // cur_proc should be valid on all cores that are not management cores.
        struct proc *cur_proc;
        trapframe_t *cur_tf;
+       struct sys_return cur_ret;
 
 #ifdef __SHARC__
        // held spin-locks. this will have to go elsewhere if multiple kernel
index a98bb3a..6711456 100644 (file)
@@ -4,7 +4,7 @@
 # error "This is ROS kernel header; user programs should not #include it"
 #endif
 
-#include <ros/syscall.h>
+#include <ros/common.h>
 #include <process.h>
 
 #define SYSTRACE_ON                                    0x01
@@ -25,6 +25,10 @@ struct systrace_record {
        uint32_t                vcoreid;
 };
 
+struct sys_return {
+       uint32_t *returnloc;
+       uint32_t *errno_loc;
+};
 
 intreg_t syscall(struct proc *p, uintreg_t num, uintreg_t a1, uintreg_t a2,
                  uintreg_t a3, uintreg_t a4, uintreg_t a5);
index afb7aee..4a965b4 100644 (file)
@@ -17,6 +17,7 @@
 #include <pmap.h>
 #include <stdio.h>
 #include <hashtable.h>
+#include <smp.h>
 #include <arsc_server.h>
 
 
@@ -24,7 +25,7 @@
 struct proc_list arsc_proc_list = TAILQ_HEAD_INITIALIZER(arsc_proc_list);
 spinlock_t arsc_proc_lock = SPINLOCK_INITIALIZER;
 
-intreg_t syscall_async(struct proc *p, syscall_req_t *call)
+intreg_t inline syscall_async(struct proc *p, syscall_req_t *call)
 {
        return syscall(p, call->num, call->args[0], call->args[1],
                       call->args[2], call->args[3], call->args[4]);
@@ -61,6 +62,7 @@ static intreg_t process_generic_syscalls(struct proc *p, size_t max)
 {
        size_t count = 0;
        syscall_back_ring_t* sysbr = &p->syscallbackring;
+       struct per_cpu_info* coreinfo = &per_cpu_info[core_id()];
        // looking at a process not initialized to perform arsc. 
        if (sysbr == NULL) 
                return count;
@@ -93,6 +95,10 @@ static intreg_t process_generic_syscalls(struct proc *p, size_t max)
                syscall_req_t* req = RING_GET_REQUEST(sysbr, ++(sysbr->req_cons));
                // print req
                printd("req no %d, req arg %c\n", req->num, *((char*)req->args[0]));
+               
+               coreinfo->cur_ret.returnloc = &(rsp.retval);
+               coreinfo->cur_ret.errno_loc = &(rsp.errno);
+               
                rsp.retval = syscall_async(p, req);
                // write response into the slot it came from
                memcpy(req, &rsp, sizeof(syscall_rsp_t));
index a48d3cc..82cbe25 100644 (file)
@@ -6,6 +6,7 @@
 #include <syscall.h>
 #include <elf.h>
 #include <pmap.h>
+#include <smp.h>
 
 typedef struct
 {
index 03959d3..024818a 100644 (file)
@@ -24,6 +24,7 @@
 #include <error.h>
 #include <cpio.h>
 #include <pmap.h>
+#include <smp.h>
 
 #define KFS_MAX_FILE_SIZE 1024*1024*128
 #define KFS_MAGIC 0xdead0001
index 9e51273..f6ebdaf 100644 (file)
@@ -21,6 +21,7 @@
 #include <slab.h>
 #include <kmalloc.h>
 #include <vfs.h>
+#include <smp.h>
 
 struct kmem_cache *vmr_kcache;
 
index f6d42a6..772cd49 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <resource.h>
 #include <process.h>
+#include <smp.h>
 #include <stdio.h>
 #include <assert.h>
 #include <schedule.h>
index 1b934a2..934b354 100644 (file)
@@ -31,6 +31,7 @@
 #include <hashtable.h>
 #include <arch/bitmask.h>
 #include <kfs.h> // eventually replace this with vfs.h
+#include <smp.h>
 #include <arsc_server.h>
 
 
index a974328..d1f7e81 100644 (file)
@@ -13,6 +13,7 @@
 #include <kmalloc.h>
 #include <assert.h>
 #include <pmap.h>
+#include <smp.h>
 
 /**
  * @brief Global variable used to store erroneous virtual addresses as the
index 4f494c4..11f0657 100644 (file)
@@ -14,6 +14,7 @@
 #include <kfs.h>
 #include <pmap.h>
 #include <umem.h>
+#include <smp.h>
 
 struct sb_tailq super_blocks = TAILQ_HEAD_INITIALIZER(super_blocks);
 spinlock_t super_blocks_lock = SPINLOCK_INITIALIZER;