]> git.corax.cc Git - corax/commitdiff
Deliver signals to processes causing exceptions, panic only if the kernel itself...
authorMatthias Kruk <m@m10k.eu>
Thu, 2 Jan 2020 07:41:15 +0000 (16:41 +0900)
committerMatthias Kruk <m@m10k.eu>
Thu, 2 Jan 2020 07:41:15 +0000 (16:41 +0900)
kernel/arch/interrupt.c

index 1ad7d04b696c4ccff8f832a0ae18082480eff046..53ff6775530173a343d065974d59951058a52cf4 100644 (file)
@@ -22,6 +22,7 @@
 #include <arch.h>
 #include <debug.h>
 #include <process.h>
+#include <signal.h>
 #include "cpu.h"
 #include "defs.h"
 
@@ -94,36 +95,10 @@ void _int_handle(stack_frame_t ctx)
     */
 /*    PANIC("Unhandled interrupt"); */
 
-       switch(ctx.intn) {
-       case INT_KEYBOARD: {
-#if FEATURE(DEBUG)
-        extern struct cpu _cpu[CONFIG_SMP_CPUS];
-#endif /* FEATURE(DEBUG) */
-
-        dbg_printf("Keyboard interrupt\n");
-
-#if FEATURE(DEBUG)
-               /* hacky reboot: clear IDT entries for
-                * #DF and #GP, then cause a #GP */
-               _cpu[CPU_ID].cpu_idt[EXC_DOUBLEFAULT].sd_low = 0;
-               _cpu[CPU_ID].cpu_idt[EXC_DOUBLEFAULT].sd_high = 0;
-               _cpu[CPU_ID].cpu_idt[EXC_PROTECTION].sd_low = 0;
-               _cpu[CPU_ID].cpu_idt[EXC_PROTECTION].sd_high = 0;
-
-               /* this is such a retarded thing to do, I don't see how this
-                * could not cause a triple fault */
-               asm volatile("ljmp $0x30, $0xfee00020"); /* LEEROY JENKINS!!! */
-#endif /* FEATURE(DEBUG) */
-               break;
-       }
-
-       case INT_TIMER:
+       if(ctx.intn == INT_TIMER) {
                sched_tick();
-               break;
-
-       default:
-               dbg_printf("Interrupt %u occurred\n", ctx.intn);
-               break;
+       } else {
+               /* FIXME: handle interrupt */
        }
 
     return;
@@ -135,23 +110,71 @@ void _exc_handle(stack_frame_t ctx)
 
        cproc = process_get_current();
 
-    dbg_printf("Exception %u [%s] occurred. Error code 0x%08x.\n", ctx.intn, ctx.intn < EXC_MAX ? _exc_name[ctx.intn] : 0, ctx.error);
-       dbg_printf("In context %p [pid %u]\n", cproc, process_get_id(cproc));
-    dbg_printf("Fault in 0x%02x:%08x; EFLAGS = 0x%08x\n", ctx.cs, ctx.eip, ctx.eflags);
+       if(ctx.cs == KERNEL_CODE) {
+               /* kernel bug */
+
+               dbg_printf("Exception %u [%s] occurred. Error code 0x%08x.\n",
+                                  ctx.intn, ctx.intn < EXC_MAX ? _exc_name[ctx.intn] : 0, ctx.error);
+               dbg_printf("In context %p [pid %u]\n", cproc, process_get_id(cproc));
+               dbg_printf("Fault in 0x%02x:%08x; EFLAGS = 0x%08x\n", ctx.cs, ctx.eip, ctx.eflags);
 
-    if(ctx.intn == EXC_PAGEFAULT) {
-        u32_t cr2;
-               pg_dir_t *pd;
+               if(ctx.intn == EXC_PAGEFAULT) {
+                       u32_t cr2;
+                       pg_dir_t *pd;
 
-        asm volatile("movl %%cr2, %%eax; movl %%eax, %0" : "=r"(cr2));
-        dbg_printf("Page fault address: 0x%08x\n", cr2);
+                       asm volatile("movl %%cr2, %%eax; movl %%eax, %0" : "=r"(cr2));
+                       dbg_printf("Page fault address: 0x%08x\n", cr2);
 
-               if(process_get_pagedir(cproc, &pd) == 0) {
-                       pg_fault_debug(pd, (void*)cr2);
+                       if(process_get_pagedir(cproc, &pd) == 0) {
+                               pg_fault_debug(pd, (void*)cr2);
+                       }
                }
-    }
 
-    PANIC("Unhandled exception");
+               PANIC("Unhandled exception");
+
+       } else {
+               /* deliver exception to causing process */
+
+               int sig;
+
+               switch(ctx.intn) {
+               default:
+               case EXC_DEBUG:
+               case EXC_NMI:
+               case EXC_BREAKPOINT:
+               case EXC_OVERFLOW:
+               case EXC_BOUNDRANGE:
+               case EXC_DEVNOTAVAIL:
+               case EXC_DOUBLEFAULT:
+               case EXC_COPROCSEGM:
+               case EXC_INVALIDTSS:
+               case EXC_SEGMNOTPRES:
+               case EXC_STACKFAULT:
+               case EXC_PROTECTION:
+               case EXC_PAGEFAULT:
+               case EXC_ALIGNMENT:
+               case EXC_MACHINECHECK:
+               case EXC_VIRTUALIZATION:
+                       sig = SIGSEGV;
+                       break;
+
+               case EXC_INVALOPCODE:
+                       sig = SIGILL;
+                       break;
+
+               case EXC_DIVERR:
+               case EXC_FPUERROR:
+               case EXC_SIMD:
+                       sig = SIGFPE;
+                       break;
+               }
+
+               /*
+                * Deliver the signal to the current process. The process_signal_deliver()
+                * function will make sure that the signal is handled by the current task.
+                */
+               process_signal_deliver(cproc, sig);
+       }
 
     return;
 }