1 /* Copyright (c) 2012 The Regents of the University of California
2 * Barret Rhoden <brho@cs.berkeley.edu>
3 * See LICENSE for details.
5 * Arch-independent trap handling and kernel messaging */
16 static void print_unhandled_trap(struct proc *p, struct user_context *ctx,
17 unsigned int trap_nr, unsigned int err,
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));
24 backtrace_user_ctx(p, ctx);
27 /* Traps that are considered normal operations. */
28 static bool benign_trap(unsigned int err)
30 return err & PF_VMR_BACKED;
33 static void printx_unhandled_trap(struct proc *p, struct user_context *ctx,
34 unsigned int trap_nr, unsigned int err,
37 if (printx_on && !benign_trap(err))
38 print_unhandled_trap(p, ctx, trap_nr, err, aux);
41 void reflect_unhandled_trap(unsigned int trap_nr, unsigned int err,
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;
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");
56 if (vcpd->notif_disabled) {
57 printk("Unhandled user trap in vcore context\n");
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);
75 print_unhandled_trap(p, pcpui->cur_ctx, trap_nr, err, aux);
80 uintptr_t get_user_ctx_pc(struct user_context *ctx)
84 return get_hwtf_pc(&ctx->tf.hw_tf);
86 return get_swtf_pc(&ctx->tf.sw_tf);
88 warn("Bad context type %d for ctx %p\n", ctx->type, ctx);
93 uintptr_t get_user_ctx_fp(struct user_context *ctx)
97 return get_hwtf_fp(&ctx->tf.hw_tf);
99 return get_swtf_fp(&ctx->tf.sw_tf);
101 warn("Bad context type %d for ctx %p\n", ctx->type, ctx);
106 struct kmem_cache *kernel_msg_cache;
108 void kernel_msg_init(void)
110 kernel_msg_cache = kmem_cache_create("kernel_msgs",
111 sizeof(struct kernel_message), ARCH_CL_SIZE, 0, 0, 0);
114 uint32_t send_kernel_message(uint32_t dst, amr_t pc, long arg0, long arg1,
117 kernel_message_t *k_msg;
119 // note this will be freed on the destination core
120 k_msg = kmem_cache_alloc(kernel_msg_cache, 0);
121 k_msg->srcid = core_id();
129 spin_lock_irqsave(&per_cpu_info[dst].immed_amsg_lock);
130 STAILQ_INSERT_TAIL(&per_cpu_info[dst].immed_amsgs, k_msg, link);
131 spin_unlock_irqsave(&per_cpu_info[dst].immed_amsg_lock);
134 spin_lock_irqsave(&per_cpu_info[dst].routine_amsg_lock);
135 STAILQ_INSERT_TAIL(&per_cpu_info[dst].routine_amsgs, k_msg, link);
136 spin_unlock_irqsave(&per_cpu_info[dst].routine_amsg_lock);
139 panic("Unknown type of kernel message!");
141 /* since we touched memory the other core will touch (the lock), we don't
143 /* if we're sending a routine message locally, we don't want/need an IPI */
144 if ((dst != k_msg->srcid) || (type == KMSG_IMMEDIATE))
145 send_ipi(dst, I_KERNEL_MSG);
149 /* Kernel message IPI/IRQ handler.
151 * This processes immediate messages, and that's it (it used to handle routines
152 * too, if it came in from userspace). Routine messages will get processed when
153 * the kernel has a chance (right before popping to userspace or in smp_idle
156 * Note that all of this happens from interrupt context, and interrupts are
158 void handle_kmsg_ipi(struct hw_trapframe *hw_tf, void *data)
160 struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
161 struct kernel_message *kmsg_i, *temp;
162 /* Avoid locking if the list appears empty (lockless peek is okay) */
163 if (STAILQ_EMPTY(&pcpui->immed_amsgs))
165 /* The lock serves as a cmb to force a re-read of the head of the list */
166 spin_lock_irqsave(&pcpui->immed_amsg_lock);
167 STAILQ_FOREACH_SAFE(kmsg_i, &pcpui->immed_amsgs, link, temp) {
168 pcpui_trace_kmsg(pcpui, (uintptr_t)kmsg_i->pc);
169 kmsg_i->pc(kmsg_i->srcid, kmsg_i->arg0, kmsg_i->arg1, kmsg_i->arg2);
170 STAILQ_REMOVE(&pcpui->immed_amsgs, kmsg_i, kernel_message, link);
171 kmem_cache_free(kernel_msg_cache, (void*)kmsg_i);
173 spin_unlock_irqsave(&pcpui->immed_amsg_lock);
176 bool has_routine_kmsg(void)
178 struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
180 return !STAILQ_EMPTY(&pcpui->routine_amsgs);
183 /* Helper function, gets the next routine KMSG (RKM). Returns 0 if the list was
185 static kernel_message_t *get_next_rkmsg(struct per_cpu_info *pcpui)
187 struct kernel_message *kmsg;
188 /* Avoid locking if the list appears empty (lockless peek is okay) */
189 if (STAILQ_EMPTY(&pcpui->routine_amsgs))
191 /* The lock serves as a cmb to force a re-read of the head of the list.
192 * IRQs are disabled by our caller. */
193 spin_lock(&pcpui->routine_amsg_lock);
194 kmsg = STAILQ_FIRST(&pcpui->routine_amsgs);
196 STAILQ_REMOVE_HEAD(&pcpui->routine_amsgs, link);
197 spin_unlock(&pcpui->routine_amsg_lock);
201 /* Runs routine kernel messages. This might not return. In the past, this
202 * would also run immediate messages, but this is unnecessary. Immediates will
203 * run whenever we reenable IRQs. We could have some sort of ordering or
204 * guarantees between KMSG classes, but that's not particularly useful at this
207 * Note this runs from normal context, with interruptes disabled. However, a
208 * particular RKM could enable interrupts - for instance __launch_kthread() will
209 * restore an old kthread that may have had IRQs on. */
210 void process_routine_kmsg(void)
212 uint32_t pcoreid = core_id();
213 struct per_cpu_info *pcpui = &per_cpu_info[pcoreid];
214 struct kernel_message msg_cp, *kmsg;
216 /* Important that callers have IRQs disabled. When sending cross-core RKMs,
217 * the IPI is used to keep the core from going to sleep - even though RKMs
218 * aren't handled in the kmsg handler. Check smp_idle() for more info. */
219 assert(!irq_is_enabled());
220 while ((kmsg = get_next_rkmsg(pcpui))) {
221 /* Copy in, and then free, in case we don't return */
223 kmem_cache_free(kernel_msg_cache, (void*)kmsg);
224 assert(msg_cp.dstid == pcoreid); /* caught a brutal bug with this */
225 set_rkmsg(pcpui); /* we're now in early RKM ctx */
226 /* The kmsg could block. If it does, we want the kthread code to know
227 * it's not running on behalf of a process, and we're actually spawning
228 * a kernel task. While we do have a syscall that does work in an RKM
229 * (change_to), it's not really the rest of the syscall context. */
230 pcpui->cur_kthread->is_ktask = TRUE;
231 pcpui_trace_kmsg(pcpui, (uintptr_t)msg_cp.pc);
232 msg_cp.pc(msg_cp.srcid, msg_cp.arg0, msg_cp.arg1, msg_cp.arg2);
233 /* And if we make it back, be sure to unset this. If we never return,
234 * but the kthread exits via some other way (smp_idle()), then
235 * smp_idle() will deal with the flag. The default state is "off". For
236 * an example of an RKM that does this, check out the
237 * monitor->mon_bin_run. Finally, if the kthread gets swapped out of
238 * pcpui, such as in __launch_kthread(), the next time the kthread is
239 * reused, is_ktask will be reset. */
240 pcpui->cur_kthread->is_ktask = FALSE;
241 /* If we aren't still in early RKM, it is because the KMSG blocked
242 * (thus leaving early RKM, finishing in default context) and then
243 * returned. This is a 'detached' RKM. Must idle in this scenario,
244 * since we might have migrated or otherwise weren't meant to PRKM
245 * (can't return twice). Also note that this may involve a core
246 * migration, so we need to reread pcpui.*/
248 pcpui = &per_cpu_info[core_id()];
249 if (!in_early_rkmsg_ctx(pcpui))
252 /* Some RKMs might turn on interrupts (perhaps in the future) and then
258 /* extremely dangerous and racy: prints out the immed and routine kmsgs for a
259 * specific core (so possibly remotely) */
260 void print_kmsgs(uint32_t coreid)
262 struct per_cpu_info *pcpui = &per_cpu_info[coreid];
263 void __print_kmsgs(struct kernel_msg_list *list, char *type)
266 struct kernel_message *kmsg_i;
267 STAILQ_FOREACH(kmsg_i, list, link) {
268 fn_name = get_fn_name((long)kmsg_i->pc);
269 printk("%s KMSG on %d from %d to run %p(%s)\n", type,
270 kmsg_i->dstid, kmsg_i->srcid, kmsg_i->pc, fn_name);
274 __print_kmsgs(&pcpui->immed_amsgs, "Immedte");
275 __print_kmsgs(&pcpui->routine_amsgs, "Routine");
278 /* Debugging stuff */
279 void kmsg_queue_stat(void)
281 struct kernel_message *kmsg;
282 bool immed_emp, routine_emp;
283 for (int i = 0; i < num_cpus; i++) {
284 spin_lock_irqsave(&per_cpu_info[i].immed_amsg_lock);
285 immed_emp = STAILQ_EMPTY(&per_cpu_info[i].immed_amsgs);
286 spin_unlock_irqsave(&per_cpu_info[i].immed_amsg_lock);
287 spin_lock_irqsave(&per_cpu_info[i].routine_amsg_lock);
288 routine_emp = STAILQ_EMPTY(&per_cpu_info[i].routine_amsgs);
289 spin_unlock_irqsave(&per_cpu_info[i].routine_amsg_lock);
290 printk("Core %d's immed_emp: %d, routine_emp %d\n", i, immed_emp,
293 kmsg = STAILQ_FIRST(&per_cpu_info[i].immed_amsgs);
294 printk("Immed msg on core %d:\n", i);
295 printk("\tsrc: %d\n", kmsg->srcid);
296 printk("\tdst: %d\n", kmsg->dstid);
297 printk("\tpc: %p\n", kmsg->pc);
298 printk("\targ0: %p\n", kmsg->arg0);
299 printk("\targ1: %p\n", kmsg->arg1);
300 printk("\targ2: %p\n", kmsg->arg2);
303 kmsg = STAILQ_FIRST(&per_cpu_info[i].routine_amsgs);
304 printk("Routine msg on core %d:\n", i);
305 printk("\tsrc: %d\n", kmsg->srcid);
306 printk("\tdst: %d\n", kmsg->dstid);
307 printk("\tpc: %p\n", kmsg->pc);
308 printk("\targ0: %p\n", kmsg->arg0);
309 printk("\targ1: %p\n", kmsg->arg1);
310 printk("\targ2: %p\n", kmsg->arg2);
316 void print_kctx_depths(const char *str)
318 uint32_t coreid = core_id();
319 struct per_cpu_info *pcpui = &per_cpu_info[coreid];
323 printk("%s: Core %d, irq depth %d, ktrap depth %d, irqon %d\n", str, coreid,
324 irq_depth(pcpui), ktrap_depth(pcpui), irq_is_enabled());
327 void print_user_ctx(struct user_context *ctx)
329 if (ctx->type == ROS_SW_CTX)
330 print_swtrapframe(&ctx->tf.sw_tf);
331 else if (ctx->type == ROS_HW_CTX)
332 print_trapframe(&ctx->tf.hw_tf);
334 printk("Bad TF %p type %d!\n", ctx, ctx->type);