From 033039f8e5ad0ff231261e316f27bf22bc5713a2 Mon Sep 17 00:00:00 2001 From: Max Shvetsov Date: Tue, 25 Feb 2020 13:55:00 +0000 Subject: [PATCH] SPMD: add command line parameter to run SPM at S-EL2 or S-EL1 Added SPMD_SPM_AT_SEL2 build command line parameter. Set to 1 to run SPM at S-EL2. Set to 0 to run SPM at S-EL1 (pre-v8.4 or S-EL2 is disabled). Removed runtime EL from SPM core manifest. Change-Id: Icb4f5ea4c800f266880db1d410d63fe27a1171c0 Signed-off-by: Artsem Artsemenka Signed-off-by: Max Shvetsov --- Makefile | 9 ++- include/services/spm_core_manifest.h | 7 --- make_helpers/defaults.mk | 3 + plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts | 1 - plat/common/plat_spmd_manifest.c | 7 --- services/std_svc/spmd/spmd_main.c | 61 +++++++++---------- 6 files changed, 39 insertions(+), 49 deletions(-) diff --git a/Makefile b/Makefile index a84c413b8..f3cb9be6b 100644 --- a/Makefile +++ b/Makefile @@ -422,11 +422,14 @@ ifneq (${SPD},none) endif ifeq (${SPD},spmd) + $(warning "SPMD is an experimental feature") # SPMD is located in std_svc directory SPD_DIR := std_svc - ifeq ($(CTX_INCLUDE_EL2_REGS),0) - $(error spmd requires CTX_INCLUDE_EL2_REGS option) + ifeq ($(SPMD_SPM_AT_SEL2),1) + ifeq ($(CTX_INCLUDE_EL2_REGS),0) + $(error SPMD with SPM at S-EL2 requires CTX_INCLUDE_EL2_REGS option) + endif endif else # All other SPDs in spd directory @@ -799,6 +802,7 @@ $(eval $(call assert_boolean,SEPARATE_CODE_AND_RODATA)) $(eval $(call assert_boolean,SEPARATE_NOBITS_REGION)) $(eval $(call assert_boolean,SPIN_ON_BL1_EXIT)) $(eval $(call assert_boolean,SPM_MM)) +$(eval $(call assert_boolean,SPMD_SPM_AT_SEL2)) $(eval $(call assert_boolean,TRUSTED_BOARD_BOOT)) $(eval $(call assert_boolean,USE_COHERENT_MEM)) $(eval $(call assert_boolean,USE_DEBUGFS)) @@ -870,6 +874,7 @@ $(eval $(call add_define,RECLAIM_INIT_CODE)) $(eval $(call add_define,SPD_${SPD})) $(eval $(call add_define,SPIN_ON_BL1_EXIT)) $(eval $(call add_define,SPM_MM)) +$(eval $(call add_define,SPMD_SPM_AT_SEL2)) $(eval $(call add_define,TRUSTED_BOARD_BOOT)) $(eval $(call add_define,USE_COHERENT_MEM)) $(eval $(call add_define,USE_DEBUGFS)) diff --git a/include/services/spm_core_manifest.h b/include/services/spm_core_manifest.h index 06ecc1391..78748826d 100644 --- a/include/services/spm_core_manifest.h +++ b/include/services/spm_core_manifest.h @@ -20,13 +20,6 @@ typedef struct spm_core_manifest_sect_attribute { uint32_t major_version; uint32_t minor_version; - /* - * Run-Time Exception Level (mandatory): - * - 1: SEL1 - * - 2: SEL2 - */ - uint32_t runtime_el; - /* * Run-Time Execution state (optional): * - 0: AArch64 (default) diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 8e1f273a3..9273469e2 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -188,6 +188,9 @@ SPD := none # Enable the Management Mode (MM)-based Secure Partition Manager implementation SPM_MM := 0 +# Use SPM at S-EL2 as a default config for SPMD +SPMD_SPM_AT_SEL2 := 1 + # Flag to introduce an infinite loop in BL1 just before it exits into the next # image. This is meant to help debugging the post-BL2 phase. SPIN_ON_BL1_EXIT := 0 diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts index e1c106f1e..c94a209fd 100644 --- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts +++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts @@ -11,7 +11,6 @@ attribute { maj_ver = <0x0>; min_ver = <0x9>; - runtime_el = <0x1>; exec_state = <0x0>; load_address = <0x0 0x6000000>; entrypoint = <0x0 0x6000000>; diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c index 4c789795e..9c3dc7177 100644 --- a/plat/common/plat_spmd_manifest.c +++ b/plat/common/plat_spmd_manifest.c @@ -37,12 +37,6 @@ static int manifest_parse_attribute(spmc_manifest_sect_attribute_t *attr, return -ENOENT; } - rc = fdtw_read_cells(fdt, node, "runtime_el", 1, &attr->runtime_el); - if (rc) { - ERROR("Missing SPM core runtime EL in manifest.\n"); - return -ENOENT; - } - rc = fdtw_read_cells(fdt, node, "exec_state", 1, &attr->exec_state); if (rc) NOTICE("Execution state not specified in SPM core manifest.\n"); @@ -61,7 +55,6 @@ static int manifest_parse_attribute(spmc_manifest_sect_attribute_t *attr, VERBOSE("SPM core manifest attribute section:\n"); VERBOSE(" version: %x.%x\n", attr->major_version, attr->minor_version); - VERBOSE(" runtime_el: 0x%x\n", attr->runtime_el); VERBOSE(" binary_size: 0x%x\n", attr->binary_size); VERBOSE(" load_address: 0x%llx\n", attr->load_address); VERBOSE(" entrypoint: 0x%llx\n", attr->entrypoint); diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index f49d23610..2cdf4f5ff 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -65,19 +65,19 @@ uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *spmc_ctx) /* Restore the context assigned above */ cm_el1_sysregs_context_restore(SECURE); +#if SPMD_SPM_AT_SEL2 cm_el2_sysregs_context_restore(SECURE); +#endif cm_set_next_eret_context(SECURE); - /* Invalidate TLBs at EL1. */ - tlbivmalle1(); - dsbish(); - - /* Enter Secure Partition */ + /* Enter SPMC */ rc = spmd_spm_core_enter(&spmc_ctx->c_rt_ctx); /* Save secure state */ cm_el1_sysregs_context_save(SECURE); +#if SPMD_SPM_AT_SEL2 cm_el2_sysregs_context_save(SECURE); +#endif return rc; } @@ -159,16 +159,8 @@ static int spmd_spmc_init(void *rd_base, size_t rd_size) INFO("SPCI version (%x.%x).\n", spmc_attrs.major_version, spmc_attrs.minor_version); - /* Validate the SPM core runtime EL */ - if ((spmc_attrs.runtime_el != MODE_EL1) && - (spmc_attrs.runtime_el != MODE_EL2)) { - WARN("Unsupported SPM core run time EL%x specified in " - "manifest image provided by BL2 boot loader.\n", - spmc_attrs.runtime_el); - return 1; - } - - INFO("SPM core run time EL%x.\n", spmc_attrs.runtime_el); + INFO("SPM core run time EL%x.\n", + SPMD_SPM_AT_SEL2 ? MODE_EL2 : MODE_EL1); /* Validate the SPM core execution state */ if ((spmc_attrs.exec_state != MODE_RW_64) && @@ -181,12 +173,10 @@ static int spmd_spmc_init(void *rd_base, size_t rd_size) INFO("SPM core execution state %x.\n", spmc_attrs.exec_state); - /* Ensure manifest has not requested S-EL2 in AArch32 state */ - if ((spmc_attrs.exec_state == MODE_RW_32) && - (spmc_attrs.runtime_el == MODE_EL2)) { - WARN("Invalid combination of SPM core execution state (%x) " - "and run time EL (%x).\n", spmc_attrs.exec_state, - spmc_attrs.runtime_el); +#if SPMD_SPM_AT_SEL2 + /* Ensure manifest has not requested AArch32 state in S-EL2 */ + if (spmc_attrs.exec_state == MODE_RW_32) { + WARN("AArch32 state at S-EL2 is not supported.\n"); return 1; } @@ -194,19 +184,16 @@ static int spmd_spmc_init(void *rd_base, size_t rd_size) * Check if S-EL2 is supported on this system if S-EL2 * is required for SPM */ - if (spmc_attrs.runtime_el == MODE_EL2) { - uint64_t sel2 = read_id_aa64pfr0_el1(); + uint64_t sel2 = read_id_aa64pfr0_el1(); - sel2 >>= ID_AA64PFR0_SEL2_SHIFT; - sel2 &= ID_AA64PFR0_SEL2_MASK; + sel2 >>= ID_AA64PFR0_SEL2_SHIFT; + sel2 &= ID_AA64PFR0_SEL2_MASK; - if (!sel2) { - WARN("SPM core run time EL: S-EL%x is not supported " - "but specified in manifest image provided by " - "BL2 boot loader.\n", spmc_attrs.runtime_el); - return 1; - } + if (!sel2) { + WARN("SPM core run time S-EL2 is not supported."); + return 1; } +#endif /* SPMD_SPM_AT_SEL2 */ /* Initialise an entrypoint to set up the CPU context */ ep_attr = SECURE | EP_ST_ENABLE; @@ -228,7 +215,13 @@ static int spmd_spmc_init(void *rd_base, size_t rd_size) DAIF_IRQ_BIT | DAIF_ABT_BIT); } else { - spmc_ep_info->spsr = SPSR_64(spmc_attrs.runtime_el, + +#if SPMD_SPM_AT_SEL2 + static const uint32_t runtime_el = MODE_EL2; +#else + static const uint32_t runtime_el = MODE_EL1; +#endif + spmc_ep_info->spsr = SPSR_64(runtime_el, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); } @@ -332,11 +325,15 @@ static uint64_t spmd_smc_forward(uint32_t smc_fid, bool secure_origin, /* Save incoming security state */ cm_el1_sysregs_context_save(secure_state_in); +#if SPMD_SPM_AT_SEL2 cm_el2_sysregs_context_save(secure_state_in); +#endif /* Restore outgoing security state */ cm_el1_sysregs_context_restore(secure_state_out); +#if SPMD_SPM_AT_SEL2 cm_el2_sysregs_context_restore(secure_state_out); +#endif cm_set_next_eret_context(secure_state_out); SMC_RET8(cm_get_context(secure_state_out), smc_fid, x1, x2, x3, x4,