From 0dd719f1bd28ca1fd3474cf2d18d9e041c5ec028 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Thu, 22 Mar 2018 14:27:32 +0100 Subject: [PATCH] kernel/arm: send SIGSEGV to processes On second thought, handle unknown faults caused by processes by sending SIGSEGV to them instead of bringing the whole system to a grind. arm/archconst: use values defined in armreg.h Change-Id: Ieed5bb06910ab0c8eef1e68b0b4eec680867acd3 --- minix/kernel/arch/earm/exception.c | 36 ++++++++++++---------- minix/kernel/arch/earm/include/archconst.h | 23 +++++--------- 2 files changed, 26 insertions(+), 33 deletions(-) diff --git a/minix/kernel/arch/earm/exception.c b/minix/kernel/arch/earm/exception.c index 1930b24ac..3a358d79d 100644 --- a/minix/kernel/arch/earm/exception.c +++ b/minix/kernel/arch/earm/exception.c @@ -116,25 +116,27 @@ data_abort(int is_nested, struct proc *pr, reg_t *saved_lr, /* Extract fault status bit [0:3, 10] from DFSR */ u32_t fs = dfsr & 0x0F; fs |= ((dfsr >> 6) & 0x10); - if (is_alignment_fault(fs)) { - if (is_nested) { - printf("KERNEL: alignment fault dfar=0x%lx\n", dfar); - inkernel_disaster(pr, saved_lr, ep, is_nested); - } - /* Send SIGBUS to violating process. */ - cause_sig(proc_nr(pr), SIGBUS); - return; - } else if (is_translation_fault(fs) || is_permission_fault(fs)) { - /* Ask VM to handle translation and permission faults as pagefaults */ + + /* Translation and permission faults are handled as pagefaults. */ + if (is_trans_fault(fs) || is_perm_fault(fs)) { pagefault(pr, saved_lr, is_nested, dfar, dfsr); - return; - } else { - /* Die on unknown things... */ - printf("KERNEL: unhandled data abort dfar=0x%lx dfsr=0x%lx " - "fs=0x%lx is_nested=%d\n", dfar, dfsr, fs, is_nested); - panic("unhandled data abort"); + } else if (!is_nested) { + /* A user process caused some other kind of data abort. */ + int signum = SIGSEGV; + + if (is_align_fault(fs)) { + signum = SIGBUS; + } else { + printf("KERNEL: unknown data abort by proc %d sending " + "SIGSEGV (dfar=0x%lx dfsr=0x%lx fs=0x%lx)\n", + proc_nr(pr), dfar, dfsr, fs); + } + cause_sig(proc_nr(pr), signum); + } else { /* is_nested */ + printf("KERNEL: inkernel data abort - disaster (dfar=0x%lx " + "dfsr=0x%lx fs=0x%lx)\n", dfar, dfsr, fs); + inkernel_disaster(pr, saved_lr, ep, is_nested); } - NOT_REACHABLE; } static void inkernel_disaster(struct proc *saved_proc, diff --git a/minix/kernel/arch/earm/include/archconst.h b/minix/kernel/arch/earm/include/archconst.h index b52fe6a59..d85dd81e0 100644 --- a/minix/kernel/arch/earm/include/archconst.h +++ b/minix/kernel/arch/earm/include/archconst.h @@ -21,24 +21,15 @@ #define INTERRUPT_VECTOR 6 #define FAST_INTERRUPT_VECTOR 7 +/* Data abort helper */ +#define is_align_fault(fault_status) \ + ((fault_status) == FAULT_ALIGN_0) -/* Known fault status bits */ -#define DFSR_FS_ALIGNMENT_FAULT 0x01 -#define DFSR_FS_TRANSLATION_FAULT_PAGE 0x07 -#define DFSR_FS_TRANSLATION_FAULT_SECTION 0x05 -#define DFSR_FS_PERMISSION_FAULT_PAGE 0x0F -#define DFSR_FS_PERMISSION_FAULT_SECTION 0x0D +#define is_trans_fault(fault_status) \ + (((fault_status) == FAULT_TRANS_S) || ((fault_status) == FAULT_TRANS_P)) -#define is_alignment_fault(fault_status) \ - ((fault_status) == DFSR_FS_ALIGNMENT_FAULT) - -#define is_translation_fault(fault_status) \ - (((fault_status) == DFSR_FS_TRANSLATION_FAULT_PAGE) \ - || ((fault_status) == DFSR_FS_TRANSLATION_FAULT_SECTION)) - -#define is_permission_fault(fault_status) \ - (((fault_status) == DFSR_FS_PERMISSION_FAULT_PAGE) \ - || ((fault_status) == DFSR_FS_PERMISSION_FAULT_SECTION)) +#define is_perm_fault(fault_status) \ + (((fault_status) == FAULT_PERM_S) || ((fault_status) == FAULT_PERM_P)) /* * defines how many bytes are reserved at the top of the kernel stack for global -- 2.44.0