diff --git a/include/plat/arm/common/arm_common.ld.S b/include/plat/arm/common/arm_common.ld.S deleted file mode 100644 index 3f6e29b..0000000 --- a/include/plat/arm/common/arm_common.ld.S +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -#ifndef __ARM_COMMON_LD_S__ -#define __ARM_COMMON_LD_S__ - -#include - -MEMORY { - EL3_SEC_DRAM (rw): ORIGIN = ARM_EL3_TZC_DRAM1_BASE, LENGTH = ARM_EL3_TZC_DRAM1_SIZE -} - -SECTIONS -{ - . = ARM_EL3_TZC_DRAM1_BASE; - ASSERT(. == ALIGN(PAGE_SIZE), - "ARM_EL3_TZC_DRAM_BASE address is not aligned on a page boundary.") - el3_tzc_dram (NOLOAD) : ALIGN(PAGE_SIZE) { - __EL3_SEC_DRAM_START__ = .; - *(arm_el3_tzc_dram) - __EL3_SEC_DRAM_UNALIGNED_END__ = .; - - . = ALIGN(PAGE_SIZE); - __EL3_SEC_DRAM_END__ = .; - } >EL3_SEC_DRAM -} - -#endif /* __ARM_COMMON_LD_S__ */ diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 23cd12f..8d81af9 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 0000000..8f22170 --- /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_tzc_dram.ld.S b/include/plat/arm/common/arm_tzc_dram.ld.S new file mode 100644 index 0000000..df951e1 --- /dev/null +++ b/include/plat/arm/common/arm_tzc_dram.ld.S @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef ARM_TZC_DRAM_LD_S__ +#define ARM_TZC_DRAM_LD_S__ + +#include + +MEMORY { + EL3_SEC_DRAM (rw): ORIGIN = ARM_EL3_TZC_DRAM1_BASE, LENGTH = ARM_EL3_TZC_DRAM1_SIZE +} + +SECTIONS +{ + . = ARM_EL3_TZC_DRAM1_BASE; + ASSERT(. == ALIGN(PAGE_SIZE), + "ARM_EL3_TZC_DRAM_BASE address is not aligned on a page boundary.") + el3_tzc_dram (NOLOAD) : ALIGN(PAGE_SIZE) { + __EL3_SEC_DRAM_START__ = .; + *(arm_el3_tzc_dram) + __EL3_SEC_DRAM_UNALIGNED_END__ = .; + + . = ALIGN(PAGE_SIZE); + __EL3_SEC_DRAM_END__ = .; + } >EL3_SEC_DRAM +} + +#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 3f344ab..d543894 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -221,6 +221,12 @@ 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 */ unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr); diff --git a/plat/arm/board/fvp/include/plat.ld.S b/plat/arm/board/fvp/include/plat.ld.S index 24c3deb..f2a3ea6 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 4cd6a24..9bd3bde 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -201,6 +201,9 @@ # 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 c545663..ed2c3fb 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 @@ #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 @@ /* 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 @@ { 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 ae06ef2..a21d189 100644 --- a/plat/arm/common/arm_common.c +++ b/plat/arm/common/arm_common.c @@ -38,6 +38,7 @@ * 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 a8df5ba..276f780 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -273,3 +273,14 @@ 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