summaryrefslogtreecommitdiffstats
path: root/arch/arm/cpu/interrupts_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/cpu/interrupts_64.c')
-rw-r--r--arch/arm/cpu/interrupts_64.c44
1 files changed, 35 insertions, 9 deletions
diff --git a/arch/arm/cpu/interrupts_64.c b/arch/arm/cpu/interrupts_64.c
index f54fdcd3dd..6262ba8872 100644
--- a/arch/arm/cpu/interrupts_64.c
+++ b/arch/arm/cpu/interrupts_64.c
@@ -6,10 +6,12 @@
#include <common.h>
#include <abort.h>
#include <asm/ptrace.h>
+#include <asm/barebox-arm.h>
#include <asm/unwind.h>
#include <init.h>
#include <asm/system.h>
#include <asm/esr.h>
+#include <efi/efi-mode.h>
/* Avoid missing prototype warning, called from assembly */
void do_bad_sync (struct pt_regs *pt_regs);
@@ -88,7 +90,7 @@ static void __noreturn do_exception(struct pt_regs *pt_regs)
unwind_backtrace(pt_regs);
- panic("panic: unhandled exception");
+ panic_no_stacktrace("panic: unhandled exception");
}
/**
@@ -142,17 +144,38 @@ void do_bad_error(struct pt_regs *pt_regs)
extern volatile int arm_ignore_data_abort;
extern volatile int arm_data_abort_occurred;
+static const char *data_abort_reason(ulong far)
+{
+ ulong guard_page;
+
+ if (far < PAGE_SIZE)
+ return "NULL pointer dereference: ";
+
+ if (IS_ENABLED(CONFIG_STACK_GUARD_PAGE)) {
+ guard_page = arm_mem_guard_page_get();
+ if (guard_page <= far && far < guard_page + PAGE_SIZE)
+ return "Stack overflow: ";
+ }
+
+ return NULL;
+}
+
void do_sync(struct pt_regs *pt_regs, unsigned int esr, unsigned long far)
{
- if ((esr >> ESR_ELx_EC_SHIFT) == ESR_ELx_EC_DABT_CUR &&
- arm_ignore_data_abort) {
- arm_data_abort_occurred = 1;
- pt_regs->elr += 4;
- return;
+ const char *extra = NULL;
+
+ if ((esr >> ESR_ELx_EC_SHIFT) == ESR_ELx_EC_DABT_CUR) {
+ if (arm_ignore_data_abort) {
+ arm_data_abort_occurred = 1;
+ pt_regs->elr += 4;
+ return;
+ }
+
+ extra = data_abort_reason(far);
}
- printf("%s exception (ESR 0x%08x) at 0x%016lx\n", esr_get_class_string(esr),
- esr, far);
+ printf("%s%s exception (ESR 0x%08x) at 0x%016lx\n", extra ?: "",
+ esr_get_class_string(esr), esr, far);
do_exception(pt_regs);
}
@@ -182,6 +205,9 @@ static int aarch64_init_vectors(void)
{
unsigned int el;
+ if (efi_is_payload())
+ return 0;
+
el = current_el();
switch (el) {
case 3:
@@ -199,4 +225,4 @@ static int aarch64_init_vectors(void)
return 0;
}
-pure_initcall(aarch64_init_vectors);
+core_initcall(aarch64_init_vectors);