From 9d7251918d338585f74a9122f904d1c0aafdf0f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bence=20Sz=C3=A9pk=C3=BAti?= <bence.szepkuti@arm.com>
Date: Thu, 24 Oct 2019 15:53:23 +0200
Subject: [PATCH] SiP: Don't validate entrypoint if state switch is impossible
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Switching execution states is only possible if EL3 is AArch64.
As such there is no need to validate the entrypoint on AArch32 builds.

Signed-off-by: Bence Szépkúti <bence.szepkuti@arm.com>
Change-Id: I3c1eb25b5df296a492870641d274bf65213c6608
---
 .../common/{ => aarch64}/execution_state_switch.c |  8 +++++---
 plat/arm/common/arm_common.mk                     |  6 ++++--
 plat/arm/common/arm_sip_svc.c                     | 15 +++++++--------
 3 files changed, 16 insertions(+), 13 deletions(-)
 rename plat/arm/common/{ => aarch64}/execution_state_switch.c (96%)

diff --git a/plat/arm/common/execution_state_switch.c b/plat/arm/common/aarch64/execution_state_switch.c
similarity index 96%
rename from plat/arm/common/execution_state_switch.c
rename to plat/arm/common/aarch64/execution_state_switch.c
index 00ac16ef0..8835fa135 100644
--- a/plat/arm/common/execution_state_switch.c
+++ b/plat/arm/common/aarch64/execution_state_switch.c
@@ -39,8 +39,6 @@ int arm_execution_state_switch(unsigned int smc_fid,
 		uint32_t cookie_lo,
 		void *handle)
 {
-	/* Execution state can be switched only if EL3 is AArch64 */
-#ifdef __aarch64__
 	bool caller_64, thumb = false, from_el2;
 	unsigned int el, endianness;
 	u_register_t spsr, pc, scr, sctlr;
@@ -48,6 +46,11 @@ int arm_execution_state_switch(unsigned int smc_fid,
 	cpu_context_t *ctx = (cpu_context_t *) handle;
 	el3_state_t *el3_ctx = get_el3state_ctx(ctx);
 
+	/* Validate supplied entry point */
+	pc = (u_register_t) (((uint64_t) pc_hi << 32) | pc_lo);
+	if (arm_validate_ns_entrypoint(pc) != 0)
+		goto invalid_param;
+
 	/* That the SMC originated from NS is already validated by the caller */
 
 	/*
@@ -173,7 +176,6 @@ invalid_param:
 	SMC_RET1(handle, STATE_SW_E_PARAM);
 
 exec_denied:
-#endif /* __aarch64__ */
 	/* State switch denied */
 	SMC_RET1(handle, STATE_SW_E_DENIED);
 }
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index acc379797..ccb851e9d 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -215,13 +215,15 @@ BL2U_SOURCES		+=	drivers/delay_timer/delay_timer.c		\
 BL31_SOURCES		+=	plat/arm/common/arm_bl31_setup.c		\
 				plat/arm/common/arm_pm.c			\
 				plat/arm/common/arm_topology.c			\
-				plat/arm/common/execution_state_switch.c	\
 				plat/common/plat_psci_common.c
 
 ifeq (${ENABLE_PMF}, 1)
-BL31_SOURCES		+=	plat/arm/common/arm_sip_svc.c			\
+ifeq (${ARCH}, aarch64)
+BL31_SOURCES		+=	plat/arm/common/aarch64/execution_state_switch.c\
+				plat/arm/common/arm_sip_svc.c			\
 				lib/pmf/pmf_smc.c
 endif
+endif
 
 ifeq (${EL3_EXCEPTION_HANDLING},1)
 BL31_SOURCES		+=	plat/arm/common/aarch64/arm_ehf.c
diff --git a/plat/arm/common/arm_sip_svc.c b/plat/arm/common/arm_sip_svc.c
index 3d308a335..a61f5f8bb 100644
--- a/plat/arm/common/arm_sip_svc.c
+++ b/plat/arm/common/arm_sip_svc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -50,23 +50,22 @@ static uintptr_t arm_sip_handler(unsigned int smc_fid,
 
 	switch (smc_fid) {
 	case ARM_SIP_SVC_EXE_STATE_SWITCH: {
-		u_register_t pc;
-
+		/* Execution state can be switched only if EL3 is AArch64 */
+#ifdef __aarch64__
 		/* Allow calls from non-secure only */
 		if (!is_caller_non_secure(flags))
 			SMC_RET1(handle, STATE_SW_E_DENIED);
 
-		/* Validate supplied entry point */
-		pc = (u_register_t) ((x1 << 32) | (uint32_t) x2);
-		if (arm_validate_ns_entrypoint(pc) != 0)
-			SMC_RET1(handle, STATE_SW_E_PARAM);
-
 		/*
 		 * Pointers used in execution state switch are all 32 bits wide
 		 */
 		return (uintptr_t) arm_execution_state_switch(smc_fid,
 				(uint32_t) x1, (uint32_t) x2, (uint32_t) x3,
 				(uint32_t) x4, handle);
+#else
+		/* State switch denied */
+		SMC_RET1(handle, STATE_SW_E_DENIED);
+#endif /* __aarch64__ */
 		}
 
 	case ARM_SIP_SVC_CALL_COUNT:
-- 
GitLab