diff options
author | Ian Moffett <ian@osmora.org> | 2024-04-10 16:41:26 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2024-04-10 16:46:25 -0400 |
commit | 055639ca4842d64af6bba9f6719eaedddc4325d1 (patch) | |
tree | fdec02b91a91ce74cc81a18fd467cc05d8252c37 /sys/arch | |
parent | f9e1486c72f3e2b9fb002666bc9091ea691f8e42 (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.c | 30 |
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; + } } |