diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 23cd12f51..8d81af960 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -280,7 +280,7 @@ * The max number of regions like RO(code), coherent and data required by * different BL stages which need to be mapped in the MMU. */ -# define ARM_BL_REGIONS 4 +#define ARM_BL_REGIONS 5 #define MAX_MMAP_REGIONS (PLAT_ARM_MMAP_ENTRIES + \ ARM_BL_REGIONS) diff --git a/include/plat/arm/common/arm_reclaim_init.ld.S b/include/plat/arm/common/arm_reclaim_init.ld.S new file mode 100644 index 000000000..8f22170fe --- /dev/null +++ b/include/plat/arm/common/arm_reclaim_init.ld.S @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef ARM_RECLAIM_INIT_LD_S +#define ARM_RECLAIM_INIT_LD_S + +SECTIONS +{ + .init __STACKS_START__ : { + . = . + PLATFORM_STACK_SIZE; + . = ALIGN(PAGE_SIZE); + __INIT_CODE_START__ = .; + /* + * Exclude PSCI initialization functions to ensure the init section + * does not become larger than the overlaid stack region + */ + *(EXCLUDE_FILE (*psci_setup.o).text.init*) + __INIT_CODE_UNALIGNED__ = .; + . = ALIGN(PAGE_SIZE); + __INIT_CODE_END__ = .; + } >RAM + +#ifdef BL31_PROGBITS_LIMIT + ASSERT(__INIT_CODE_END__ <= BL31_PROGBITS_LIMIT, + "BL31 init has exceeded progbits limit.") +#endif + +#if RECLAIM_INIT_CODE + ASSERT(__INIT_CODE_END__ <= __STACKS_END__, + "Init code ends past the end of the stacks") +#endif +} + +#endif /* ARM_RECLAIM_INIT_LD_S */ diff --git a/include/plat/arm/common/arm_common.ld.S b/include/plat/arm/common/arm_tzc_dram.ld.S similarity index 87% rename from include/plat/arm/common/arm_common.ld.S rename to include/plat/arm/common/arm_tzc_dram.ld.S index 3f6e29b0a..df951e117 100644 --- a/include/plat/arm/common/arm_common.ld.S +++ b/include/plat/arm/common/arm_tzc_dram.ld.S @@ -3,8 +3,8 @@ * * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef __ARM_COMMON_LD_S__ -#define __ARM_COMMON_LD_S__ +#ifndef ARM_TZC_DRAM_LD_S__ +#define ARM_TZC_DRAM_LD_S__ #include @@ -27,4 +27,4 @@ SECTIONS } >EL3_SEC_DRAM } -#endif /* __ARM_COMMON_LD_S__ */ +#endif /* ARM_TZC_DRAM_LD_S__ */ diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 3f344abce..d543894d7 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -220,6 +220,12 @@ void arm_bl2_dyn_cfg_init(void); void arm_bl1_set_mbedtls_heap(void); int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size); +/* + * Free the memory storing initialization code only used during an images boot + * time so it can be reclaimed for runtime data + */ +void arm_free_init_memory(void); + /* * Mandatory functions required in ARM standard platforms */ diff --git a/plat/arm/board/fvp/include/plat.ld.S b/plat/arm/board/fvp/include/plat.ld.S index 24c3debd9..f2a3ea6a4 100644 --- a/plat/arm/board/fvp/include/plat.ld.S +++ b/plat/arm/board/fvp/include/plat.ld.S @@ -6,6 +6,7 @@ #ifndef __PLAT_LD_S__ #define __PLAT_LD_S__ -#include +#include +#include #endif /* __PLAT_LD_S__ */ diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 4cd6a24de..9bd3bde65 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -201,6 +201,9 @@ ENABLE_AMU := 1 # Enable dynamic mitigation support by default DYNAMIC_WORKAROUND_CVE_2018_3639 := 1 +# Enable reclaiming of BL31 initialisation code for secondary cores stacks for FVP +RECLAIM_INIT_CODE := 1 + ifeq (${ENABLE_AMU},1) BL31_SOURCES += lib/cpus/aarch64/cortex_a75_pubsub.c \ lib/cpus/aarch64/cortex_ares_pubsub.c \ diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index c54566390..ed2c3fbce 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include /* * Placeholder variables for copying the arguments that have been passed to @@ -35,10 +37,20 @@ CASSERT(BL31_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl31_base_overflows); #pragma weak bl31_plat_arch_setup #pragma weak bl31_plat_get_next_image_ep_info -#define MAP_BL31_TOTAL MAP_REGION_FLAT( \ +#define MAP_BL31_TOTAL MAP_REGION_FLAT( \ BL31_BASE, \ BL31_END - BL31_BASE, \ MT_MEMORY | MT_RW | MT_SECURE) +#if RECLAIM_INIT_CODE +IMPORT_SYM(unsigned long, __INIT_CODE_START__, BL_INIT_CODE_BASE); +IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_INIT_CODE_END); + +#define MAP_BL_INIT_CODE MAP_REGION_FLAT( \ + BL_INIT_CODE_BASE, \ + BL_INIT_CODE_END \ + - BL_INIT_CODE_BASE, \ + MT_CODE | MT_SECURE) +#endif /******************************************************************************* * Return a pointer to the 'entry_point_info' structure of the next image for the @@ -233,8 +245,29 @@ void arm_bl31_plat_runtime_setup(void) /* Initialize the runtime console */ arm_console_runtime_init(); +#if RECLAIM_INIT_CODE + arm_free_init_memory(); +#endif } +#if RECLAIM_INIT_CODE +/* + * Zero out and make RW memory used to store image boot time code so it can + * be reclaimed during runtime + */ +void arm_free_init_memory(void) +{ + int ret = xlat_change_mem_attributes(BL_INIT_CODE_BASE, + BL_INIT_CODE_END - BL_INIT_CODE_BASE, + MT_RW_DATA); + + if (ret != 0) { + ERROR("Could not reclaim initialization code"); + panic(); + } +} +#endif + void __init bl31_platform_setup(void) { arm_bl31_platform_setup(); @@ -255,6 +288,9 @@ void __init arm_bl31_plat_arch_setup(void) { const mmap_region_t bl_regions[] = { MAP_BL31_TOTAL, +#if RECLAIM_INIT_CODE + MAP_BL_INIT_CODE, +#endif ARM_MAP_BL_RO, #if USE_ROMLIB ARM_MAP_ROMLIB_CODE, diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c index ae06ef280..a21d189e9 100644 --- a/plat/arm/common/arm_common.c +++ b/plat/arm/common/arm_common.c @@ -38,6 +38,7 @@ void arm_setup_romlib(void) * as an array specifying the generic memory regions which can be; * - Code section; * - Read-only data section; + * - Init code section, if applicable * - Coherent memory region, if applicable. */ diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index a8df5bad3..276f7801c 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -273,3 +273,14 @@ endif include ${IMG_PARSER_LIB_MK} endif + +# RECLAIM_INIT_CODE can only be set when LOAD_IMAGE_V2=2 and xlat tables v2 +# are used +ifeq (${RECLAIM_INIT_CODE}, 1) + ifeq (${LOAD_IMAGE_V2}, 0) + $(error "LOAD_IMAGE_V2 must be enabled to use RECLAIM_INIT_CODE") + endif + ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1) + $(error "To reclaim init code xlat tables v2 must be used") + endif +endif