diff --git a/bl31/aarch64/ea_delegate.S b/bl31/aarch64/ea_delegate.S index 9faa503ff..9d7c5e8a9 100644 --- a/bl31/aarch64/ea_delegate.S +++ b/bl31/aarch64/ea_delegate.S @@ -5,6 +5,7 @@ */ +#include #include #include #include @@ -179,6 +180,15 @@ endfunc delegate_async_ea * x1: EA syndrome */ func ea_proceed + /* + * If the ESR loaded earlier is not zero, we were processing an EA + * already, and this is a double fault. + */ + ldr x5, [sp, #CTX_EL3STATE_OFFSET + CTX_ESR_EL3] + cbz x5, 1f + no_ret plat_handle_double_fault + +1: /* Save EL3 state */ mrs x2, spsr_el3 mrs x3, elr_el3 @@ -216,7 +226,6 @@ func ea_proceed mov x28, sp #endif bl plat_ea_handler - mov x30, x29 #if ENABLE_ASSERTIONS /* @@ -232,7 +241,7 @@ func ea_proceed /* Make SP point to context */ msr spsel, #1 - /* Restore EL3 state */ + /* Restore EL3 state and ESR */ ldp x1, x2, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3] msr spsr_el3, x1 msr elr_el3, x2 @@ -242,5 +251,13 @@ func ea_proceed msr scr_el3, x3 msr esr_el3, x4 - ret +#if ENABLE_ASSERTIONS + cmp x4, xzr + ASM_ASSERT(ne) +#endif + + /* Clear ESR storage */ + str xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_ESR_EL3] + + ret x29 endfunc ea_proceed diff --git a/plat/common/aarch64/platform_helpers.S b/plat/common/aarch64/platform_helpers.S index 13dfac84b..8a07f8f54 100644 --- a/plat/common/aarch64/platform_helpers.S +++ b/plat/common/aarch64/platform_helpers.S @@ -21,6 +21,7 @@ .weak bl32_plat_enable_mmu .weak plat_handle_uncontainable_ea + .weak plat_handle_double_fault #if !ENABLE_PLAT_COMPAT .globl platform_get_core_pos @@ -200,3 +201,14 @@ endfunc bl32_plat_enable_mmu func plat_handle_uncontainable_ea b report_unhandled_exception endfunc plat_handle_uncontainable_ea + + /* ----------------------------------------------------- + * Platform handler for Double Fault. + * + * x0: EA reason + * x1: EA syndrome + * ----------------------------------------------------- + */ +func plat_handle_double_fault + b report_unhandled_exception +endfunc plat_handle_double_fault