aboutsummaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2024-04-10 16:41:26 -0400
committerIan Moffett <ian@osmora.org>2024-04-10 16:46:25 -0400
commit055639ca4842d64af6bba9f6719eaedddc4325d1 (patch)
treefdec02b91a91ce74cc81a18fd467cc05d8252c37 /sys/arch
parentf9e1486c72f3e2b9fb002666bc9091ea691f8e42 (diff)
kernel/amd64: trap: Send signals to thread
Send SIGSEGV, SIGFPE, etc to the thread instead of panicking if it is running in userland Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'sys/arch')
-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;
+ }
}