]> Zhao Yanbai Git Server - minix.git/commitdiff
kernel/arm: send SIGSEGV to processes 17/3517/2
authorArne Welzel <arne.welzel@gmail.com>
Thu, 22 Mar 2018 13:27:32 +0000 (14:27 +0100)
committerLionel Sambuc <lionel.sambuc@gmail.com>
Sun, 25 Mar 2018 13:16:29 +0000 (15:16 +0200)
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
minix/kernel/arch/earm/include/archconst.h

index 1930b24accc26e9531d42ff73b1193848d585f15..3a358d79d8d0262973618381c271c873dedc6ea1 100644 (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,
index b52fe6a591c1a6f2135fe25c0ab673c985e0239f..d85dd81e0a7ea6a152ee4953d13399fc4e044730 100644 (file)
 #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