Properly clears cur_sysc when leaving a core
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 17 Mar 2011 23:26:59 +0000 (16:26 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:36:00 +0000 (17:36 -0700)
This was responsible for the PF when bin_run()ning a non existant
program after running a program on core 0.

kern/src/kthread.c
kern/src/process.c
kern/src/syscall.c

index b23c9f5..dc33820 100644 (file)
@@ -71,7 +71,7 @@ void sleep_on(struct semaphore *sem)
        kthread->proc = current;
        /* kthread tracks the syscall it is working on, which implies errno */
        kthread->sysc = pcpui->cur_sysc;
-       pcpui->cur_sysc = 0;                            /* catch bugs */
+       pcpui->cur_sysc = 0;                            /* this core no longer works on sysc */
        if (kthread->proc)
                proc_incref(kthread->proc, 1);
        /* Save the context, toggle blocking for the reactivation */
@@ -159,6 +159,7 @@ void restart_kthread(struct kthread *kthread)
                        lcr3(kthread->proc->env_cr3);
        }
        /* Tell the core which syscall we are running (if any) */
+       assert(!pcpui->cur_sysc);       /* catch bugs, prev user should clear */
        pcpui->cur_sysc = kthread->sysc;
        /* Finally, restart our thread */
        pop_kernel_tf(&kthread->context);
index d04607e..77abbbc 100644 (file)
@@ -1308,8 +1308,12 @@ void __unmap_vcore(struct proc *p, uint32_t vcoreid)
  * process's context. */
 void abandon_core(void)
 {
-       if (current) {
-               current_tf = 0;
+       struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
+       /* Syscalls that don't return will ultimately call abadon_core(), so we need
+        * to make sure we don't think we are still working on a syscall. */
+       pcpui->cur_sysc = 0;
+       if (pcpui->cur_proc) {
+               pcpui->cur_tf = 0;
                __abandon_core();
        }
 }
index 13746f1..57f64d9 100644 (file)
@@ -73,6 +73,7 @@ static bool proc_is_traced(struct proc *p)
 static void signal_current_sc(int retval)
 {
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
+       assert(pcpui->cur_sysc);
        pcpui->cur_sysc->retval = retval;
        pcpui->cur_sysc->flags |= SC_DONE;
 }
@@ -1439,7 +1440,8 @@ static void run_local_syscall(struct syscall *sysc)
         * with userspace for the event_queue registration. */
        atomic_or_int(&sysc->flags, SC_DONE); 
        signal_syscall(sysc, pcpui->cur_proc);
-       /* Can unpin at this point */
+       /* Can unpin (UMEM) at this point */
+       pcpui->cur_sysc = 0;    /* no longer working on sysc */
 }
 
 /* A process can trap and call this function, which will set up the core to