Fixes sys_change_vcore() return path
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 14 Nov 2011 20:39:26 +0000 (12:39 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 15 Dec 2011 22:48:40 +0000 (14:48 -0800)
Once we unlock, we could have the calling vcore start up remotely before
we get a chance to finish the syscall (writing the syscall struct).  If
the vcore had notifs disabled, it'll start up where it left off and wait
on the syscall finishing, which is fine.  However, if the vcore starts
from scratch on a remote core, nothing will ever wait on the sysc, and
we now could be writing into the stack at some random future date.

kern/src/syscall.c

index 602962f..1060c2a 100644 (file)
@@ -377,7 +377,17 @@ static int sys_proc_yield(struct proc *p, bool being_nice)
 static void sys_change_vcore(struct proc *p, uint32_t vcoreid,
                             bool enable_my_notif)
 {
+       struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
+       /* Change to vcore may start the vcore up remotely before we can finish the
+        * async syscall, so we need to finish the sysc and not touch the struct.
+        * Note this sysc has no return value. */
+       finish_sysc(pcpui->cur_sysc, pcpui->cur_proc);
+       pcpui->cur_sysc = 0;    /* don't touch sysc again */
        proc_change_to_vcore(p, vcoreid, enable_my_notif);
+       /* Should't return, to prevent the chance of mucking with cur_sysc.
+        * smp_idle will make sure we run the appropriate cur_tf (which will be the
+        * new vcore for successful calls). */
+       smp_idle();
 }
 
 static ssize_t sys_fork(env_t* e)