diff --git a/arch/x86/traps.c b/arch/x86/traps.c index fa7da76b..915b2b4e 100644 --- a/arch/x86/traps.c +++ b/arch/x86/traps.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -34,9 +35,9 @@ #include #include #include +#include #include -#include extern void asm_interrupt_handler_uart(void); extern void asm_interrupt_handler_keyboard(void); @@ -298,7 +299,7 @@ static bool extables_fixup(struct cpu_regs *regs) { void do_exception(struct cpu_regs *regs) { static char ec_str[32], panic_str[128]; - if (extables_fixup(regs)) + if (!from_usermode(regs->cs) && extables_fixup(regs)) return; dump_regs(regs); @@ -312,5 +313,11 @@ void do_exception(struct cpu_regs *regs) { exception_names[regs->vector], ec_str, regs->cs, regs->_ASM_IP, regs->ss, regs->_ASM_SP); + /* Handle user tasks' exceptions */ + if (from_usermode(regs->cs)) { + printk("Task exception: %s\n", panic_str); + goto_syscall_exit(-EFAULT); + } + panic(panic_str); } diff --git a/include/usermode.h b/include/usermode.h index 03b7fc01..8a7acfea 100644 --- a/include/usermode.h +++ b/include/usermode.h @@ -37,6 +37,11 @@ static inline bool from_usermode(uint16_t cs) { return (cs & 0x3) != 0; } +static inline void goto_syscall_exit(long exit_code) { + swapgs(); + asm volatile("jmp syscall_handler" ::"A"(SYSCALL_EXIT), "D"(exit_code)); +} + /* External declarations */ extern unsigned long enter_usermode(task_func_t fn, void *fn_arg,