Add exception vector guards

This patch adds guards so that an exception vector exceeding 32
instructions will generate a compile-time error. This keeps the
exception handlers in check from spilling over.

Change-Id: I7aa56dd0071a333664e2814c656d3896032046fe
diff --git a/bl1/aarch64/early_exceptions.S b/bl1/aarch64/early_exceptions.S
index 84bdae1..d06e854 100644
--- a/bl1/aarch64/early_exceptions.S
+++ b/bl1/aarch64/early_exceptions.S
@@ -33,6 +33,7 @@
 #include <bl1.h>
 #include <platform.h>
 #include <runtime_svc.h>
+#include <asm_macros.S>
 
 	.globl	early_exceptions
 	.weak	display_boot_progress
@@ -55,24 +56,28 @@
 	mov	x0, #SYNC_EXCEPTION_SP_EL0
 	bl	plat_report_exception
 	b	SynchronousExceptionSP0
+	check_vector_size SynchronousExceptionSP0
 
 	.align	7
 IrqSP0:
 	mov	x0, #IRQ_SP_EL0
 	bl	plat_report_exception
 	b	IrqSP0
+	check_vector_size IrqSP0
 
 	.align	7
 FiqSP0:
 	mov	x0, #FIQ_SP_EL0
 	bl	plat_report_exception
 	b	FiqSP0
+	check_vector_size FiqSP0
 
 	.align	7
 SErrorSP0:
 	mov	x0, #SERROR_SP_EL0
 	bl	plat_report_exception
 	b	SErrorSP0
+	check_vector_size SErrorSP0
 
 	/* -----------------------------------------------------
 	 * Current EL with SPx: 0x200 - 0x380
@@ -83,24 +88,28 @@
 	mov	x0, #SYNC_EXCEPTION_SP_ELX
 	bl	plat_report_exception
 	b	SynchronousExceptionSPx
+	check_vector_size SynchronousExceptionSPx
 
 	.align	7
 IrqSPx:
 	mov	x0, #IRQ_SP_ELX
 	bl	plat_report_exception
 	b	IrqSPx
+	check_vector_size IrqSPx
 
 	.align	7
 FiqSPx:
 	mov	x0, #FIQ_SP_ELX
 	bl	plat_report_exception
 	b	FiqSPx
+	check_vector_size FiqSPx
 
 	.align	7
 SErrorSPx:
 	mov	x0, #SERROR_SP_ELX
 	bl	plat_report_exception
 	b	SErrorSPx
+	check_vector_size SErrorSPx
 
 	/* -----------------------------------------------------
 	 * Lower EL using AArch64 : 0x400 - 0x580
@@ -115,24 +124,28 @@
 	 * ---------------------------------------------
 	 */
 	b	process_exception
+	check_vector_size SynchronousExceptionA64
 
 	.align	7
 IrqA64:
 	mov	x0, #IRQ_AARCH64
 	bl	plat_report_exception
 	b	IrqA64
+	check_vector_size IrqA64
 
 	.align	7
 FiqA64:
 	mov	x0, #FIQ_AARCH64
 	bl	plat_report_exception
 	b	FiqA64
+	check_vector_size FiqA64
 
 	.align	7
 SErrorA64:
 	mov	x0, #SERROR_AARCH64
 	bl	plat_report_exception
 	b   	SErrorA64
+	check_vector_size SErrorA64
 
 	/* -----------------------------------------------------
 	 * Lower EL using AArch32 : 0x0 - 0x180
@@ -143,24 +156,28 @@
 	mov	x0, #SYNC_EXCEPTION_AARCH32
 	bl	plat_report_exception
 	b	SynchronousExceptionA32
+	check_vector_size SynchronousExceptionA32
 
 	.align	7
 IrqA32:
 	mov	x0, #IRQ_AARCH32
 	bl	plat_report_exception
 	b	IrqA32
+	check_vector_size IrqA32
 
 	.align	7
 FiqA32:
 	mov	x0, #FIQ_AARCH32
 	bl	plat_report_exception
 	b	FiqA32
+	check_vector_size FiqA32
 
 	.align	7
 SErrorA32:
 	mov	x0, #SERROR_AARCH32
 	bl	plat_report_exception
 	b	SErrorA32
+	check_vector_size SErrorA32
 
 	.align	7
 
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index 10e65dc..870c274 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -32,6 +32,7 @@
 #include <runtime_svc.h>
 #include <platform.h>
 #include <context.h>
+#include "asm_macros.S"
 #include "cm_macros.S"
 
 	.globl	runtime_exceptions
@@ -53,6 +54,7 @@
 	 */
 	wfi
 	b	sync_exception_sp_el0
+	check_vector_size sync_exception_sp_el0
 
 	.align	7
 	/* -----------------------------------------------------
@@ -63,16 +65,19 @@
 irq_sp_el0:
 	handle_async_exception IRQ_SP_EL0
 	b	irq_sp_el0
+	check_vector_size irq_sp_el0
 
 	.align	7
 fiq_sp_el0:
 	handle_async_exception FIQ_SP_EL0
 	b	fiq_sp_el0
+	check_vector_size fiq_sp_el0
 
 	.align	7
 serror_sp_el0:
 	handle_async_exception SERROR_SP_EL0
 	b	serror_sp_el0
+	check_vector_size serror_sp_el0
 
 	/* -----------------------------------------------------
 	 * Current EL with SPx: 0x200 - 0x380
@@ -93,6 +98,7 @@
 	 */
 	wfi
 	b	sync_exception_sp_elx
+	check_vector_size sync_exception_sp_elx
 
 	/* -----------------------------------------------------
 	 * As mentioned in the previous comment, all bets are
@@ -103,12 +109,17 @@
 	.align	7
 irq_sp_elx:
 	b	irq_sp_elx
+	check_vector_size irq_sp_elx
+
 	.align	7
 fiq_sp_elx:
 	b	fiq_sp_elx
+	check_vector_size fiq_sp_elx
+
 	.align	7
 serror_sp_elx:
 	b	serror_sp_elx
+	check_vector_size serror_sp_elx
 
 	/* -----------------------------------------------------
 	 * Lower EL using AArch64 : 0x400 - 0x580
@@ -125,6 +136,7 @@
 	 * -----------------------------------------------------
 	 */
 	handle_sync_exception
+	check_vector_size sync_exception_aarch64
 
 	.align	7
 	/* -----------------------------------------------------
@@ -135,16 +147,19 @@
 irq_aarch64:
 	handle_async_exception IRQ_AARCH64
 	b	irq_aarch64
+	check_vector_size irq_aarch64
 
 	.align	7
 fiq_aarch64:
 	handle_async_exception FIQ_AARCH64
 	b	fiq_aarch64
+	check_vector_size fiq_aarch64
 
 	.align	7
 serror_aarch64:
 	handle_async_exception SERROR_AARCH64
 	b	serror_aarch64
+	check_vector_size serror_aarch64
 
 	/* -----------------------------------------------------
 	 * Lower EL using AArch32 : 0x600 - 0x780
@@ -161,6 +176,7 @@
 	 * -----------------------------------------------------
 	 */
 	handle_sync_exception
+	check_vector_size sync_exception_aarch32
 
 	.align	7
 	/* -----------------------------------------------------
@@ -171,16 +187,20 @@
 irq_aarch32:
 	handle_async_exception IRQ_AARCH32
 	b	irq_aarch32
+	check_vector_size irq_aarch32
 
 	.align	7
 fiq_aarch32:
 	handle_async_exception FIQ_AARCH32
 	b	fiq_aarch32
+	check_vector_size fiq_aarch32
 
 	.align	7
 serror_aarch32:
 	handle_async_exception SERROR_AARCH32
 	b	serror_aarch32
+	check_vector_size serror_aarch32
+
 	.align	7
 
 	.section	.text, "ax"
diff --git a/include/asm_macros.S b/include/asm_macros.S
index decef0b..f94d75f 100644
--- a/include/asm_macros.S
+++ b/include/asm_macros.S
@@ -68,3 +68,15 @@
 	ubfx	\end_level, \clidr, \shift, \fw
 	lsl	\end_level, \end_level, \ls
 	.endm
+
+	/*
+	 * This macro verifies that the a given vector doesn't exceed the
+	 * architectural limit of 32 instructions. This is meant to be placed
+	 * immedately after the last instruction in the vector. It takes the
+	 * vector entry as the parameter
+	 */
+	.macro check_vector_size since
+	  .if (. - \since) > (32 * 4)
+	    .error "Vector exceeds 32 instructions"
+	  .endif
+	.endm