Have switch_{to,back} use an opaque uintptr_t
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 7 Dec 2015 21:31:40 +0000 (16:31 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 10 Dec 2015 16:22:21 +0000 (11:22 -0500)
The value happens to include a struct proc *, but users of switch_{to,back}
should not assume that.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
12 files changed:
kern/include/process.h
kern/src/arsc.c
kern/src/elf.c
kern/src/event.c
kern/src/ktest/pb_ktests.c
kern/src/kthread.c
kern/src/ns/sysfile.c
kern/src/process.c
kern/src/syscall.c
kern/src/ucq.c
kern/src/umem.c
kern/src/vfs.c

index 141225f..23ae35c 100644 (file)
@@ -141,8 +141,8 @@ bool proc_preempt_core(struct proc *p, uint32_t pcoreid, uint64_t usec);
 void proc_preempt_all(struct proc *p, uint64_t usec);
 
 /* Current / cr3 / context management */
-struct proc *switch_to(struct proc *new_p);
-void switch_back(struct proc *new_p, struct proc *old_proc);
+uintptr_t switch_to(struct proc *new_p);
+void switch_back(struct proc *new_p, uintptr_t old_ret);
 void abandon_core(void);
 void clear_owning_proc(uint32_t coreid);
 void proc_tlbshootdown(struct proc *p, uintptr_t start, uintptr_t end);
index 8c52fdc..d97cd1a 100644 (file)
@@ -83,7 +83,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* pcpui = &per_cpu_info[core_id()];
-       struct proc *old_proc;
+       uintptr_t old_proc;
        // looking at a process not initialized to perform arsc. 
        if (sysbr == NULL) 
                return count;
index 8a15f2f..9d1ab58 100644 (file)
@@ -21,7 +21,7 @@ bool is_valid_elf(struct file *f)
 {
        elf64_t h;
        off64_t o = 0;
-       struct proc *c = switch_to(0);
+       uintptr_t c = switch_to(0);
 
        if (f->f_op->read(f, (char*)&h, sizeof(elf64_t), &o) != sizeof(elf64_t)) {
                goto fail;
@@ -148,7 +148,7 @@ static int load_one_elf(struct proc *p, struct file *f, uintptr_t pg_num,
        
        /* 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 *old_proc = switch_to(0);
+       uintptr_t old_proc = switch_to(0);
 
        /* Read in ELF header. */
        elf64_t elfhdr_storage;
index d36a9be..5386b9c 100644 (file)
@@ -362,8 +362,9 @@ static void send_indir(struct proc *p, struct event_queue *ev_q,
 void send_event(struct proc *p, struct event_queue *ev_q, struct event_msg *msg,
                 uint32_t vcoreid)
 {
-       struct proc *old_proc;
+       uintptr_t old_proc;
        struct event_mbox *ev_mbox = 0;
+
        assert(!in_irq_ctx(&per_cpu_info[core_id()]));
        assert(p);
        if (p->state == PROC_DYING)
@@ -482,7 +483,8 @@ void post_vcore_event(struct proc *p, struct event_msg *msg, uint32_t vcoreid,
 {
        /* Need to set p as current to post the event */
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
-       struct proc *old_proc = switch_to(p);
+       uintptr_t old_proc = switch_to(p);
+
        /* *ev_mbox is the user address of the vcpd mbox */
        post_vc_msg(p, vcoreid, get_vcpd_mbox(vcoreid, ev_flags), msg, ev_flags);
        switch_back(p, old_proc);
index a5de1ee..0878162 100644 (file)
@@ -1058,7 +1058,8 @@ bool test_ucq(void)
        void send_msgs(struct alarm_waiter *waiter)
        {
                struct timer_chain *tchain;
-               struct proc *old_proc, *p = waiter->data;
+               struct proc *p = waiter->data;
+               uintptr_t old_proc;
                struct ucq *ucq = (struct ucq*)USTACKTOP;
                struct event_msg msg;
 
index 193a6af..9c6c4ed 100644 (file)
@@ -790,7 +790,7 @@ static int __abort_all_sysc(struct proc *p,
        struct cv_lookup_elm *cle;
        int8_t irq_state = 0;
        struct cv_lookup_tailq abortall_list;
-       struct proc *old_proc = switch_to(p);
+       uintptr_t old_proc = switch_to(p);
        int ret = 0;
        /* Concerns: we need to not remove them from their original list, since
         * concurrent wake ups will cause a dereg, which will remove from the list.
index 24ae802..0d4d171 100644 (file)
@@ -1335,7 +1335,7 @@ void print_chaninfo(struct chan *c)
 int plan9setup(struct proc *new_proc, struct proc *parent, int flags)
 {
        
-       struct proc *old_current;
+       uintptr_t old_current;
        struct kref *new_dot_ref;
        ERRSTACK(1);
        if (waserror()) {
index 9525ffa..a1e80b0 100644 (file)
@@ -1791,14 +1791,14 @@ void clear_owning_proc(uint32_t coreid)
 
 /* Switches to the address space/context of new_p, doing nothing if we are
  * already in new_p.  This won't add extra refcnts or anything, and needs to be
- * paired with switch_back() at the end of whatever function you are in.  Don't
- * migrate cores in the middle of a pair.  Specifically, the uncounted refs are
- * one for the old_proc, which is passed back to the caller, and new_p is
- * getting placed in cur_proc. */
-struct proc *switch_to(struct proc *new_p)
+ * paired with switch_back() at the end of whatever function you are in.
+ * Specifically, the uncounted refs are one for the old_proc, which is passed
+ * back to the caller, and new_p is getting placed in cur_proc. */
+uintptr_t switch_to(struct proc *new_p)
 {
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
        struct proc *old_proc;
+
        old_proc = pcpui->cur_proc;                                     /* uncounted ref */
        /* If we aren't the proc already, then switch to it */
        if (old_proc != new_p) {
@@ -1808,14 +1808,16 @@ struct proc *switch_to(struct proc *new_p)
                else
                        lcr3(boot_cr3);
        }
-       return old_proc;
+       return (uintptr_t)old_proc;
 }
 
-/* This switches back to old_proc from new_p.  Pair it with switch_to(), and
- * pass in its return value for old_proc. */
-void switch_back(struct proc *new_p, struct proc *old_proc)
+/* This switches back from new_p to the original process.  Pair it with
+ * switch_to(), and pass in its return value for old_ret. */
+void switch_back(struct proc *new_p, uintptr_t old_ret)
 {
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
+       struct proc *old_proc = (struct proc*)old_ret;
+
        if (old_proc != new_p) {
                pcpui->cur_proc = old_proc;
                if (old_proc)
index 77995c6..70fe938 100644 (file)
@@ -712,7 +712,7 @@ static int sys_change_vcore(struct proc *p, uint32_t vcoreid,
 
 static ssize_t sys_fork(env_t* e)
 {
-       struct proc *temp;
+       uintptr_t temp;
        int8_t state = 0;
        int ret;
 
@@ -2724,7 +2724,7 @@ bool syscall_uses_fd(struct syscall *sysc, int fd)
 
 void print_sysc(struct proc *p, struct syscall *sysc)
 {
-       struct proc *old_p = switch_to(p);
+       uintptr_t old_p = switch_to(p);
        printk("SYS_%d, flags %p, a0 %p, a1 %p, a2 %p, a3 %p, a4 %p, a5 %p\n",
               sysc->num, atomic_read(&sysc->flags),
               sysc->arg0, sysc->arg1, sysc->arg2, sysc->arg3, sysc->arg4,
index e11c809..8b24b7d 100644 (file)
@@ -134,7 +134,7 @@ error_addr:
 void print_ucq(struct proc *p, struct ucq *ucq)
 {
        struct ucq_page *ucq_pg;
-       struct proc *old_proc = switch_to(p);
+       uintptr_t old_proc = switch_to(p);
 
        printk("UCQ %p\n", ucq);
        printk("prod_idx: %p, cons_idx: %p\n", atomic_read(&ucq->prod_idx),
index 46b066e..94753ba 100644 (file)
@@ -54,7 +54,7 @@ static int string_copy_to_user(char *dst, const char *src)
 
 int strcpy_from_user(struct proc *p, char *dst, const char *src)
 {
-       struct proc *prev = switch_to(p);
+       uintptr_t prev = switch_to(p);
        int error = string_copy_from_user(dst, src);
 
        switch_back(p, prev);
@@ -64,7 +64,7 @@ int strcpy_from_user(struct proc *p, char *dst, const char *src)
 
 int strcpy_to_user(struct proc *p, char *dst, const char *src)
 {
-       struct proc *prev = switch_to(p);
+       uintptr_t prev = switch_to(p);
        int error = string_copy_to_user(dst, src);
 
        switch_back(p, prev);
@@ -74,7 +74,7 @@ int strcpy_to_user(struct proc *p, char *dst, const char *src)
 
 int memcpy_from_user(struct proc *p, void *dest, const void *va, size_t len)
 {
-       struct proc *prev = switch_to(p);
+       uintptr_t prev = switch_to(p);
        int error = copy_from_user(dest, va, len);
 
        switch_back(p, prev);
@@ -84,7 +84,7 @@ int memcpy_from_user(struct proc *p, void *dest, const void *va, size_t len)
 
 int memcpy_to_user(struct proc *p, void *dest, const void *src, size_t len)
 {
-       struct proc *prev = switch_to(p);
+       uintptr_t prev = switch_to(p);
        int error = copy_to_user(dest, src, len);
 
        switch_back(p, prev);
index f783e91..8de2f1a 100644 (file)
@@ -2328,9 +2328,10 @@ void file_release(struct kref *kref)
 ssize_t kread_file(struct file *file, void *buf, size_t sz)
 {
        /* TODO: (KFOP) (VFS kernel read/writes need to have no proc current) */
-       struct proc *old_proc = switch_to(0);
+       uintptr_t old_proc = switch_to(0);
        off64_t dummy = 0;
        ssize_t cpy_amt = file->f_op->read(file, buf, sz, &dummy);
+
        switch_back(0, old_proc);
        return cpy_amt;
 }