diff options
Diffstat (limited to 'arch/arm/cpu/interrupts_64.c')
-rw-r--r-- | arch/arm/cpu/interrupts_64.c | 44 |
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); |