From f4162dff52733d919579e4cb11d882ba5a2297fd Mon Sep 17 00:00:00 2001 From: Tomoki Shirasawa Date: Tue, 14 Apr 2015 15:11:36 +0900 Subject: [PATCH] some signals set siginfo.si_code --- arch/x86/kernel/syscall.c | 1 + kernel/mem.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/arch/x86/kernel/syscall.c b/arch/x86/kernel/syscall.c index f9174d85..edc44d6b 100644 --- a/arch/x86/kernel/syscall.c +++ b/arch/x86/kernel/syscall.c @@ -800,6 +800,7 @@ do_kill(int pid, int tid, int sig, siginfo_t *info, int ptracecont) memset(&info0, '\0', sizeof info0); info = &info0; info0.si_signo = sig; + info0.si_code = SI_KERNEL; } if(tid == -1 && pid <= 0){ diff --git a/kernel/mem.c b/kernel/mem.c index 9691ccc5..5032ad95 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -381,9 +381,24 @@ static void page_fault_handler(void *fault_addr, uint64_t reason, void *regs) unhandled_page_fault(proc, fault_addr, regs); memset(&info, '\0', sizeof info); if (error == -ERANGE) { + info.si_signo = SIGBUS; + info.si_code = BUS_ADRERR; + info._sifields._sigfault.si_addr = fault_addr; set_signal(SIGBUS, regs, &info); } else { + struct process_vm *vm = proc->vm; + struct vm_range *range; + + info.si_signo = SIGSEGV; + info.si_code = SEGV_MAPERR; + list_for_each_entry(range, &vm->vm_range_list, list) { + if (range->start <= (unsigned long)fault_addr && range->end > (unsigned long)fault_addr) { + info.si_code = SEGV_ACCERR; + break; + } + } + info._sifields._sigfault.si_addr = fault_addr; set_signal(SIGSEGV, regs, &info); } check_signal(0, regs);