core: arm32: bugfix booting second cpu with ASLR

Fixes crashing second cpu when booting with ASLR enabled.

Fixes: 170e9084a84f ("core: add support for CFG_CORE_ASLR")
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
Tested-by: Etienne Carriere <etienne.carriere@linaro.org> (b2260)
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
diff --git a/core/arch/arm/kernel/generic_entry_a32.S b/core/arch/arm/kernel/generic_entry_a32.S
index 4ebacef..45111e7 100644
--- a/core/arch/arm/kernel/generic_entry_a32.S
+++ b/core/arch/arm/kernel/generic_entry_a32.S
@@ -77,9 +77,9 @@
 KEEP_PAGER plat_cpu_reset_early
 .weak plat_cpu_reset_early
 
-	.section .text.reset_vect_table
+	.section .identity_map, "ax"
 	.align 5
-LOCAL_FUNC reset_vect_table , :
+LOCAL_FUNC reset_vect_table , : , .identity_map
 	b	.
 	b	.	/* Undef */
 	b	.	/* Syscall */
@@ -264,12 +264,34 @@
 		cmp	r0, #CFG_TEE_CORE_NB_CORE
 		/* Unsupported CPU, park it before it breaks something */
 		bge	unhandled_cpu
-		ldr	r1, =stack_tmp_stride
-		ldr	r1, [r1]
+
+		/*
+		 * stack_tmp_stride and stack_tmp_stride_rel are the
+		 * equivalent of:
+		 * extern const u32 stack_tmp_stride;
+		 * u32 stack_tmp_stride_rel = (u32)&stack_tmp_stride -
+		 *			      (u32)&stack_tmp_stride_rel 
+		 *
+		 * To load the value of stack_tmp_stride we do the equivalent
+		 * of:
+		 * *(u32 *)(stack_tmp_stride + (u32)&stack_tmp_stride_rel)
+		 */
+		adr	r3, stack_tmp_stride_rel
+		ldr	r1, [r3]
+		ldr	r1, [r1, r3]
+
+		/* Same pattern as for stack_tmp_stride above */
+		adr	r3, stack_tmp_export_rel
+		ldr	r2, [r3]
+		ldr	r2, [r2, r3]
+
+		/*
+		 * r0 is core pos
+		 * r1 is value of stack_tmp_stride
+		 * r2 is value of stack_tmp_export
+		 */
 		mul	r1, r0, r1
-		ldr	r0, =stack_tmp_export
-		ldr	r0, [r0]
-		add	sp, r1, r0
+		add	sp, r1, r2
 	.endm
 
 	/*
@@ -324,7 +346,7 @@
 #define flush_cpu_semaphores
 #endif
 
-LOCAL_FUNC reset_primary , :, .identity_map
+LOCAL_FUNC reset_primary , : , .identity_map
 UNWIND(	.fnstart)
 UNWIND(	.cantunwind)
 
@@ -726,12 +748,20 @@
 	bx	lr
 END_FUNC enable_mmu
 
+LOCAL_DATA stack_tmp_export_rel , :
+	.word	stack_tmp_export - stack_tmp_export_rel
+END_DATA stack_tmp_export_rel
+
+LOCAL_DATA stack_tmp_stride_rel , :
+	.word	stack_tmp_stride - stack_tmp_stride_rel
+END_DATA stack_tmp_stride_rel
+
 DATA boot_mmu_config , : /* struct core_mmu_config */
 	.skip	CORE_MMU_CONFIG_SIZE
 END_DATA boot_mmu_config
 
 #if defined(CFG_WITH_ARM_TRUSTED_FW)
-FUNC cpu_on_handler , :
+FUNC cpu_on_handler , : , .identity_map
 UNWIND(	.fnstart)
 UNWIND(	.cantunwind)
 	mov	r4, r0
@@ -741,7 +771,7 @@
 	set_sctlr
 	isb
 
-	ldr	r0, =reset_vect_table
+	adr	r0, reset_vect_table
 	write_vbar r0
 
 	mov	r4, lr
@@ -765,12 +795,23 @@
 LOCAL_FUNC reset_secondary , : , .identity_map
 UNWIND(	.fnstart)
 UNWIND(	.cantunwind)
-	ldr	r0, =reset_vect_table
+	adr	r0, reset_vect_table
 	write_vbar r0
 
 	wait_primary
 
 	set_sp
+#ifdef CFG_CORE_ASLR
+	/*
+	 * stack_tmp_export which is used as base when initializing sp has
+	 * been relocated to the new offset. Since MMU isn't enabled on
+	 * this CPU yet we need to restore the corresponding physical
+	 * address.
+	 */
+	adr	r0, boot_mmu_config
+	ldr	r0, [r0, #CORE_MMU_CONFIG_LOAD_OFFSET]
+	sub	sp, sp, r0
+#endif
 
 #if defined (CFG_BOOT_SECONDARY_REQUEST)
 	/* if L1 is not invalidated before, do it here */
diff --git a/core/arch/arm/kernel/thread.c b/core/arch/arm/kernel/thread.c
index e41cddc..cf2d2a6 100644
--- a/core/arch/arm/kernel/thread.c
+++ b/core/arch/arm/kernel/thread.c
@@ -104,9 +104,11 @@
 DECLARE_STACK(stack_thread, CFG_NUM_THREADS, STACK_THREAD_SIZE, static);
 #endif
 
-const void *stack_tmp_export = (uint8_t *)stack_tmp + sizeof(stack_tmp[0]) -
-			       (STACK_TMP_OFFS + STACK_CANARY_SIZE / 2);
-const uint32_t stack_tmp_stride = sizeof(stack_tmp[0]);
+const void *stack_tmp_export __section(".identity_map.stack_tmp_export") =
+	(uint8_t *)stack_tmp + sizeof(stack_tmp[0]) -
+	(STACK_TMP_OFFS + STACK_CANARY_SIZE / 2);
+const uint32_t stack_tmp_stride __section(".identity_map.stack_tmp_stride") =
+	sizeof(stack_tmp[0]);
 
 /*
  * These stack setup info are required by secondary boot cores before they