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
This commit is contained in:
Arne Welzel 2018-03-22 14:27:32 +01:00 committed by Lionel Sambuc
parent 5e9e5b98f6
commit 0dd719f1bd
2 changed files with 26 additions and 33 deletions

View File

@ -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,

View File

@ -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