Define and use no_ret macro where no return is expected

There are many instances in ARM Trusted Firmware where control is
transferred to functions from which return isn't expected. Such jumps
are made using 'bl' instruction to provide the callee with the location
from which it was jumped to. Additionally, debuggers infer the caller by
examining where 'lr' register points to. If a 'bl' of the nature
described above falls at the end of an assembly function, 'lr' will be
left pointing to a location outside of the function range. This misleads
the debugger back trace.

This patch defines a 'no_ret' macro to be used when jumping to functions
from which return isn't expected. The macro ensures to use 'bl'
instruction for the jump, and also, for debug builds, places a 'nop'
instruction immediately thereafter (unless instructed otherwise) so as
to leave 'lr' pointing within the function range.

Change-Id: Ib34c69fc09197cfd57bc06e147cc8252910e01b0
Co-authored-by: Douglas Raillard <douglas.raillard@arm.com>
Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
diff --git a/bl1/aarch64/bl1_exceptions.S b/bl1/aarch64/bl1_exceptions.S
index 869261d..7d97dd6 100644
--- a/bl1/aarch64/bl1_exceptions.S
+++ b/bl1/aarch64/bl1_exceptions.S
@@ -49,25 +49,25 @@
 vector_entry SynchronousExceptionSP0
 	mov	x0, #SYNC_EXCEPTION_SP_EL0
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size SynchronousExceptionSP0
 
 vector_entry IrqSP0
 	mov	x0, #IRQ_SP_EL0
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size IrqSP0
 
 vector_entry FiqSP0
 	mov	x0, #FIQ_SP_EL0
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size FiqSP0
 
 vector_entry SErrorSP0
 	mov	x0, #SERROR_SP_EL0
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size SErrorSP0
 
 	/* -----------------------------------------------------
@@ -77,25 +77,25 @@
 vector_entry SynchronousExceptionSPx
 	mov	x0, #SYNC_EXCEPTION_SP_ELX
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size SynchronousExceptionSPx
 
 vector_entry IrqSPx
 	mov	x0, #IRQ_SP_ELX
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size IrqSPx
 
 vector_entry FiqSPx
 	mov	x0, #FIQ_SP_ELX
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size FiqSPx
 
 vector_entry SErrorSPx
 	mov	x0, #SERROR_SP_ELX
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size SErrorSPx
 
 	/* -----------------------------------------------------
@@ -120,19 +120,19 @@
 vector_entry IrqA64
 	mov	x0, #IRQ_AARCH64
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size IrqA64
 
 vector_entry FiqA64
 	mov	x0, #FIQ_AARCH64
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size FiqA64
 
 vector_entry SErrorA64
 	mov	x0, #SERROR_AARCH64
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size SErrorA64
 
 	/* -----------------------------------------------------
@@ -142,25 +142,25 @@
 vector_entry SynchronousExceptionA32
 	mov	x0, #SYNC_EXCEPTION_AARCH32
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size SynchronousExceptionA32
 
 vector_entry IrqA32
 	mov	x0, #IRQ_AARCH32
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size IrqA32
 
 vector_entry FiqA32
 	mov	x0, #FIQ_AARCH32
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size FiqA32
 
 vector_entry SErrorA32
 	mov	x0, #SERROR_AARCH32
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size SErrorA32
 
 
@@ -231,7 +231,7 @@
 unexpected_sync_exception:
 	mov	x0, #SYNC_EXCEPTION_AARCH64
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 
 	/* -----------------------------------------------------
 	 * Save Secure/Normal world context and jump to
diff --git a/bl2/aarch32/bl2_entrypoint.S b/bl2/aarch32/bl2_entrypoint.S
index 6c620e2..bb0b7f3 100644
--- a/bl2/aarch32/bl2_entrypoint.S
+++ b/bl2/aarch32/bl2_entrypoint.S
@@ -140,6 +140,6 @@
 	 * Should never reach this point.
 	 * ---------------------------------------------
 	 */
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 
 endfunc bl2_entrypoint
diff --git a/bl2/aarch64/bl2_entrypoint.S b/bl2/aarch64/bl2_entrypoint.S
index 476efe8..25363ac 100644
--- a/bl2/aarch64/bl2_entrypoint.S
+++ b/bl2/aarch64/bl2_entrypoint.S
@@ -131,6 +131,6 @@
 	 * Should never reach this point.
 	 * ---------------------------------------------
 	 */
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 
 endfunc bl2_entrypoint
diff --git a/bl2u/aarch64/bl2u_entrypoint.S b/bl2u/aarch64/bl2u_entrypoint.S
index ef3db92..1175c6f 100644
--- a/bl2u/aarch64/bl2u_entrypoint.S
+++ b/bl2u/aarch64/bl2u_entrypoint.S
@@ -126,6 +126,6 @@
 	 * Should never reach this point.
 	 * ---------------------------------------------
 	 */
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 
 endfunc bl2u_entrypoint
diff --git a/bl31/aarch64/crash_reporting.S b/bl31/aarch64/crash_reporting.S
index 7f5a86b..8e60386 100644
--- a/bl31/aarch64/crash_reporting.S
+++ b/bl31/aarch64/crash_reporting.S
@@ -350,17 +350,17 @@
 	plat_crash_print_regs
 
 	/* Done reporting */
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 endfunc do_crash_reporting
 
 #else	/* CRASH_REPORTING */
 func report_unhandled_exception
 report_unhandled_interrupt:
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 endfunc report_unhandled_exception
 #endif	/* CRASH_REPORTING */
 
 
 func crash_panic
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 endfunc crash_panic
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index 220d1cc..6909d08 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -73,7 +73,7 @@
 	b.eq	smc_handler64
 
 	/* Other kinds of synchronous exceptions are not handled */
-	bl	report_unhandled_exception
+	no_ret	report_unhandled_exception
 	.endm
 
 
@@ -176,7 +176,7 @@
 	 */
 vector_entry sync_exception_sp_el0
 	/* We don't expect any synchronous exceptions from EL3 */
-	bl	report_unhandled_exception
+	no_ret	report_unhandled_exception
 	check_vector_size sync_exception_sp_el0
 
 vector_entry irq_sp_el0
@@ -184,17 +184,17 @@
 	 * EL3 code is non-reentrant. Any asynchronous exception is a serious
 	 * error. Loop infinitely.
 	 */
-	bl	report_unhandled_interrupt
+	no_ret	report_unhandled_interrupt
 	check_vector_size irq_sp_el0
 
 
 vector_entry fiq_sp_el0
-	bl	report_unhandled_interrupt
+	no_ret	report_unhandled_interrupt
 	check_vector_size fiq_sp_el0
 
 
 vector_entry serror_sp_el0
-	bl	report_unhandled_exception
+	no_ret	report_unhandled_exception
 	check_vector_size serror_sp_el0
 
 	/* ---------------------------------------------------------------------
@@ -208,19 +208,19 @@
 	 * synchronous exception. There is a high probability that SP_EL3 is
 	 * corrupted.
 	 */
-	bl	report_unhandled_exception
+	no_ret	report_unhandled_exception
 	check_vector_size sync_exception_sp_elx
 
 vector_entry irq_sp_elx
-	bl	report_unhandled_interrupt
+	no_ret	report_unhandled_interrupt
 	check_vector_size irq_sp_elx
 
 vector_entry fiq_sp_elx
-	bl	report_unhandled_interrupt
+	no_ret	report_unhandled_interrupt
 	check_vector_size fiq_sp_elx
 
 vector_entry serror_sp_elx
-	bl	report_unhandled_exception
+	no_ret	report_unhandled_exception
 	check_vector_size serror_sp_elx
 
 	/* ---------------------------------------------------------------------
@@ -250,7 +250,7 @@
 	 * SError exceptions from lower ELs are not currently supported.
 	 * Report their occurrence.
 	 */
-	bl	report_unhandled_exception
+	no_ret	report_unhandled_exception
 	check_vector_size serror_aarch64
 
 	/* ---------------------------------------------------------------------
@@ -280,7 +280,7 @@
 	 * SError exceptions from lower ELs are not currently supported.
 	 * Report their occurrence.
 	 */
-	bl	report_unhandled_exception
+	no_ret	report_unhandled_exception
 	check_vector_size serror_aarch32
 
 
@@ -415,5 +415,5 @@
 rt_svc_fw_critical_error:
 	/* Switch to SP_ELx */
 	msr	spsel, #1
-	bl	report_unhandled_exception
+	no_ret	report_unhandled_exception
 endfunc smc_handler
diff --git a/bl32/tsp/aarch64/tsp_entrypoint.S b/bl32/tsp/aarch64/tsp_entrypoint.S
index 453d2c1..25385ca 100644
--- a/bl32/tsp/aarch64/tsp_entrypoint.S
+++ b/bl32/tsp/aarch64/tsp_entrypoint.S
@@ -391,7 +391,7 @@
 
 	/* Should never reach here */
 tsp_sel1_int_entry_panic:
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 endfunc tsp_sel1_intr_entry
 
 	/*---------------------------------------------
@@ -409,7 +409,7 @@
 	restore_args_call_smc
 
 	/* Should never reach here */
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 endfunc tsp_cpu_resume_entry
 
 	/*---------------------------------------------
@@ -422,7 +422,7 @@
 	restore_args_call_smc
 
 	/* Should never reach here */
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 endfunc tsp_fast_smc_entry
 
 	/*---------------------------------------------
@@ -439,5 +439,5 @@
 	restore_args_call_smc
 
 	/* Should never reach here */
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 endfunc tsp_std_smc_entry
diff --git a/bl32/tsp/aarch64/tsp_exceptions.S b/bl32/tsp/aarch64/tsp_exceptions.S
index 20e40df..400d5c6 100644
--- a/bl32/tsp/aarch64/tsp_exceptions.S
+++ b/bl32/tsp/aarch64/tsp_exceptions.S
@@ -105,19 +105,19 @@
 	 * -----------------------------------------------------
 	 */
 vector_entry sync_exception_sp_el0
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size sync_exception_sp_el0
 
 vector_entry irq_sp_el0
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size irq_sp_el0
 
 vector_entry fiq_sp_el0
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size fiq_sp_el0
 
 vector_entry serror_sp_el0
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size serror_sp_el0
 
 
@@ -127,7 +127,7 @@
 	 * -----------------------------------------------------
 	 */
 vector_entry sync_exception_sp_elx
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size sync_exception_sp_elx
 
 vector_entry irq_sp_elx
@@ -139,7 +139,7 @@
 	check_vector_size fiq_sp_elx
 
 vector_entry serror_sp_elx
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size serror_sp_elx
 
 
@@ -149,19 +149,19 @@
 	 * -----------------------------------------------------
 	 */
 vector_entry sync_exception_aarch64
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size sync_exception_aarch64
 
 vector_entry irq_aarch64
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size irq_aarch64
 
 vector_entry fiq_aarch64
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size fiq_aarch64
 
 vector_entry serror_aarch64
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size serror_aarch64
 
 
@@ -171,17 +171,17 @@
 	 * -----------------------------------------------------
 	 */
 vector_entry sync_exception_aarch32
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size sync_exception_aarch32
 
 vector_entry irq_aarch32
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size irq_aarch32
 
 vector_entry fiq_aarch32
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size fiq_aarch32
 
 vector_entry serror_aarch32
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size serror_aarch32
diff --git a/common/aarch32/debug.S b/common/aarch32/debug.S
index 6be6951..cfce7ed 100644
--- a/common/aarch32/debug.S
+++ b/common/aarch32/debug.S
@@ -38,7 +38,7 @@
 	 * The common implementation of do_panic for all BL stages
 	 ***********************************************************/
 func do_panic
-	b	plat_panic_handler
+	no_ret	plat_panic_handler
 endfunc do_panic
 
 	/***********************************************************
@@ -50,5 +50,5 @@
 	mrs	r0, cpsr
 	and	r0, #MODE32_MASK
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 endfunc report_exception
diff --git a/common/aarch64/debug.S b/common/aarch64/debug.S
index d353879..9dd53ca 100644
--- a/common/aarch64/debug.S
+++ b/common/aarch64/debug.S
@@ -191,5 +191,5 @@
 	/* Pass to plat_panic_handler the address from where el3_panic was
 	 * called, not the address of the call from el3_panic. */
 	mov	x30,x6
-	b	plat_panic_handler
+	no_ret	plat_panic_handler
 endfunc do_panic
diff --git a/common/aarch64/early_exceptions.S b/common/aarch64/early_exceptions.S
index ad5b4d8..be21459 100644
--- a/common/aarch64/early_exceptions.S
+++ b/common/aarch64/early_exceptions.S
@@ -47,25 +47,25 @@
 vector_entry SynchronousExceptionSP0
 	mov	x0, #SYNC_EXCEPTION_SP_EL0
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size SynchronousExceptionSP0
 
 vector_entry IrqSP0
 	mov	x0, #IRQ_SP_EL0
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size IrqSP0
 
 vector_entry FiqSP0
 	mov	x0, #FIQ_SP_EL0
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size FiqSP0
 
 vector_entry SErrorSP0
 	mov	x0, #SERROR_SP_EL0
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size SErrorSP0
 
 	/* -----------------------------------------------------
@@ -75,25 +75,25 @@
 vector_entry SynchronousExceptionSPx
 	mov	x0, #SYNC_EXCEPTION_SP_ELX
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size SynchronousExceptionSPx
 
 vector_entry IrqSPx
 	mov	x0, #IRQ_SP_ELX
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size IrqSPx
 
 vector_entry FiqSPx
 	mov	x0, #FIQ_SP_ELX
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size FiqSPx
 
 vector_entry SErrorSPx
 	mov	x0, #SERROR_SP_ELX
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size SErrorSPx
 
 	/* -----------------------------------------------------
@@ -103,25 +103,25 @@
 vector_entry SynchronousExceptionA64
 	mov	x0, #SYNC_EXCEPTION_AARCH64
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size SynchronousExceptionA64
 
 vector_entry IrqA64
 	mov	x0, #IRQ_AARCH64
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size IrqA64
 
 vector_entry FiqA64
 	mov	x0, #FIQ_AARCH64
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size FiqA64
 
 vector_entry SErrorA64
 	mov	x0, #SERROR_AARCH64
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size SErrorA64
 
 	/* -----------------------------------------------------
@@ -131,23 +131,23 @@
 vector_entry SynchronousExceptionA32
 	mov	x0, #SYNC_EXCEPTION_AARCH32
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size SynchronousExceptionA32
 
 vector_entry IrqA32
 	mov	x0, #IRQ_AARCH32
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size IrqA32
 
 vector_entry FiqA32
 	mov	x0, #FIQ_AARCH32
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size FiqA32
 
 vector_entry SErrorA32
 	mov	x0, #SERROR_AARCH32
 	bl	plat_report_exception
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 	check_vector_size SErrorA32
diff --git a/include/common/aarch32/asm_macros.S b/include/common/aarch32/asm_macros.S
index 5f04499..23122f3 100644
--- a/include/common/aarch32/asm_macros.S
+++ b/include/common/aarch32/asm_macros.S
@@ -102,4 +102,26 @@
 	ldr r0, =(\_name + \_size)
 	.endm
 
+	/*
+	 * Macro to mark instances where we're jumping to a function and don't
+	 * expect a return. To provide the function being jumped to with
+	 * additional information, we use 'bl' instruction to jump rather than
+	 * 'b'.
+         *
+	 * Debuggers infer the location of a call from where LR points to, which
+	 * is usually the instruction after 'bl'. If this macro expansion
+	 * happens to be the last location in a function, that'll cause the LR
+	 * to point a location beyond the function, thereby misleading debugger
+	 * back trace. We therefore insert a 'nop' after the function call for
+	 * debug builds, unless 'skip_nop' parameter is non-zero.
+	 */
+	.macro no_ret _func:req, skip_nop=0
+	bl	\_func
+#if DEBUG
+	.ifeq \skip_nop
+	nop
+	.endif
+#endif
+	.endm
+
 #endif /* __ASM_MACROS_S__ */
diff --git a/include/common/aarch32/el3_common_macros.S b/include/common/aarch32/el3_common_macros.S
index 0018ea4..228d721 100644
--- a/include/common/aarch32/el3_common_macros.S
+++ b/include/common/aarch32/el3_common_macros.S
@@ -212,7 +212,7 @@
 		/* This is a cold boot on a secondary CPU */
 		bl	plat_secondary_cold_boot_setup
 		/* plat_secondary_cold_boot_setup() is not supposed to return */
-		bl	plat_panic_handler
+		no_ret	plat_panic_handler
 
 	do_primary_cold_boot:
 	.endif /* _secondary_cold_boot */
diff --git a/include/common/aarch64/asm_macros.S b/include/common/aarch64/asm_macros.S
index cc8f424..88e8d9c 100644
--- a/include/common/aarch64/asm_macros.S
+++ b/include/common/aarch64/asm_macros.S
@@ -178,4 +178,26 @@
 		.endif
 	.endm
 
+	/*
+	 * Macro to mark instances where we're jumping to a function and don't
+	 * expect a return. To provide the function being jumped to with
+	 * additional information, we use 'bl' instruction to jump rather than
+	 * 'b'.
+         *
+	 * Debuggers infer the location of a call from where LR points to, which
+	 * is usually the instruction after 'bl'. If this macro expansion
+	 * happens to be the last location in a function, that'll cause the LR
+	 * to point a location beyond the function, thereby misleading debugger
+	 * back trace. We therefore insert a 'nop' after the function call for
+	 * debug builds, unless 'skip_nop' parameter is non-zero.
+	 */
+	.macro no_ret _func:req, skip_nop=0
+	bl	\_func
+#if DEBUG
+	.ifeq \skip_nop
+	nop
+	.endif
+#endif
+	.endm
+
 #endif /* __ASM_MACROS_S__ */
diff --git a/lib/psci/aarch32/psci_helpers.S b/lib/psci/aarch32/psci_helpers.S
index 36d5d7d..27d651e 100644
--- a/lib/psci/aarch32/psci_helpers.S
+++ b/lib/psci/aarch32/psci_helpers.S
@@ -176,5 +176,5 @@
 func psci_power_down_wfi
 	dsb	sy		// ensure write buffer empty
 	wfi
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 endfunc psci_power_down_wfi
diff --git a/lib/psci/aarch64/psci_helpers.S b/lib/psci/aarch64/psci_helpers.S
index ff250a0..eaa17c7 100644
--- a/lib/psci/aarch64/psci_helpers.S
+++ b/lib/psci/aarch64/psci_helpers.S
@@ -167,7 +167,7 @@
 func psci_power_down_wfi
 	dsb	sy		// ensure write buffer empty
 	wfi
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 endfunc psci_power_down_wfi
 
 /* -----------------------------------------------------------------------
diff --git a/plat/arm/board/fvp/aarch64/fvp_helpers.S b/plat/arm/board/fvp/aarch64/fvp_helpers.S
index 6a7ad23..6508705 100644
--- a/plat/arm/board/fvp/aarch64/fvp_helpers.S
+++ b/plat/arm/board/fvp/aarch64/fvp_helpers.S
@@ -111,7 +111,7 @@
 	 */
 	dsb	sy
 	wfi
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 #else
 	mov_imm	x0, PLAT_ARM_TRUSTED_MAILBOX_BASE
 
@@ -182,7 +182,7 @@
 	 * ---------------------------------------------------------------------
 	 */
 _panic_handler:
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 endfunc plat_get_my_entrypoint
 
 	/* -----------------------------------------------------
diff --git a/plat/arm/board/juno/aarch64/juno_helpers.S b/plat/arm/board/juno/aarch64/juno_helpers.S
index 9291fa4..ac54ac9 100644
--- a/plat/arm/board/juno/aarch64/juno_helpers.S
+++ b/plat/arm/board/juno/aarch64/juno_helpers.S
@@ -201,7 +201,7 @@
 	JUMP_TO_HANDLER_IF_JUNO_R(2)
 
 	/* Board revision is not supported */
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 
 endfunc plat_reset_handler
 
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S b/plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S
index 0afed47..3139e67 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S
@@ -61,7 +61,7 @@
 	 */
 	dsb	sy
 1:
-	bl	plat_panic_handler
+	no_ret	plat_panic_handler
 endfunc plat_secondary_cold_boot_setup
 
 func plat_is_my_cpu_primary