From 781f4aac76b56c059bb70b06b71a5c8ef2211844 Mon Sep 17 00:00:00 2001 From: Jeenu Viswambharan <jeenu.viswambharan@arm.com> Date: Thu, 19 Oct 2017 09:15:15 +0100 Subject: [PATCH] ARM platforms: Provide SDEI entry point validation Provide a strong definition for plat_sdei_validate_sdei_entrypoint() which translates client address to Physical Address, and then validating the address to be present in DRAM. Change-Id: Ib93eb66b413d638aa5524d1b3de36aa16d38ea11 Signed-off-by: Jeenu Viswambharan <jeenu.viswambharan@arm.com> --- include/lib/aarch64/arch.h | 6 ++++ include/lib/aarch64/arch_helpers.h | 1 + plat/arm/common/arm_common.c | 48 ++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h index 16d12a383..cb7dab7ff 100644 --- a/include/lib/aarch64/arch.h +++ b/include/lib/aarch64/arch.h @@ -598,4 +598,10 @@ #define MAKE_MAIR_NORMAL_MEMORY(inner, outer) ((inner) | ((outer) << MAIR_NORM_OUTER_SHIFT)) +/* PAR_EL1 fields */ +#define PAR_F_SHIFT 0 +#define PAR_F_MASK 1 +#define PAR_ADDR_SHIFT 12 +#define PAR_ADDR_MASK (BIT(40) - 1) /* 40-bits-wide page address */ + #endif /* __ARCH_H__ */ diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h index 9c022ab5e..782343d67 100644 --- a/include/lib/aarch64/arch_helpers.h +++ b/include/lib/aarch64/arch_helpers.h @@ -155,6 +155,7 @@ DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e1r) DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e1w) DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e0r) DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e0w) +DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e2r) void flush_dcache_range(uintptr_t addr, size_t size); void clean_dcache_range(uintptr_t addr, size_t size); diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c index 1905c0b05..bf6397377 100644 --- a/plat/arm/common/arm_common.c +++ b/plat/arm/common/arm_common.c @@ -204,3 +204,51 @@ unsigned int plat_get_syscnt_freq2(void) } #endif /* ARM_SYS_CNTCTL_BASE */ + +#if SDEI_SUPPORT +/* + * Translate SDEI entry point to PA, and perform standard ARM entry point + * validation on it. + */ +int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode) +{ + uint64_t par, pa; + uint32_t scr_el3; + + /* Doing Non-secure address translation requires SCR_EL3.NS set */ + scr_el3 = read_scr_el3(); + write_scr_el3(scr_el3 | SCR_NS_BIT); + isb(); + + assert((client_mode == MODE_EL2) || (client_mode == MODE_EL1)); + if (client_mode == MODE_EL2) { + /* + * Translate entry point to Physical Address using the EL2 + * translation regime. + */ + ats1e2r(ep); + } else { + /* + * Translate entry point to Physical Address using the EL1&0 + * translation regime, including stage 2. + */ + ats12e1r(ep); + } + isb(); + par = read_par_el1(); + + /* Restore original SCRL_EL3 */ + write_scr_el3(scr_el3); + isb(); + + /* If the translation resulted in fault, return failure */ + if ((par & PAR_F_MASK) != 0) + return -1; + + /* Extract Physical Address from PAR */ + pa = (par & (PAR_ADDR_MASK << PAR_ADDR_SHIFT)); + + /* Perform NS entry point validation on the physical address */ + return arm_validate_ns_entrypoint(pa); +} +#endif -- GitLab