From: Matthias Kruk Date: Sun, 5 Jan 2020 07:55:54 +0000 (+0900) Subject: Deliver a POSIX signal to a process that has caused an exception X-Git-Url: https://git.corax.cc/?a=commitdiff_plain;h=ca81cd4e572c07526e8064599d17f4785a496773;p=corax Deliver a POSIX signal to a process that has caused an exception --- diff --git a/kernel/arch/interrupt.c b/kernel/arch/interrupt.c index 53ff677..6aaf88a 100644 --- a/kernel/arch/interrupt.c +++ b/kernel/arch/interrupt.c @@ -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; diff --git a/kernel/include/arch.h b/kernel/include/arch.h index 29c8804..9917ea4 100644 --- a/kernel/include/arch.h +++ b/kernel/include/arch.h @@ -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 */