From 990d972f1bd7c0c26102fa9876e5baabf648d4f5 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Fri, 31 Jul 2020 16:15:16 +0100 Subject: [PATCH 1/3] plat/arm: enable support for Plat owned SPs For Arm platforms SPs are loaded by parsing tb_fw_config.dts and adding them to SP structure sequentially, which in-turn is appended to loadable image list. With recently introduced dualroot CoT for SPs where they are owned either by SiP or by Platform. SiP owned SPs index starts at SP_PKG1_ID and Plat owned SPs index starts at SP_PKG5_ID. As the start index of SP depends on the owner, there should be a mechanism to parse owner of a SP and put it at the correct index in SP structure. This patch adds support for parsing a new optional field "owner" and based on it put SP details(UUID & Load-address) at the correct index in SP structure. Change-Id: Ibd255b60d5c45023cc7fdb10971bef6626cb560b Signed-off-by: Manish Pandey --- include/plat/arm/common/fconf_arm_sp_getter.h | 2 + plat/arm/common/fconf/arm_fconf_io.c | 9 ++- plat/arm/common/fconf/arm_fconf_sp.c | 76 ++++++++++++++----- 3 files changed, 66 insertions(+), 21 deletions(-) diff --git a/include/plat/arm/common/fconf_arm_sp_getter.h b/include/plat/arm/common/fconf_arm_sp_getter.h index 236254bd2..c6315bee2 100644 --- a/include/plat/arm/common/fconf_arm_sp_getter.h +++ b/include/plat/arm/common/fconf_arm_sp_getter.h @@ -14,11 +14,13 @@ #define arm__sp_getter(prop) arm_sp.prop #define ARM_SP_MAX_SIZE U(0x80000) +#define ARM_SP_OWNER_NAME_LEN U(8) struct arm_sp_t { unsigned int number_of_sp; union uuid_helper_t uuids[MAX_SP_IDS]; uintptr_t load_addr[MAX_SP_IDS]; + char owner[MAX_SP_IDS][ARM_SP_OWNER_NAME_LEN]; }; int fconf_populate_arm_sp(uintptr_t config); diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c index 350ecd1b6..5f125d3d5 100644 --- a/plat/arm/common/fconf/arm_fconf_io.c +++ b/plat/arm/common/fconf/arm_fconf_io.c @@ -52,6 +52,7 @@ const io_uuid_spec_t arm_uuid_spec[MAX_NUMBER_IDS] = { [NON_TRUSTED_FW_CONTENT_CERT_ID] = {UUID_NON_TRUSTED_FW_CONTENT_CERT}, #if defined(SPD_spmd) [SIP_SP_CONTENT_CERT_ID] = {UUID_SIP_SECURE_PARTITION_CONTENT_CERT}, + [PLAT_SP_CONTENT_CERT_ID] = {UUID_PLAT_SECURE_PARTITION_CONTENT_CERT}, #endif #endif /* ARM_IO_IN_DTB */ #endif /* TRUSTED_BOARD_BOOT */ @@ -189,6 +190,11 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = { (uintptr_t)&arm_uuid_spec[SIP_SP_CONTENT_CERT_ID], open_fip }, + [PLAT_SP_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[PLAT_SP_CONTENT_CERT_ID], + open_fip + }, #endif #endif /* ARM_IO_IN_DTB */ #endif /* TRUSTED_BOARD_BOOT */ @@ -197,7 +203,7 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = { #ifdef IMAGE_BL2 #if TRUSTED_BOARD_BOOT -#define FCONF_ARM_IO_UUID_NUMBER U(20) +#define FCONF_ARM_IO_UUID_NUMBER U(21) #else #define FCONF_ARM_IO_UUID_NUMBER U(10) #endif @@ -234,6 +240,7 @@ static const struct policies_load_info load_info[FCONF_ARM_IO_UUID_NUMBER] = { {NON_TRUSTED_FW_CONTENT_CERT_ID, "nt_fw_content_cert_uuid"}, #if defined(SPD_spmd) {SIP_SP_CONTENT_CERT_ID, "sip_sp_content_cert_uuid"}, + {PLAT_SP_CONTENT_CERT_ID, "plat_sp_content_cert_uuid"}, #endif #endif /* TRUSTED_BOARD_BOOT */ }; diff --git a/plat/arm/common/fconf/arm_fconf_sp.c b/plat/arm/common/fconf/arm_fconf_sp.c index 4459264c7..50a9dd4d5 100644 --- a/plat/arm/common/fconf/arm_fconf_sp.c +++ b/plat/arm/common/fconf/arm_fconf_sp.c @@ -30,7 +30,13 @@ int fconf_populate_arm_sp(uintptr_t config) union uuid_helper_t uuid_helper; unsigned int index = 0; uint32_t val32; - const unsigned int sp_start_index = SP_PKG1_ID; + bool is_plat_owned = false; + const unsigned int sip_start = SP_PKG1_ID; + unsigned int sip_index = sip_start; + const unsigned int sip_end = sip_start + MAX_SP_IDS / 2; + const unsigned int plat_start = SP_PKG5_ID; + unsigned int plat_index = plat_start; + const unsigned int plat_end = plat_start + MAX_SP_IDS / 2; /* As libfdt use void *, we can't avoid this cast */ const void *dtb = (void *)config; @@ -45,27 +51,20 @@ int fconf_populate_arm_sp(uintptr_t config) } fdt_for_each_subnode(sp_node, dtb, node) { - if (index == MAX_SP_IDS) { + if ((index == MAX_SP_IDS) || (sip_index == sip_end) + || (plat_index == plat_end)) { ERROR("FCONF: Reached max number of SPs\n"); return -1; } + /* Read UUID */ err = fdt_read_uint32_array(dtb, sp_node, "uuid", 4, uuid_helper.word); if (err < 0) { ERROR("FCONF: cannot read SP uuid\n"); return -1; } - arm_sp.uuids[index] = uuid_helper; - - err = fdt_read_uint32(dtb, sp_node, "load-address", &val32); - if (err < 0) { - ERROR("FCONF: cannot read SP load address\n"); - return -1; - } - arm_sp.load_addr[index] = val32; - VERBOSE("FCONF: %s UUID %x-%x-%x-%x load_addr=%lx\n", __func__, uuid_helper.word[0], @@ -74,8 +73,52 @@ int fconf_populate_arm_sp(uintptr_t config) uuid_helper.word[3], arm_sp.load_addr[index]); - /* Add SP information in mem param descriptor */ - sp_mem_params_descs[index].image_id = sp_start_index + index; + /* Read Load address */ + err = fdt_read_uint32(dtb, sp_node, "load-address", &val32); + if (err < 0) { + ERROR("FCONF: cannot read SP load address\n"); + return -1; + } + arm_sp.load_addr[index] = val32; + + /* Read owner field only for dualroot CoT */ +#if defined(ARM_COT_dualroot) + /* Owner is an optional field, no need to catch error */ + fdtw_read_string(dtb, sp_node, "owner", + arm_sp.owner[index], ARM_SP_OWNER_NAME_LEN); +#endif + /* If owner is empty mark it as SiP owned */ + if ((strncmp(arm_sp.owner[index], "SiP", + ARM_SP_OWNER_NAME_LEN) == 0) || + (strncmp(arm_sp.owner[index], "", + ARM_SP_OWNER_NAME_LEN) == 0)) { + is_plat_owned = false; + } else if (strcmp(arm_sp.owner[index], "Plat") == 0) { + is_plat_owned = true; + } else { + ERROR("FCONF: %s is not a valid SP owner\n", + arm_sp.owner[index]); + return -1; + } + /* + * Add SP information in mem param descriptor and IO policies + * structure. + */ + if (is_plat_owned) { + sp_mem_params_descs[index].image_id = plat_index; + policies[plat_index].image_spec = + (uintptr_t)&arm_sp.uuids[index]; + policies[plat_index].dev_handle = &fip_dev_handle; + policies[plat_index].check = open_fip; + plat_index++; + } else { + sp_mem_params_descs[index].image_id = sip_index; + policies[sip_index].image_spec = + (uintptr_t)&arm_sp.uuids[index]; + policies[sip_index].dev_handle = &fip_dev_handle; + policies[sip_index].check = open_fip; + sip_index++; + } SET_PARAM_HEAD(&sp_mem_params_descs[index].image_info, PARAM_IMAGE_BINARY, VERSION_2, 0); sp_mem_params_descs[index].image_info.image_max_size = @@ -84,13 +127,6 @@ int fconf_populate_arm_sp(uintptr_t config) INVALID_IMAGE_ID; sp_mem_params_descs[index].image_info.image_base = arm_sp.load_addr[index]; - - /* Add SP information in IO policies structure */ - policies[sp_start_index + index].image_spec = - (uintptr_t)&arm_sp.uuids[index]; - policies[sp_start_index + index].dev_handle = &fip_dev_handle; - policies[sp_start_index + index].check = open_fip; - index++; } From 1e7528ec378eb633125e67ddf1b1089eba149945 Mon Sep 17 00:00:00 2001 From: Ruari Phipps Date: Fri, 24 Jul 2020 16:20:57 +0100 Subject: [PATCH 2/3] SPM: Alter sp_gen.mk entry depending on owner of partition With recently introduced dualroot CoT for SPs where they are owned either by SiP or by Platform. SiP owned SPs index starts at SP_PKG1_ID while Plat owned SPs index starts at SP_PKG5_ID. This patch modifies SP makefile generator script to take CoT as an argument and if it is "dualroot" then generates SP_PKG in order mentioned above, otherwise generates it sequentially. Signed-off-by: Ruari Phipps Change-Id: Iffad1131787be650a9462f6f8cc09b603cddb3b8 --- Makefile | 2 +- tools/sptool/sp_mk_generator.py | 36 ++++++++++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index f4589d9b2..05b296922 100644 --- a/Makefile +++ b/Makefile @@ -1135,7 +1135,7 @@ endif # Add Secure Partition packages ifeq (${NEED_SP_PKG},yes) $(BUILD_PLAT)/sp_gen.mk: ${SP_MK_GEN} ${SP_LAYOUT_FILE} | ${BUILD_PLAT} - ${Q}${PYTHON} "$<" "$@" $(filter-out $<,$^) $(BUILD_PLAT) + ${Q}${PYTHON} "$<" "$@" $(filter-out $<,$^) $(BUILD_PLAT) ${COT} sp: $(SPTOOL) $(DTBS) $(BUILD_PLAT)/sp_gen.mk ${Q}$(SPTOOL) $(SPTOOL_ARGS) @${ECHO_BLANK_LINE} diff --git a/tools/sptool/sp_mk_generator.py b/tools/sptool/sp_mk_generator.py index 2153a5651..a37e702bb 100755 --- a/tools/sptool/sp_mk_generator.py +++ b/tools/sptool/sp_mk_generator.py @@ -19,6 +19,7 @@ standard format. param1: Generated mk file "sp_gen.mk" param2: "SP_LAYOUT_FILE", json file containing platform provided information param3: plat out directory +param4: CoT parameter Generated "sp_gen.mk" file contains triplet of following information for each Secure Partition entry @@ -58,11 +59,39 @@ json_dir = os.path.dirname(json_file) gen_file = os.path.abspath(sys.argv[1]) out_dir = os.path.abspath(sys.argv[3]) dtb_dir = out_dir + "/fdts/" +MAX_SP = 8 +dualroot = sys.argv[4].lower() == "dualroot" +split = int(MAX_SP / 2) print(dtb_dir) +platform_count = 1 +sip_count = 1 with open(gen_file, 'w') as out_file: for idx, key in enumerate(data.keys()): + pkg_num = idx + 1 + + if (pkg_num > MAX_SP): + print("WARNING: Too many secure partitions\n") + exit(-1) + + if dualroot: + owner = data[key].get('owner') + if owner == "Plat": + if (platform_count > split): + print("WARNING: Maximum Secure partitions by Plat " + + "have been exceeded (" + str(split) + ")\n") + exit(-1) + pkg_num = split + platform_count + platform_count += 1 + elif (sip_count > split): + print("WARNING: Maximum Secure partitions by SiP " + + "have been exceeded (" + str(split) + ")\n") + exit(-1) + else: + pkg_num = sip_count + sip_count += 1 + """ Append FDT_SOURCES """ @@ -81,10 +110,10 @@ with open(gen_file, 'w') as out_file: Extract uuid from partition manifest """ pm_file = open(dts) - key = "uuid" + uuid_key = "uuid" for line in pm_file: - if key in line: + if uuid_key in line: uuid_hex = re.findall(r'\<(.+?)\>', line)[0]; # PM has uuid in format 0xABC... 0x... 0x... 0x... @@ -103,5 +132,6 @@ with open(gen_file, 'w') as out_file: """ Append CRT_ARGS """ - out_file.write("CRT_ARGS += --sp-pkg" + str(idx + 1) + " " + dst + "\n") + + out_file.write("CRT_ARGS += --sp-pkg" + str(pkg_num) + " " + dst + "\n") out_file.write("\n") From ad86d35aa073b64bcfaed9bf8c283fa99c458408 Mon Sep 17 00:00:00 2001 From: Ruari Phipps Date: Tue, 11 Aug 2020 15:28:03 +0100 Subject: [PATCH 3/3] SPM: Add owner field to cactus secure partitions For supporting dualroot CoT for Secure Partitions a new optional field "owner" is introduced which will be used to sign the SP with corresponding signing domain. To demonstrate its usage, this patch adds owners to cactus Secure Partitions. Signed-off-by: Ruari Phipps Change-Id: I7b760580355fc92edf5402cecc38c38125dc1cae --- plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts index 280a64aad..1ee728546 100644 --- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts @@ -84,11 +84,13 @@ cactus-primary { uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>; load-address = <0x7000000>; + owner = "SiP"; }; cactus-secondary { uuid = <0x092358d1 0xb94723f0 0x64447c82 0xc88f57f5>; load-address = <0x7100000>; + owner = "Plat"; }; #endif };