Use a helper to copy out the current context
[akaros.git] / kern / src / trap.c
1 /* Copyright (c) 2012 The Regents of the University of California
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * Arch-independent trap handling and kernel messaging */
6
7 #include <arch/arch.h>
8 #include <smp.h>
9 #include <trap.h>
10 #include <stdio.h>
11 #include <slab.h>
12 #include <assert.h>
13 #include <kdebug.h>
14 #include <kmalloc.h>
15
16 static void print_unhandled_trap(struct proc *p, struct user_context *ctx,
17                                  unsigned int trap_nr, unsigned int err,
18                                  unsigned long aux)
19 {
20         print_user_ctx(ctx);
21         printk("err 0x%x (for PFs: User 4, Wr 2, Rd 1), aux %p\n", err, aux);
22         debug_addr_proc(p, get_user_ctx_pc(ctx));
23         print_vmrs(p);
24         backtrace_user_ctx(p, ctx);
25 }
26
27 /* Traps that are considered normal operations. */
28 static bool benign_trap(unsigned int err)
29 {
30         return err & PF_VMR_BACKED;
31 }
32
33 static void printx_unhandled_trap(struct proc *p, struct user_context *ctx,
34                                   unsigned int trap_nr, unsigned int err,
35                                   unsigned long aux)
36 {
37         if (printx_on && !benign_trap(err))
38                 print_unhandled_trap(p, ctx, trap_nr, err, aux);
39 }
40
41 void reflect_unhandled_trap(unsigned int trap_nr, unsigned int err,
42                             unsigned long aux)
43 {
44         uint32_t coreid = core_id();
45         struct per_cpu_info *pcpui = &per_cpu_info[coreid];
46         struct proc *p = pcpui->cur_proc;
47         uint32_t vcoreid = pcpui->owning_vcoreid;
48         struct preempt_data *vcpd = &p->procdata->vcore_preempt_data[vcoreid];
49         struct hw_trapframe *hw_tf = &pcpui->cur_ctx->tf.hw_tf;
50         assert(p);
51         assert(pcpui->cur_ctx && (pcpui->cur_ctx->type == ROS_HW_CTX));
52         if (!proc_is_vcctx_ready(p)) {
53                 printk("Unhandled user trap from early SCP\n");
54                 goto error_out;
55         }
56         if (vcpd->notif_disabled) {
57                 printk("Unhandled user trap in vcore context from VC %d\n", vcoreid);
58                 goto error_out;
59         }
60         printx_unhandled_trap(p, pcpui->cur_ctx, trap_nr, err, aux);
61         /* need to store trap_nr, err code, and aux into the tf so that it can get
62          * extracted on the other end, and we need to flag the TF in some way so we
63          * can tell it was reflected.  for example, on a PF, we need some number (14
64          * on x86), the prot violation (write, read, etc), and the virt addr (aux).
65          * parlib will know how to extract this info. */
66         __arch_reflect_trap_hwtf(hw_tf, trap_nr, err, aux);
67         /* the guts of a __notify */
68         vcpd->notif_disabled = TRUE;
69         vcpd->uthread_ctx = *pcpui->cur_ctx;
70         memset(pcpui->cur_ctx, 0, sizeof(struct user_context));
71         proc_init_ctx(pcpui->cur_ctx, vcoreid, vcpd->vcore_entry,
72                       vcpd->vcore_stack, vcpd->vcore_tls_desc);
73         return;
74 error_out:
75         print_unhandled_trap(p, pcpui->cur_ctx, trap_nr, err, aux);
76         enable_irq();
77         proc_destroy(p);
78 }
79
80 uintptr_t get_user_ctx_pc(struct user_context *ctx)
81 {
82         switch (ctx->type) {
83                 case ROS_HW_CTX:
84                         return get_hwtf_pc(&ctx->tf.hw_tf);
85                 case ROS_SW_CTX:
86                         return get_swtf_pc(&ctx->tf.sw_tf);
87                 default:
88                         warn("Bad context type %d for ctx %p\n", ctx->type, ctx);
89                         return 0;
90         }
91 }
92
93 uintptr_t get_user_ctx_fp(struct user_context *ctx)
94 {
95         switch (ctx->type) {
96                 case ROS_HW_CTX:
97                         return get_hwtf_fp(&ctx->tf.hw_tf);
98                 case ROS_SW_CTX:
99                         return get_swtf_fp(&ctx->tf.sw_tf);
100                 default:
101                         warn("Bad context type %d for ctx %p\n", ctx->type, ctx);
102                         return 0;
103         }
104 }
105
106 /* Helper, copies the current context to to_ctx. */
107 void copy_current_ctx_to(struct user_context *to_ctx)
108 {
109         struct user_context *cur_ctx = current_ctx;
110
111         *to_ctx = *cur_ctx;
112 }
113
114 struct kmem_cache *kernel_msg_cache;
115
116 void kernel_msg_init(void)
117 {
118         kernel_msg_cache = kmem_cache_create("kernel_msgs",
119                            sizeof(struct kernel_message), ARCH_CL_SIZE, 0, 0, 0);
120 }
121
122 uint32_t send_kernel_message(uint32_t dst, amr_t pc, long arg0, long arg1,
123                              long arg2, int type)
124 {
125         kernel_message_t *k_msg;
126         assert(pc);
127         // note this will be freed on the destination core
128         k_msg = kmem_cache_alloc(kernel_msg_cache, 0);
129         k_msg->srcid = core_id();
130         k_msg->dstid = dst;
131         k_msg->pc = pc;
132         k_msg->arg0 = arg0;
133         k_msg->arg1 = arg1;
134         k_msg->arg2 = arg2;
135         switch (type) {
136                 case KMSG_IMMEDIATE:
137                         spin_lock_irqsave(&per_cpu_info[dst].immed_amsg_lock);
138                         STAILQ_INSERT_TAIL(&per_cpu_info[dst].immed_amsgs, k_msg, link);
139                         spin_unlock_irqsave(&per_cpu_info[dst].immed_amsg_lock);
140                         break;
141                 case KMSG_ROUTINE:
142                         spin_lock_irqsave(&per_cpu_info[dst].routine_amsg_lock);
143                         STAILQ_INSERT_TAIL(&per_cpu_info[dst].routine_amsgs, k_msg, link);
144                         spin_unlock_irqsave(&per_cpu_info[dst].routine_amsg_lock);
145                         break;
146                 default:
147                         panic("Unknown type of kernel message!");
148         }
149         /* since we touched memory the other core will touch (the lock), we don't
150          * need an wmb_f() */
151         /* if we're sending a routine message locally, we don't want/need an IPI */
152         if ((dst != k_msg->srcid) || (type == KMSG_IMMEDIATE))
153                 send_ipi(dst, I_KERNEL_MSG);
154         return 0;
155 }
156
157 /* Kernel message IPI/IRQ handler.
158  *
159  * This processes immediate messages, and that's it (it used to handle routines
160  * too, if it came in from userspace).  Routine messages will get processed when
161  * the kernel has a chance (right before popping to userspace or in smp_idle
162  * before halting).
163  *
164  * Note that all of this happens from interrupt context, and interrupts are
165  * disabled. */
166 void handle_kmsg_ipi(struct hw_trapframe *hw_tf, void *data)
167 {
168         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
169         struct kernel_message *kmsg_i, *temp;
170         /* Avoid locking if the list appears empty (lockless peek is okay) */
171         if (STAILQ_EMPTY(&pcpui->immed_amsgs))
172                 return;
173         /* The lock serves as a cmb to force a re-read of the head of the list */
174         spin_lock_irqsave(&pcpui->immed_amsg_lock);
175         STAILQ_FOREACH_SAFE(kmsg_i, &pcpui->immed_amsgs, link, temp) {
176                 pcpui_trace_kmsg(pcpui, (uintptr_t)kmsg_i->pc);
177                 kmsg_i->pc(kmsg_i->srcid, kmsg_i->arg0, kmsg_i->arg1, kmsg_i->arg2);
178                 STAILQ_REMOVE(&pcpui->immed_amsgs, kmsg_i, kernel_message, link);
179                 kmem_cache_free(kernel_msg_cache, (void*)kmsg_i);
180         }
181         spin_unlock_irqsave(&pcpui->immed_amsg_lock);
182 }
183
184 bool has_routine_kmsg(void)
185 {
186         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
187         /* lockless peek */
188         return !STAILQ_EMPTY(&pcpui->routine_amsgs);
189 }
190
191 /* Helper function, gets the next routine KMSG (RKM).  Returns 0 if the list was
192  * empty. */
193 static kernel_message_t *get_next_rkmsg(struct per_cpu_info *pcpui)
194 {
195         struct kernel_message *kmsg;
196         /* Avoid locking if the list appears empty (lockless peek is okay) */
197         if (STAILQ_EMPTY(&pcpui->routine_amsgs))
198                 return 0;
199         /* The lock serves as a cmb to force a re-read of the head of the list.
200          * IRQs are disabled by our caller. */
201         spin_lock(&pcpui->routine_amsg_lock);
202         kmsg = STAILQ_FIRST(&pcpui->routine_amsgs);
203         if (kmsg)
204                 STAILQ_REMOVE_HEAD(&pcpui->routine_amsgs, link);
205         spin_unlock(&pcpui->routine_amsg_lock);
206         return kmsg;
207 }
208
209 /* Runs routine kernel messages.  This might not return.  In the past, this
210  * would also run immediate messages, but this is unnecessary.  Immediates will
211  * run whenever we reenable IRQs.  We could have some sort of ordering or
212  * guarantees between KMSG classes, but that's not particularly useful at this
213  * point.
214  *
215  * Note this runs from normal context, with interruptes disabled.  However, a
216  * particular RKM could enable interrupts - for instance __launch_kthread() will
217  * restore an old kthread that may have had IRQs on. */
218 void process_routine_kmsg(void)
219 {
220         uint32_t pcoreid = core_id();
221         struct per_cpu_info *pcpui = &per_cpu_info[pcoreid];
222         struct kernel_message msg_cp, *kmsg;
223
224         /* Important that callers have IRQs disabled.  When sending cross-core RKMs,
225          * the IPI is used to keep the core from going to sleep - even though RKMs
226          * aren't handled in the kmsg handler.  Check smp_idle() for more info. */
227         assert(!irq_is_enabled());
228         while ((kmsg = get_next_rkmsg(pcpui))) {
229                 /* Copy in, and then free, in case we don't return */
230                 msg_cp = *kmsg;
231                 kmem_cache_free(kernel_msg_cache, (void*)kmsg);
232                 assert(msg_cp.dstid == pcoreid);        /* caught a brutal bug with this */
233                 set_rkmsg(pcpui);                                       /* we're now in early RKM ctx */
234                 /* The kmsg could block.  If it does, we want the kthread code to know
235                  * it's not running on behalf of a process, and we're actually spawning
236                  * a kernel task.  While we do have a syscall that does work in an RKM
237                  * (change_to), it's not really the rest of the syscall context. */
238                 pcpui->cur_kthread->is_ktask = TRUE;
239                 pcpui_trace_kmsg(pcpui, (uintptr_t)msg_cp.pc);
240                 msg_cp.pc(msg_cp.srcid, msg_cp.arg0, msg_cp.arg1, msg_cp.arg2);
241                 /* And if we make it back, be sure to unset this.  If we never return,
242                  * but the kthread exits via some other way (smp_idle()), then
243                  * smp_idle() will deal with the flag.  The default state is "off".  For
244                  * an example of an RKM that does this, check out the
245                  * monitor->mon_bin_run.  Finally, if the kthread gets swapped out of
246                  * pcpui, such as in __launch_kthread(), the next time the kthread is
247                  * reused, is_ktask will be reset. */
248                 pcpui->cur_kthread->is_ktask = FALSE;
249                 /* If we aren't still in early RKM, it is because the KMSG blocked
250                  * (thus leaving early RKM, finishing in default context) and then
251                  * returned.  This is a 'detached' RKM.  Must idle in this scenario,
252                  * since we might have migrated or otherwise weren't meant to PRKM
253                  * (can't return twice).  Also note that this may involve a core
254                  * migration, so we need to reread pcpui.*/
255                 cmb();
256                 pcpui = &per_cpu_info[core_id()];
257                 if (!in_early_rkmsg_ctx(pcpui))
258                         smp_idle();
259                 clear_rkmsg(pcpui);
260                 /* Some RKMs might turn on interrupts (perhaps in the future) and then
261                  * return. */
262                 disable_irq();
263         }
264 }
265
266 /* extremely dangerous and racy: prints out the immed and routine kmsgs for a
267  * specific core (so possibly remotely) */
268 void print_kmsgs(uint32_t coreid)
269 {
270         struct per_cpu_info *pcpui = &per_cpu_info[coreid];
271         void __print_kmsgs(struct kernel_msg_list *list, char *type)
272         {
273                 char *fn_name;
274                 struct kernel_message *kmsg_i;
275                 STAILQ_FOREACH(kmsg_i, list, link) {
276                         fn_name = get_fn_name((long)kmsg_i->pc);
277                         printk("%s KMSG on %d from %d to run %p(%s)\n", type,
278                                kmsg_i->dstid, kmsg_i->srcid, kmsg_i->pc, fn_name); 
279                         kfree(fn_name);
280                 }
281         }
282         __print_kmsgs(&pcpui->immed_amsgs, "Immedte");
283         __print_kmsgs(&pcpui->routine_amsgs, "Routine");
284 }
285
286 /* Debugging stuff */
287 void kmsg_queue_stat(void)
288 {
289         struct kernel_message *kmsg;
290         bool immed_emp, routine_emp;
291         for (int i = 0; i < num_cores; i++) {
292                 spin_lock_irqsave(&per_cpu_info[i].immed_amsg_lock);
293                 immed_emp = STAILQ_EMPTY(&per_cpu_info[i].immed_amsgs);
294                 spin_unlock_irqsave(&per_cpu_info[i].immed_amsg_lock);
295                 spin_lock_irqsave(&per_cpu_info[i].routine_amsg_lock);
296                 routine_emp = STAILQ_EMPTY(&per_cpu_info[i].routine_amsgs);
297                 spin_unlock_irqsave(&per_cpu_info[i].routine_amsg_lock);
298                 printk("Core %d's immed_emp: %d, routine_emp %d\n", i, immed_emp,
299                routine_emp);
300                 if (!immed_emp) {
301                         kmsg = STAILQ_FIRST(&per_cpu_info[i].immed_amsgs);
302                         printk("Immed msg on core %d:\n", i);
303                         printk("\tsrc:  %d\n", kmsg->srcid);
304                         printk("\tdst:  %d\n", kmsg->dstid);
305                         printk("\tpc:   %p\n", kmsg->pc);
306                         printk("\targ0: %p\n", kmsg->arg0);
307                         printk("\targ1: %p\n", kmsg->arg1);
308                         printk("\targ2: %p\n", kmsg->arg2);
309                 }
310                 if (!routine_emp) {
311                         kmsg = STAILQ_FIRST(&per_cpu_info[i].routine_amsgs);
312                         printk("Routine msg on core %d:\n", i);
313                         printk("\tsrc:  %d\n", kmsg->srcid);
314                         printk("\tdst:  %d\n", kmsg->dstid);
315                         printk("\tpc:   %p\n", kmsg->pc);
316                         printk("\targ0: %p\n", kmsg->arg0);
317                         printk("\targ1: %p\n", kmsg->arg1);
318                         printk("\targ2: %p\n", kmsg->arg2);
319                 }
320                         
321         }
322 }
323
324 void print_kctx_depths(const char *str)
325 {
326         uint32_t coreid = core_id();
327         struct per_cpu_info *pcpui = &per_cpu_info[coreid];
328         
329         if (!str)
330                 str = "(none)";
331         printk("%s: Core %d, irq depth %d, ktrap depth %d, irqon %d\n", str, coreid,
332                irq_depth(pcpui), ktrap_depth(pcpui), irq_is_enabled());
333 }
334
335 void print_user_ctx(struct user_context *ctx)
336 {
337         if (ctx->type == ROS_SW_CTX)
338                 print_swtrapframe(&ctx->tf.sw_tf);
339         else if (ctx->type == ROS_HW_CTX)
340                 print_trapframe(&ctx->tf.hw_tf);
341         else
342                 printk("Bad TF %p type %d!\n", ctx, ctx->type);
343 }