Use a helper to copy out the current context
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 19 Nov 2015 23:05:56 +0000 (15:05 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 8 Dec 2015 20:59:08 +0000 (15:59 -0500)
The helper allows us to run some code before we copy out the current
context.  I'll use this shortly as the location to 'finalize' the
context (fully copy it out of hardware).  In the future, we might want
other things in here.

I considered making this take the cur_ctx * to avoid another core_id()
call, but most callers were already passing current_ctx.  Also, if we
didn't use current_ctx (and took a pointer) we could inline the call in
trap.h.  But it's not really worth the hassle yet.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/include/trap.h
kern/src/process.c
kern/src/syscall.c
kern/src/trap.c

index ddbfe50..3fef422 100644 (file)
@@ -40,6 +40,8 @@ void __arch_reflect_trap_hwtf(struct hw_trapframe *hw_tf, unsigned int trap_nr,
 uintptr_t get_user_ctx_pc(struct user_context *ctx);
 uintptr_t get_user_ctx_fp(struct user_context *ctx);
 
+void copy_current_ctx_to(struct user_context *to_ctx);
+
 /* Kernel messages.  This is an in-order 'active message' style messaging
  * subsystem, where you can instruct other cores (including your own) to execute
  * a function (with arguments), either immediately or whenever the kernel is
index c9d63f7..5624b32 100644 (file)
@@ -949,7 +949,7 @@ int proc_change_to_m(struct proc *p)
                        struct preempt_data *vcpd = &p->procdata->vcore_preempt_data[0];
                        assert(current_ctx);
                        /* Copy uthread0's context to VC 0's uthread slot */
-                       vcpd->uthread_ctx = *current_ctx;
+                       copy_current_ctx_to(&vcpd->uthread_ctx);
                        clear_owning_proc(core_id());   /* so we don't restart */
                        save_vc_fp_state(vcpd);
                        /* Userspace needs to not fuck with notif_disabled before
@@ -1006,7 +1006,7 @@ uint32_t __proc_change_to_s(struct proc *p, uint32_t *pc_arr)
        assert(p->state == PROC_RUNNING_M); // TODO: (ACR) async core req
        /* save the context, to be restarted in _S mode */
        assert(current_ctx);
-       p->scp_ctx = *current_ctx;
+       copy_current_ctx_to(&p->scp_ctx);
        clear_owning_proc(core_id());   /* so we don't restart */
        save_vc_fp_state(vcpd);
        /* sending death, since it's not our job to save contexts or anything in
@@ -1091,7 +1091,7 @@ void __proc_save_fpu_s(struct proc *p)
  * VCPD) as a location for pcpui->cur_ctx to point (dangerous) */
 void __proc_save_context_s(struct proc *p)
 {
-       p->scp_ctx = *current_ctx;
+       copy_current_ctx_to(&p->scp_ctx);
        __seq_start_write(&p->procinfo->coremap_seqctr);
        __unmap_vcore(p, 0);
        __seq_end_write(&p->procinfo->coremap_seqctr);
@@ -2005,7 +2005,7 @@ int proc_change_to_vcore(struct proc *p, uint32_t new_vcoreid,
        } else {
                /* need to set up the calling vcore's ctx so that it'll get restarted by
                 * __startcore, to make the caller look like it was preempted. */
-               caller_vcpd->vcore_ctx = *current_ctx;
+               copy_current_ctx_to(&caller_vcpd->vcore_ctx);
                save_vc_fp_state(caller_vcpd);
        }
        /* Mark our core as preempted (for userspace recovery).  Userspace checks
@@ -2136,7 +2136,7 @@ void __notify(uint32_t srcid, long a0, long a1, long a2)
        vcpd->notif_disabled = TRUE;
        /* save the old ctx in the uthread slot, build and pop a new one.  Note that
         * silly state isn't our business for a notification. */
-       vcpd->uthread_ctx = *pcpui->cur_ctx;
+       copy_current_ctx_to(&vcpd->uthread_ctx);
        memset(pcpui->cur_ctx, 0, sizeof(struct user_context));
        proc_init_ctx(pcpui->cur_ctx, vcoreid, vcpd->vcore_entry,
                      vcpd->vcore_stack, vcpd->vcore_tls_desc);
@@ -2167,9 +2167,9 @@ void __preempt(uint32_t srcid, long a0, long a1, long a2)
         * cur_ctx in the uthread slot, and it'll appear to the vcore when it comes
         * back up the uthread just took a notification. */
        if (vcpd->notif_disabled)
-               vcpd->vcore_ctx = *pcpui->cur_ctx;
+               copy_current_ctx_to(&vcpd->vcore_ctx);
        else
-               vcpd->uthread_ctx = *pcpui->cur_ctx;
+               copy_current_ctx_to(&vcpd->uthread_ctx);
        /* Userspace in a preemption handler on another core might be copying FP
         * state from memory (VCPD) at the moment, and if so we don't want to
         * clobber it.  In this rare case, our current core's FPU state should be
index 56bfa5d..77995c6 100644 (file)
@@ -736,7 +736,7 @@ static ssize_t sys_fork(env_t* e)
                set_errno(EINVAL);
                return -1;
        }
-       env->scp_ctx = *current_ctx;
+       copy_current_ctx_to(&env->scp_ctx);
        enable_irqsave(&state);
 
        env->cache_colors_map = cache_colors_map_alloc();
@@ -824,7 +824,7 @@ static int sys_exec(struct proc *p, char *path, size_t path_l,
        }
        /* Preemptively copy out the cur_ctx, in case we fail later (easier on
         * cur_ctx if we do this now) */
-       p->scp_ctx = *pcpui->cur_ctx;
+       copy_current_ctx_to(&p->scp_ctx);
        /* Clear the current_ctx.  We won't be returning the 'normal' way.  Even if
         * we want to return with an error, we need to go back differently in case
         * we succeed.  This needs to be done before we could possibly block, but
index c3aca07..c228ba2 100644 (file)
@@ -103,6 +103,14 @@ uintptr_t get_user_ctx_fp(struct user_context *ctx)
        }
 }
 
+/* Helper, copies the current context to to_ctx. */
+void copy_current_ctx_to(struct user_context *to_ctx)
+{
+       struct user_context *cur_ctx = current_ctx;
+
+       *to_ctx = *cur_ctx;
+}
+
 struct kmem_cache *kernel_msg_cache;
 
 void kernel_msg_init(void)