Fix elf loading 'current' management
authorBarret Rhoden <brho@cs.berkeley.edu>
Sun, 9 Feb 2014 04:34:48 +0000 (20:34 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Sun, 9 Feb 2014 07:23:00 +0000 (23:23 -0800)
By not keeping current in sync with the cr3, and not properly switching
back, we expose ourselves to some issues.  Specifically, if we block
after improperly clearing current, we could come back with the
boot_pgdir (the one for current = 0), and then later fail to restore
that.  sys_proc_create caused this with KFS blocking.

kern/src/elf.c
kern/src/process.c

index d8fc0df..9162fc8 100644 (file)
@@ -30,8 +30,7 @@ static int load_one_elf(struct proc *p, struct file *f, uintptr_t pgoffset,
        
        /* When reading on behalf of the kernel, we need to make sure no proc is
         * "current".  This is a bit ghetto (TODO: KFOP) */
-       struct proc *cur_proc = current;
-       current = 0;
+       struct proc *old_proc = switch_to(0);
 
        /* Read in ELF header. */
        elf64_t elfhdr_storage;
@@ -219,7 +218,7 @@ static int load_one_elf(struct proc *p, struct file *f, uintptr_t pgoffset,
 fail:
        if (phdrs)
                kfree(phdrs);
-       current = cur_proc;
+       switch_back(0, old_proc);
        return ret;
 }
 
index c2e5838..0802517 100644 (file)
@@ -1740,7 +1740,10 @@ struct proc *switch_to(struct proc *new_p)
        /* If we aren't the proc already, then switch to it */
        if (old_proc != new_p) {
                pcpui->cur_proc = new_p;                                /* uncounted ref */
-               lcr3(new_p->env_cr3);
+               if (new_p)
+                       lcr3(new_p->env_cr3);
+               else
+                       lcr3(boot_cr3);
        }
        return old_proc;
 }