aboutsummaryrefslogtreecommitdiff
path: root/sys/arch/amd64
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/amd64')
-rw-r--r--sys/arch/amd64/amd64/trap.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/sys/arch/amd64/amd64/trap.c b/sys/arch/amd64/amd64/trap.c
index f1e58f1..3caaaff 100644
--- a/sys/arch/amd64/amd64/trap.c
+++ b/sys/arch/amd64/amd64/trap.c
@@ -32,6 +32,9 @@
#include <sys/spinlock.h>
#include <sys/syslog.h>
#include <sys/panic.h>
+#include <sys/signal.h>
+#include <sys/proc.h>
+#include <sys/sched.h>
static const char *trap_type[] = {
[TRAP_BREAKPOINT] = "breakpoint",
@@ -103,23 +106,44 @@ regdump(struct trapframe *tf)
tf->rbp, tf->rsp, tf->rip);
}
+static inline void
+handle_fatal(struct trapframe *tf)
+{
+ trap_print(tf);
+ regdump(tf);
+ panic("Halted\n");
+}
+
/*
* Handles traps.
*/
void
trap_handler(struct trapframe *tf)
{
- trap_print(tf);
+ struct proc *curtd = this_td();
/*
* XXX: Handle NMIs better. For now we just
* panic.
*/
if (tf->trapno == TRAP_NMI) {
+ trap_print(tf);
kprintf("Possible hardware failure?\n");
panic("Caught NMI; bailing out\n");
}
- regdump(tf);
- panic("Halted\n");
+ if (curtd == NULL) {
+ handle_fatal(tf);
+ } else if (!curtd->is_user) {
+ handle_fatal(tf);
+ }
+
+ switch (tf->trapno) {
+ case TRAP_ARITH_ERR:
+ signal_raise(curtd, SIGFPE);
+ break;
+ default:
+ signal_raise(curtd, SIGSEGV);
+ break;
+ }
}