return;
}
+static void
+data_abort(int is_nested, struct proc *pr, reg_t *saved_lr,
+ struct ex_s *ep, u32_t dfar, u32_t dfsr)
+{
+ /* 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 */
+ 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");
+ }
+ NOT_REACHABLE;
+}
+
static void inkernel_disaster(struct proc *saved_proc,
reg_t *saved_lr, struct ex_s *ep,
int is_nested)
}
if (vector == DATA_ABORT_VECTOR) {
- pagefault(saved_proc, saved_lr, is_nested, read_dfar(), read_dfsr());
+ data_abort(is_nested, saved_proc, saved_lr, ep, read_dfar(), read_dfsr());
return;
}
#define INTERRUPT_VECTOR 6
#define FAST_INTERRUPT_VECTOR 7
+
+/* 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_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))
+
/*
* defines how many bytes are reserved at the top of the kernel stack for global
* information like currently scheduled process or current cpu id