From 5b8d50e40701ebb6a7ba548ccaa96ba879587fb9 Mon Sep 17 00:00:00 2001 From: Sathees Balya Date: Thu, 15 Nov 2018 14:22:30 +0000 Subject: [PATCH] plat/arm: Save BL2 descriptors to reserved memory. On ARM platforms, the BL2 memory can be overlaid by BL31/BL32. The memory descriptors describing the list of executable images are created in BL2 R/W memory, which could be possibly corrupted later on by BL31/BL32 due to overlay. This patch creates a reserved location in SRAM for these descriptors and are copied over by BL2 before handing over to next BL image. Also this patch increases the PLAT_ARM_MAX_BL2_SIZE for juno when TBBR is enabled. Fixes ARM-Software/tf-issues#626 Change-Id: I755735706fa702024b4032f51ed4895b3687377f Signed-off-by: Sathees Balya --- common/desc_image_load.c | 25 +++++++-- docs/firmware-design.rst | 21 ++++++-- include/common/desc_image_load.h | 3 ++ include/plat/arm/common/arm_def.h | 19 +++++-- include/plat/arm/common/plat_arm.h | 1 + plat/arm/board/juno/include/platform_def.h | 2 +- plat/arm/common/arm_image_load.c | 59 +++++++++++++++++++--- plat/arm/css/sgi/sgi_image_load.c | 8 ++- 8 files changed, 116 insertions(+), 22 deletions(-) diff --git a/common/desc_image_load.c b/common/desc_image_load.c index ada02f8d..405bb834 100644 --- a/common/desc_image_load.c +++ b/common/desc_image_load.c @@ -20,11 +20,28 @@ static bl_params_t next_bl_params; ******************************************************************************/ void flush_bl_params_desc(void) { - flush_dcache_range((uintptr_t)bl_mem_params_desc_ptr, - sizeof(*bl_mem_params_desc_ptr) * bl_mem_params_desc_num); + flush_bl_params_desc_args(bl_mem_params_desc_ptr, + bl_mem_params_desc_num, + &next_bl_params); +} + +/******************************************************************************* + * This function flushes the data structures specified as arguments so that they + * are visible in memory for the next BL image. + ******************************************************************************/ +void flush_bl_params_desc_args(bl_mem_params_node_t *mem_params_desc_ptr, + unsigned int mem_params_desc_num, + bl_params_t *next_bl_params_ptr) +{ + assert(mem_params_desc_ptr != NULL); + assert(mem_params_desc_num != 0U); + assert(next_bl_params_ptr != NULL); + + flush_dcache_range((uintptr_t)mem_params_desc_ptr, + sizeof(*mem_params_desc_ptr) * mem_params_desc_num); - flush_dcache_range((uintptr_t)&next_bl_params, - sizeof(next_bl_params)); + flush_dcache_range((uintptr_t)next_bl_params_ptr, + sizeof(*next_bl_params_ptr)); } /******************************************************************************* diff --git a/docs/firmware-design.rst b/docs/firmware-design.rst index c79f03d2..06fdbacd 100644 --- a/docs/firmware-design.rst +++ b/docs/firmware-design.rst @@ -1684,6 +1684,21 @@ an example. Note: Loading the BL32 image in TZC secured DRAM doesn't change the memory layout of the other images in Trusted SRAM. +CONFIG section in memory layouts shown below contains: + +:: + + +--------------------+ + |bl2_mem_params_descs| + |--------------------| + | fw_configs | + +--------------------+ + +``bl2_mem_params_descs`` contains parameters passed from BL2 to next the +BL image during boot. + +``fw_configs`` includes soc_fw_config, tos_fw_config and tb_fw_config. + **FVP with TSP in Trusted SRAM with firmware configs :** (These diagrams only cover the AArch64 case) @@ -1708,7 +1723,7 @@ layout of the other images in Trusted SRAM. | | <<<<<<<<<<<<< |----------------| | | <<<<<<<<<<<<< | BL32 | 0x04002000 +----------+ +----------------+ - |fw_configs| + | CONFIG | 0x04001000 +----------+ | Shared | 0x04000000 +----------+ @@ -1745,7 +1760,7 @@ layout of the other images in Trusted SRAM. | | <<<<<<<<<<<<< | BL31 PROGBITS | | | +----------------+ +--------------+ - | fw_configs | + | CONFIG | 0x04001000 +--------------+ | Shared | 0x04000000 +--------------+ @@ -1779,7 +1794,7 @@ layout of the other images in Trusted SRAM. | | <<<<<<<<<<<<< | BL31 PROGBITS | | | +----------------+ 0x04002000 +----------+ - |fw_configs| + | CONFIG | 0x04001000 +----------+ | Shared | 0x04000000 +----------+ diff --git a/include/common/desc_image_load.h b/include/common/desc_image_load.h index f2f26ea9..e46eb279 100644 --- a/include/common/desc_image_load.h +++ b/include/common/desc_image_load.h @@ -31,6 +31,9 @@ extern unsigned int bl_mem_params_desc_num; /* BL image loading utility functions */ void flush_bl_params_desc(void); +void flush_bl_params_desc_args(bl_mem_params_node_t *mem_params_desc_ptr, + unsigned int mem_params_desc_num, + bl_params_t *next_bl_params_ptr); int get_bl_params_node_index(unsigned int image_id); bl_mem_params_node_t *get_bl_mem_params_node(unsigned int image_id); bl_load_info_t *get_bl_load_info_from_mem_params_desc(void); diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index e27dd80e..62623c1b 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -348,7 +348,20 @@ * and limit. Leave enough space of BL2 meminfo. */ #define ARM_TB_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) -#define ARM_TB_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE) +#define ARM_TB_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE / 2U)) + +/* + * Boot parameters passed from BL2 to BL31/BL32 are stored here + */ +#define ARM_BL2_MEM_DESC_BASE ARM_TB_FW_CONFIG_LIMIT +#define ARM_BL2_MEM_DESC_LIMIT (ARM_BL2_MEM_DESC_BASE + \ + (PAGE_SIZE / 2U)) + +/* + * Define limit of firmware configuration memory: + * ARM_TB_FW_CONFIG + ARM_BL2_MEM_DESC memory + */ +#define ARM_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + PAGE_SIZE) /******************************************************************************* * BL1 specific defines. @@ -443,7 +456,7 @@ * SP_MIN is the only BL image in SRAM. Allocate the whole of SRAM (excluding * the page reserved for fw_configs) to BL32 */ -# define BL32_BASE ARM_TB_FW_CONFIG_LIMIT +# define BL32_BASE ARM_FW_CONFIG_LIMIT # define BL32_LIMIT (ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE) # else /* Put BL32 below BL2 in the Trusted SRAM.*/ @@ -481,7 +494,7 @@ # define TSP_SEC_MEM_BASE ARM_BL_RAM_BASE # define TSP_SEC_MEM_SIZE ARM_BL_RAM_SIZE # define TSP_PROGBITS_LIMIT BL31_BASE -# define BL32_BASE ARM_TB_FW_CONFIG_LIMIT +# define BL32_BASE ARM_FW_CONFIG_LIMIT # define BL32_LIMIT BL31_BASE # elif ARM_TSP_RAM_LOCATION_ID == ARM_TRUSTED_DRAM_ID # define TSP_SEC_MEM_BASE PLAT_ARM_TRUSTED_DRAM_BASE diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index b5edc74b..9d6786f5 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -188,6 +188,7 @@ void arm_bl2_plat_arch_setup(void); uint32_t arm_get_spsr_for_bl32_entry(void); uint32_t arm_get_spsr_for_bl33_entry(void); int arm_bl2_handle_post_image_load(unsigned int image_id); +struct bl_params *arm_get_next_bl_params(void); /* BL2 at EL3 functions */ void arm_bl2_el3_early_platform_setup(void); diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index ed82879a..b10cfdcb 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -143,7 +143,7 @@ #elif TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA # define PLAT_ARM_MAX_BL2_SIZE UL(0x1D000) #else -# define PLAT_ARM_MAX_BL2_SIZE UL(0x1C000) +# define PLAT_ARM_MAX_BL2_SIZE UL(0x1D000) #endif #else # define PLAT_ARM_MAX_BL2_SIZE UL(0xF000) diff --git a/plat/arm/common/arm_image_load.c b/plat/arm/common/arm_image_load.c index bf1fbfd4..74018d2d 100644 --- a/plat/arm/common/arm_image_load.c +++ b/plat/arm/common/arm_image_load.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include #include #include #include @@ -14,6 +15,7 @@ #pragma weak plat_get_bl_image_load_info #pragma weak plat_get_next_bl_params +static bl_params_t *next_bl_params_cpy_ptr; /******************************************************************************* * This function flushes the data structures so that they are visible @@ -21,7 +23,11 @@ ******************************************************************************/ void plat_flush_next_bl_params(void) { - flush_bl_params_desc(); + assert(next_bl_params_cpy_ptr != NULL); + + flush_bl_params_desc_args(bl_mem_params_desc_ptr, + bl_mem_params_desc_num, + next_bl_params_cpy_ptr); } /******************************************************************************* @@ -33,12 +39,53 @@ struct bl_load_info *plat_get_bl_image_load_info(void) } /******************************************************************************* - * This function returns the list of executable images. + * ARM helper function to return the list of executable images.Since the default + * descriptors are allocated within BL2 RW memory, this prevents BL31/BL32 + * overlay of BL2 memory. Hence this function also copies the descriptors to a + * pre-allocated memory indicated by ARM_BL2_MEM_DESC_BASE. ******************************************************************************/ -struct bl_params *plat_get_next_bl_params(void) +struct bl_params *arm_get_next_bl_params(void) { - bl_params_t *next_bl_params = get_next_bl_params_from_mem_params_desc(); + bl_mem_params_node_t *bl2_mem_params_descs_cpy + = (bl_mem_params_node_t *)ARM_BL2_MEM_DESC_BASE; + const bl_params_t *next_bl_params; + + next_bl_params_cpy_ptr = + (bl_params_t *)(ARM_BL2_MEM_DESC_BASE + + (bl_mem_params_desc_num * sizeof(bl_mem_params_node_t))); + + /* + * Copy the memory descriptors to ARM_BL2_MEM_DESC_BASE area. + */ + (void) memcpy(bl2_mem_params_descs_cpy, bl_mem_params_desc_ptr, + (bl_mem_params_desc_num * sizeof(bl_mem_params_node_t))); + + /* + * Modify the global 'bl_mem_params_desc_ptr' to point to the + * copied location. + */ + bl_mem_params_desc_ptr = bl2_mem_params_descs_cpy; + + next_bl_params = get_next_bl_params_from_mem_params_desc(); + assert(next_bl_params != NULL); + + /* + * Copy 'next_bl_params' to the reserved location after the copied + * memory descriptors. + */ + (void) memcpy(next_bl_params_cpy_ptr, next_bl_params, + (sizeof(bl_params_t))); + + populate_next_bl_params_config(next_bl_params_cpy_ptr); - populate_next_bl_params_config(next_bl_params); - return next_bl_params; + return next_bl_params_cpy_ptr; } + +/******************************************************************************* + * This function returns the list of executable images + ******************************************************************************/ +struct bl_params *plat_get_next_bl_params(void) +{ + return arm_get_next_bl_params(); +} + diff --git a/plat/arm/css/sgi/sgi_image_load.c b/plat/arm/css/sgi/sgi_image_load.c index 1ed219d6..e52124f2 100644 --- a/plat/arm/css/sgi/sgi_image_load.c +++ b/plat/arm/css/sgi/sgi_image_load.c @@ -11,6 +11,7 @@ #include #include +#include #include /******************************************************************************* @@ -72,14 +73,11 @@ static int plat_sgi_append_config_node(void) bl_params_t *plat_get_next_bl_params(void) { int ret; - bl_params_t *next_bl_params; ret = plat_sgi_append_config_node(); if (ret != 0) panic(); - next_bl_params = get_next_bl_params_from_mem_params_desc(); - populate_next_bl_params_config(next_bl_params); - - return next_bl_params; + return arm_get_next_bl_params(); } + -- 2.30.2