Adds syscall for help entering VC context (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 22 Apr 2013 19:11:15 +0000 (12:11 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 24 Apr 2013 22:19:09 +0000 (15:19 -0700)
We had been using sys_self_notify for this, but I actually want
something that doesn't require a specific vcoreid and just acts on the
calling pcore.

There are a couple cases with the old style where we could send
(harmless) notifs to the wrong core.  If the uthread were interrupted
and migrated right after it decided to self_notify, when it was repopped
in the future, it would notify its old vcore.

The other nice thing about this is that we don't need to worry about the
storage space for the syscall, simplifying our pop code a bit.  I didn't
bother removing the local_sysc from the restart_helper.  Not worth the
hassle, and I'll do it on the next rewrite of the HW TF stuff.

Reinstall kernel headers, rebuild parlib + apps.

kern/include/ros/bits/syscall.h
kern/src/syscall.c
user/parlib/i686/vcore.c [new file with mode: 0644]
user/parlib/include/i686/vcore.h

index 782dc79..c4ae910 100644 (file)
@@ -36,6 +36,7 @@
 #define SYS_provision                          24
 #define SYS_notify                                     25
 #define SYS_self_notify                                26
+#define SYS_vc_entry                           31
 #define SYS_halt_core                          27
 #define SYS_init_arsc                          28
 #define SYS_change_to_m                                29
 #define SYS_socket                                     40
 #define SYS_sendto                                     41
 #define SYS_recvfrom                           42
-#define SYS_select          43
-#define SYS_connect                              44
-#define SYS_send                                               45
-#define SYS_recv                                               46
-#define SYS_bind                                               47
-#define SYS_accept                                     48
-#define SYS_listen                               49
+#define SYS_select                                     43
+#define SYS_connect                                    44
+#define SYS_send                                       45
+#define SYS_recv                                       46
+#define SYS_bind                                       47
+#define SYS_accept                                     48
+#define SYS_listen                                     49
 
 /* Platform specific syscalls */
 #define SYS_serial_read                                75
index 61cad03..6a8b075 100644 (file)
@@ -853,6 +853,15 @@ static int sys_self_notify(struct proc *p, uint32_t vcoreid,
        return 0;
 }
 
+/* Puts the calling core into vcore context, if it wasn't already, via a
+ * self-IPI / active notification.  Barring any weird unmappings, we just send
+ * ourselves a __notify. */
+static int sys_vc_entry(struct proc *p)
+{
+       send_kernel_message(core_id(), __notify, (long)p, 0, 0, KMSG_ROUTINE);
+       return 0;
+}
+
 /* This will set a local timer for usec, then shut down the core.  There's a
  * slight race between spinner and halt.  For now, the core will wake up for
  * other interrupts and service them, but will not process routine messages or
@@ -1554,6 +1563,7 @@ const static struct sys_table_entry syscall_table[] = {
        [SYS_provision] = {(syscall_t)sys_provision, "provision"},
        [SYS_notify] = {(syscall_t)sys_notify, "notify"},
        [SYS_self_notify] = {(syscall_t)sys_self_notify, "self_notify"},
+       [SYS_vc_entry] = {(syscall_t)sys_vc_entry, "vc_entry"},
        [SYS_halt_core] = {(syscall_t)sys_halt_core, "halt_core"},
 #ifdef __CONFIG_SERIAL_IO__
        [SYS_serial_read] = {(syscall_t)sys_serial_read, "ser_read"},
diff --git a/user/parlib/i686/vcore.c b/user/parlib/i686/vcore.c
new file mode 100644 (file)
index 0000000..36574a0
--- /dev/null
@@ -0,0 +1,17 @@
+#include <ros/syscall.h>
+#include <arch/vcore.h>
+
+struct syscall vc_entry = {
+       .num = SYS_vc_entry,
+       .err = 0,
+       .retval = 0,
+       .flags = 0,
+       .ev_q = 0,
+       .u_data = 0,
+       .arg0 = 0,
+       .arg1 = 0,
+       .arg2 = 0,
+       .arg3 = 0,
+       .arg4 = 0,
+       .arg5 = 0,
+};
index baa944b..49cbbef 100644 (file)
@@ -57,12 +57,19 @@ struct restart_helper {
        uint32_t                                        notif_disab_loc;
        uint32_t                                        notif_pend_loc;
        struct syscall                          *sysc;
-       struct syscall                          local_sysc;
+       struct syscall                          local_sysc;     /* unused for now */
        uint32_t                                        eax_save;
        uint32_t                                        eflags;
        uint32_t                                        eip;
 };
 
+/* Static syscall, used for self-notifying.  We never wait on it, and we
+ * actually might submit it multiple times in parallel on different cores!
+ * While this may seem dangerous, the kernel needs to be able to handle this
+ * scenario.  It's also important that we never wait on this, since for all but
+ * the first call, the DONE flag will be set.  (Set once, then never reset) */
+extern struct syscall vc_entry;        /* in i686/vcore.c */
+
 static inline void pop_user_ctx(struct user_context *ctx, uint32_t vcoreid)
 {
        struct hw_trapframe *tf = &ctx->tf.hw_tf;
@@ -79,15 +86,7 @@ static inline void pop_user_ctx(struct user_context *ctx, uint32_t vcoreid)
        /* Fill in the info we'll need later */
        rst->notif_disab_loc = (uint32_t)&vcpd->notif_disabled;
        rst->notif_pend_loc = (uint32_t)&vcpd->notif_pending;
-       rst->sysc = &rst->local_sysc;   /* point to the local one */
-       /* Need to prep the async sysc in case we need to notify ourselves */
-       rst->sysc->num = SYS_self_notify;
-       rst->sysc->flags = 0;
-       rst->sysc->ev_q = 0;            /* technically not needed but will avoid bugs */
-       rst->sysc->arg0 = vcoreid;
-       rst->sysc->arg1 = EV_NONE;
-       rst->sysc->arg2 = 0;            /* no ev_msg */
-       rst->sysc->arg3 = TRUE;         /* just a private VCPD notification */
+       rst->sysc = &vc_entry;
        rst->eax_save = 0;                      /* avoid bugs */
        rst->eflags = tf->tf_eflags;
        rst->eip = tf->tf_eip;