Split up reflect_unhandled_trap()
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 21 Jan 2016 21:46:32 +0000 (16:46 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 2 Feb 2016 22:43:52 +0000 (17:43 -0500)
reflect_unhandled_trap() was doing two things: putting the trap info into
the hardware context and reflecting that context back to the 2LS.  This
commit pulls out the latter part, which will be used when reflecting vm
exits.

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

index b5f8d3c..9f13469 100644 (file)
@@ -34,6 +34,7 @@ void set_stack_top(uintptr_t stacktop);
 uintptr_t get_stack_top(void);
 
 void send_nmi(uint32_t os_coreid);
 uintptr_t get_stack_top(void);
 
 void send_nmi(uint32_t os_coreid);
+int reflect_current_context(void);
 void reflect_unhandled_trap(unsigned int trap_nr, unsigned int err,
                             unsigned long aux);
 void __arch_reflect_trap_hwtf(struct hw_trapframe *hw_tf, unsigned int trap_nr,
 void reflect_unhandled_trap(unsigned int trap_nr, unsigned int err,
                             unsigned long aux);
 void __arch_reflect_trap_hwtf(struct hw_trapframe *hw_tf, unsigned int trap_nr,
index 4946ea0..3ad2b31 100644 (file)
@@ -17,6 +17,14 @@ static void print_unhandled_trap(struct proc *p, struct user_context *ctx,
                                  unsigned int trap_nr, unsigned int err,
                                  unsigned long aux)
 {
                                  unsigned int trap_nr, unsigned int err,
                                  unsigned long aux)
 {
+       struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
+       uint32_t vcoreid = pcpui->owning_vcoreid;
+       struct preempt_data *vcpd = &p->procdata->vcore_preempt_data[vcoreid];
+
+       if (!proc_is_vcctx_ready(p))
+               printk("Unhandled user trap from early SCP\n");
+       else if (vcpd->notif_disabled)
+               printk("Unhandled user trap in vcore context from VC %d\n", vcoreid);
        print_user_ctx(ctx);
        printk("err 0x%x (for PFs: User 4, Wr 2, Rd 1), aux %p\n", err, aux);
        debug_addr_proc(p, get_user_ctx_pc(ctx));
        print_user_ctx(ctx);
        printk("err 0x%x (for PFs: User 4, Wr 2, Rd 1), aux %p\n", err, aux);
        debug_addr_proc(p, get_user_ctx_pc(ctx));
@@ -38,42 +46,49 @@ static void printx_unhandled_trap(struct proc *p, struct user_context *ctx,
                print_unhandled_trap(p, ctx, trap_nr, err, aux);
 }
 
                print_unhandled_trap(p, ctx, trap_nr, err, aux);
 }
 
-void reflect_unhandled_trap(unsigned int trap_nr, unsigned int err,
-                            unsigned long aux)
+/* Helper, reflects the current context back to the 2LS.  Returns 0 on success,
+ * -1 on failure. */
+int reflect_current_context(void)
 {
        uint32_t coreid = core_id();
        struct per_cpu_info *pcpui = &per_cpu_info[coreid];
        struct proc *p = pcpui->cur_proc;
        uint32_t vcoreid = pcpui->owning_vcoreid;
        struct preempt_data *vcpd = &p->procdata->vcore_preempt_data[vcoreid];
 {
        uint32_t coreid = core_id();
        struct per_cpu_info *pcpui = &per_cpu_info[coreid];
        struct proc *p = pcpui->cur_proc;
        uint32_t vcoreid = pcpui->owning_vcoreid;
        struct preempt_data *vcpd = &p->procdata->vcore_preempt_data[vcoreid];
-       struct hw_trapframe *hw_tf = &pcpui->cur_ctx->tf.hw_tf;
+
+       if (!proc_is_vcctx_ready(p))
+               return -1;
+       if (vcpd->notif_disabled)
+               return -1;
+       /* the guts of a __notify */
+       vcpd->notif_disabled = TRUE;
+       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);
+       return 0;
+}
+
+void reflect_unhandled_trap(unsigned int trap_nr, unsigned int err,
+                            unsigned long aux)
+{
+       uint32_t coreid = core_id();
+       struct per_cpu_info *pcpui = &per_cpu_info[coreid];
+       struct proc *p = pcpui->cur_proc;
+
        assert(p);
        assert(pcpui->cur_ctx && (pcpui->cur_ctx->type == ROS_HW_CTX));
        assert(p);
        assert(pcpui->cur_ctx && (pcpui->cur_ctx->type == ROS_HW_CTX));
-       if (!proc_is_vcctx_ready(p)) {
-               printk("Unhandled user trap from early SCP\n");
-               goto error_out;
-       }
-       if (vcpd->notif_disabled) {
-               printk("Unhandled user trap in vcore context from VC %d\n", vcoreid);
-               goto error_out;
-       }
-       printx_unhandled_trap(p, pcpui->cur_ctx, trap_nr, err, aux);
        /* need to store trap_nr, err code, and aux into the tf so that it can get
         * extracted on the other end, and we need to flag the TF in some way so we
         * can tell it was reflected.  for example, on a PF, we need some number (14
         * on x86), the prot violation (write, read, etc), and the virt addr (aux).
         * parlib will know how to extract this info. */
        /* need to store trap_nr, err code, and aux into the tf so that it can get
         * extracted on the other end, and we need to flag the TF in some way so we
         * can tell it was reflected.  for example, on a PF, we need some number (14
         * on x86), the prot violation (write, read, etc), and the virt addr (aux).
         * parlib will know how to extract this info. */
-       __arch_reflect_trap_hwtf(hw_tf, trap_nr, err, aux);
-       /* the guts of a __notify */
-       vcpd->notif_disabled = TRUE;
-       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);
-       return;
-error_out:
-       print_unhandled_trap(p, pcpui->cur_ctx, trap_nr, err, aux);
-       proc_destroy(p);
+       __arch_reflect_trap_hwtf(&pcpui->cur_ctx->tf.hw_tf, trap_nr, err, aux);
+       printx_unhandled_trap(p, pcpui->cur_ctx, trap_nr, err, aux);
+       if (reflect_current_context()) {
+               print_unhandled_trap(p, pcpui->cur_ctx, trap_nr, err, aux);
+               proc_destroy(p);
+       }
 }
 
 uintptr_t get_user_ctx_pc(struct user_context *ctx)
 }
 
 uintptr_t get_user_ctx_pc(struct user_context *ctx)