]> git.corax.cc Git - corax/commitdiff
Deliver a POSIX signal to a process that has caused an exception
authorMatthias Kruk <m@m10k.eu>
Sun, 5 Jan 2020 07:55:54 +0000 (16:55 +0900)
committerMatthias Kruk <m@m10k.eu>
Sun, 5 Jan 2020 07:55:54 +0000 (16:55 +0900)
kernel/arch/interrupt.c
kernel/include/arch.h

index 53ff6775530173a343d065974d59951058a52cf4..6aaf88a6c73a0100d38226aded20bfbe43103ea5 100644 (file)
@@ -27,6 +27,7 @@
 #include "defs.h"
 
 extern void pg_fault_debug(pg_dir_t*, void*);
+extern void _task_sig_stub();
 
 void sched_tick(void);
 extern int sys_cxnet(long, long, long, long, long, long, long);
@@ -47,6 +48,29 @@ extern void _apic_eoi(u32_t);
 extern void _i8259_eoi(u32_t);
 #endif /* CONFIG_APIC */
 
+void task_signal_deliver(task_t *task, stack_frame_t *stk, int signum)
+{
+       struct {
+               void *eip;
+               void *handler;
+               int signal;
+               void *data;
+               siginfo_t si;
+       } __attribute__((packed)) stkfrm;
+
+       stkfrm.data = NULL;
+       stkfrm.signal = signum;
+       stkfrm.eip = (void*)stk->eip;
+       stkfrm.handler = process_get_sighandler((process_t*)task->t_proc, signum);
+       stk->eip = (u32_t)_task_sig_stub;
+       stk->prevesp -= sizeof(stkfrm);
+
+       /* copy the data onto the user-mode stack */
+       process_memcpy_ktop((process_t*)task->t_proc, (void*)stk->prevesp, &stkfrm, sizeof(stkfrm));
+
+       return;
+}
+
 void _int_handle(stack_frame_t ctx)
 {
     switch(ctx.intn) {
@@ -107,8 +131,10 @@ void _int_handle(stack_frame_t ctx)
 void _exc_handle(stack_frame_t ctx)
 {
        process_t *cproc;
+       task_t *ctask;
 
-       cproc = process_get_current();
+       ctask = task_get_current();
+       cproc = (process_t*)ctask->t_proc;
 
        if(ctx.cs == KERNEL_CODE) {
                /* kernel bug */
@@ -137,6 +163,22 @@ void _exc_handle(stack_frame_t ctx)
 
                int sig;
 
+               dbg_printf("User-mode exception %u at 0x%08x\n", ctx.intn, ctx.eip);
+
+               if(ctx.intn == EXC_PAGEFAULT) {
+                       u32_t cr2;
+                       pg_dir_t *pd;
+
+                       asm volatile("movl %%cr2, %%eax; movl %%eax, %0" : "=r"(cr2));
+                       dbg_printf("CR2: 0x%08x\n", cr2);
+
+                       if(process_get_pagedir(cproc, &pd) == 0) {
+                               pg_fault_debug(pd, (void*)cr2);
+                       }
+                       for(;;);
+               }
+
+
                switch(ctx.intn) {
                default:
                case EXC_DEBUG:
@@ -170,10 +212,9 @@ void _exc_handle(stack_frame_t ctx)
                }
 
                /*
-                * Deliver the signal to the current process. The process_signal_deliver()
-                * function will make sure that the signal is handled by the current task.
+                * Deliver the signal to the currently executing task
                 */
-               process_signal_deliver(cproc, sig);
+               task_signal_deliver(ctask, &ctx, sig);
        }
 
     return;
index 29c8804b4f91673a1b136280e144c7cae610df07..9917ea41a27ac0e5db92763fa9b1d16188191f71 100644 (file)
@@ -192,6 +192,8 @@ int     pg_dir_munmap(pg_dir_t*, void*, u32_t);
 u8_t    io_inb(const u16_t);
 void    io_outb(const u16_t, const u8_t);
 
+void    task_signal_deliver(task_t*, stack_frame_t*, int);
+
 #endif /* !__ASSEMBLY_SOURCE */
 
 #endif /* __ARCH_H */