Add support for attempting returns from panic
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 30 Oct 2017 18:35:39 +0000 (14:35 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Mon, 30 Oct 2017 18:57:25 +0000 (14:57 -0400)
If you ever wanted to keep going after a panic, it just got a little
easier.  You can exit the monitor ('exit' or 'e'), like always.  This
commit cleans up a little so the core doesn't keep panicking.

This will rarely work well, since the system is toasted, but I've been able
to get back to userspace with it.  You might lose the core that panicked,
(e.g. MCP triggers a racy panic), but at least that core won't keep polling
the console in the monitor.

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

index a383536..9efb1cd 100644 (file)
@@ -87,3 +87,4 @@ void __signal_syscall(struct syscall *sysc, struct proc *p);
 /* Utility */
 bool syscall_uses_fd(struct syscall *sysc, int fd);
 void print_sysc(struct proc *p, struct syscall *sysc);
+void kth_panic_sysc(struct kthread *kth);
index 935e569..414e7ea 100644 (file)
@@ -255,12 +255,19 @@ void _panic(const char *file, int line, const char *fmt,...)
        cprintf("\n");
        va_end(ap);
 
-dead:
        monitor(NULL);
-       /* We could consider turning the lock checker back on here, but things are
-        * probably a mess anyways, and with it on we would probably lock up right
-        * away when we idle. */
-       //pcpui->__lock_checking_enabled++;
+       if (pcpui->cur_proc) {
+               printk("panic killing proc %d\n", pcpui->cur_proc->pid);
+               proc_destroy(pcpui->cur_proc);
+       }
+       /* Yikes!  We're claiming to be not in IRQ/trap ctx and not holding any
+        * locks.  Obviously we could be wrong, and could easily deadlock.  We could
+        * be in an IRQ handler, an unhandled kernel fault, or just a 'normal' panic
+        * in a syscall - any of which can involve unrestore invariants. */
+       pcpui->__ctx_depth = 0;
+       pcpui->lock_depth = 0;
+       if (pcpui->cur_kthread)
+               kth_panic_sysc(pcpui->cur_kthread);
        smp_idle();
 }
 
index b4c2717..39bd0eb 100644 (file)
@@ -2869,3 +2869,12 @@ void print_sysc(struct proc *p, struct syscall *sysc)
               sysc->arg5);
        switch_back(p, old_p);
 }
+
+/* Called when we try to return from a panic. */
+void kth_panic_sysc(struct kthread *kth)
+{
+       kth->sysc = NULL;
+       /* We actually could block here, but that might be OK, since we cleared
+        * cur_kthread->sysc.  As OK as anything is after a panic... */
+       systrace_finish_trace(kth, -12345);
+}