Unverified Commit 43d71452 authored by danh-arm's avatar danh-arm Committed by GitHub
Browse files

Merge pull request #1354 from robertovargas-arm/mem_protect

ARM platforms: Demonstrate mem_protect from el3_runtime
parents 0d2a1e42 638b034c
/* /*
* Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -29,6 +29,18 @@ typedef struct mem_region { ...@@ -29,6 +29,18 @@ typedef struct mem_region {
*/ */
void clear_mem_regions(mem_region_t *tbl, size_t nregions); void clear_mem_regions(mem_region_t *tbl, size_t nregions);
/*
* zero_normalmem all the regions defined in region. It dynamically
* maps chunks of 'chunk_size' in 'va' virtual address and clears them.
* For this reason memory regions must be multiple of chunk_size and
* must be aligned to it as well. chunk_size and va can be selected
* in a way that they minimize the number of entries used in the
* translation tables.
*/
void clear_map_dyn_mem_regions(mem_region_t *region,
size_t nregions,
uintptr_t va,
size_t chunk_size);
/* /*
* checks that a region (addr + nbytes-1) of memory is totally covered by * checks that a region (addr + nbytes-1) of memory is totally covered by
......
...@@ -30,7 +30,11 @@ ...@@ -30,7 +30,11 @@
#elif defined(IMAGE_BL2U) #elif defined(IMAGE_BL2U)
# define PLATFORM_STACK_SIZE 0x200 # define PLATFORM_STACK_SIZE 0x200
#elif defined(IMAGE_BL31) #elif defined(IMAGE_BL31)
#ifdef PLAT_XLAT_TABLES_DYNAMIC
# define PLATFORM_STACK_SIZE 0x800
#else
# define PLATFORM_STACK_SIZE 0x400 # define PLATFORM_STACK_SIZE 0x400
#endif
#elif defined(IMAGE_BL32) #elif defined(IMAGE_BL32)
# define PLATFORM_STACK_SIZE 0x440 # define PLATFORM_STACK_SIZE 0x440
#endif #endif
...@@ -59,11 +63,11 @@ ...@@ -59,11 +63,11 @@
# define PLAT_SP_IMAGE_MMAP_REGIONS 7 # define PLAT_SP_IMAGE_MMAP_REGIONS 7
# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10 # define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10
# else # else
# define PLAT_ARM_MMAP_ENTRIES 7 # define PLAT_ARM_MMAP_ENTRIES 8
# define MAX_XLAT_TABLES 5 # define MAX_XLAT_TABLES 5
# endif # endif
#elif defined(IMAGE_BL32) #elif defined(IMAGE_BL32)
# define PLAT_ARM_MMAP_ENTRIES 7 # define PLAT_ARM_MMAP_ENTRIES 8
# define MAX_XLAT_TABLES 5 # define MAX_XLAT_TABLES 5
#else #else
# define PLAT_ARM_MMAP_ENTRIES 11 # define PLAT_ARM_MMAP_ENTRIES 11
......
...@@ -166,7 +166,8 @@ void arm_system_pwr_domain_resume(void); ...@@ -166,7 +166,8 @@ void arm_system_pwr_domain_resume(void);
void arm_program_trusted_mailbox(uintptr_t address); void arm_program_trusted_mailbox(uintptr_t address);
int arm_psci_read_mem_protect(int *enabled); int arm_psci_read_mem_protect(int *enabled);
int arm_nor_psci_write_mem_protect(int val); int arm_nor_psci_write_mem_protect(int val);
void arm_nor_psci_do_mem_protect(void); void arm_nor_psci_do_static_mem_protect(void);
void arm_nor_psci_do_dyn_mem_protect(void);
int arm_psci_mem_protect_chk(uintptr_t base, u_register_t length); int arm_psci_mem_protect_chk(uintptr_t base, u_register_t length);
/* Topology utility function */ /* Topology utility function */
......
...@@ -172,7 +172,7 @@ ...@@ -172,7 +172,7 @@
#endif /* CSS_LOAD_SCP_IMAGES */ #endif /* CSS_LOAD_SCP_IMAGES */
/* Load address of Non-Secure Image for CSS platform ports */ /* Load address of Non-Secure Image for CSS platform ports */
#define PLAT_ARM_NS_IMAGE_OFFSET 0xE0000000 #define PLAT_ARM_NS_IMAGE_OFFSET U(0xE0000000)
/* TZC related constants */ /* TZC related constants */
#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT_ALL #define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT_ALL
......
/* /*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -40,6 +40,59 @@ void clear_mem_regions(mem_region_t *tbl, size_t nregions) ...@@ -40,6 +40,59 @@ void clear_mem_regions(mem_region_t *tbl, size_t nregions)
} }
} }
#if defined(PLAT_XLAT_TABLES_DYNAMIC)
/*
* zero_normalmem all the regions defined in regions.
* It assumes that MMU is enabled and the memory is Normal memory.
* regions must be a valid pointer to a memory mem_region_t array,
* nregions is the size of the array. va is the virtual address
* where we want to map the physical pages that are going to
* be cleared, and chunk is the amount of memory mapped and
* cleared in every iteration.
*/
void clear_map_dyn_mem_regions(mem_region_t *regions,
size_t nregions,
uintptr_t va,
size_t chunk)
{
uintptr_t begin;
int r;
size_t size;
const mmap_attr_t attr = MT_MEMORY|MT_RW|MT_NS;
assert(regions != NULL);
assert(nregions > 0 && chunk > 0);
for ( ; nregions--; regions++) {
begin = regions->base;
size = regions->nbytes;
if ((begin & (chunk-1)) != 0 || (size & (chunk-1)) != 0) {
INFO("PSCI: Not correctly aligned region\n");
panic();
}
while (size > 0) {
r = mmap_add_dynamic_region(begin, va, chunk, attr);
if (r != 0) {
INFO("PSCI: mmap_add_dynamic_region failed with %d\n", r);
panic();
}
zero_normalmem((void *) va, chunk);
r = mmap_remove_dynamic_region(va, chunk);
if (r != 0) {
INFO("PSCI: mmap_remove_dynamic_region failed with %d\n", r);
panic();
}
begin += chunk;
size -= chunk;
}
}
}
#endif
/* /*
* This function checks that a region (addr + nbytes-1) of memory is totally * This function checks that a region (addr + nbytes-1) of memory is totally
* covered by one of the regions defined in tbl. * covered by one of the regions defined in tbl.
......
/* /*
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -73,6 +73,9 @@ const mmap_region_t plat_arm_mmap[] = { ...@@ -73,6 +73,9 @@ const mmap_region_t plat_arm_mmap[] = {
const mmap_region_t plat_arm_mmap[] = { const mmap_region_t plat_arm_mmap[] = {
#ifdef AARCH32 #ifdef AARCH32
ARM_MAP_SHARED_RAM, ARM_MAP_SHARED_RAM,
#ifdef PLAT_ARM_MEM_PROT_ADDR
ARM_V2M_MAP_MEM_PROTECT,
#endif
#endif #endif
V2M_MAP_IOFPGA, V2M_MAP_IOFPGA,
CSS_MAP_DEVICE, CSS_MAP_DEVICE,
......
...@@ -412,13 +412,7 @@ plat_psci_ops_t plat_arm_psci_pm_ops = { ...@@ -412,13 +412,7 @@ plat_psci_ops_t plat_arm_psci_pm_ops = {
*/ */
.get_sys_suspend_power_state = fvp_get_sys_suspend_power_state, .get_sys_suspend_power_state = fvp_get_sys_suspend_power_state,
#endif #endif
#if !RESET_TO_BL31 && !RESET_TO_SP_MIN
/*
* mem_protect is not supported in RESET_TO_BL31 and RESET_TO_SP_MIN,
* as that would require mapping in all of NS DRAM into BL31 or BL32.
*/
.mem_protect_chk = arm_psci_mem_protect_chk, .mem_protect_chk = arm_psci_mem_protect_chk,
.read_mem_protect = arm_psci_read_mem_protect, .read_mem_protect = arm_psci_read_mem_protect,
.write_mem_protect = arm_nor_psci_write_mem_protect, .write_mem_protect = arm_nor_psci_write_mem_protect,
#endif
}; };
...@@ -7,6 +7,17 @@ ...@@ -7,6 +7,17 @@
#ifndef __PLATFORM_DEF_H__ #ifndef __PLATFORM_DEF_H__
#define __PLATFORM_DEF_H__ #define __PLATFORM_DEF_H__
/* Enable the dynamic translation tables library. */
#ifdef AARCH32
# if defined(IMAGE_BL32) && RESET_TO_SP_MIN
# define PLAT_XLAT_TABLES_DYNAMIC 1
# endif
#else
# if defined(IMAGE_BL31) && RESET_TO_BL31
# define PLAT_XLAT_TABLES_DYNAMIC 1
# endif
#endif /* AARCH32 */
#include <arm_def.h> #include <arm_def.h>
#include <arm_spm_def.h> #include <arm_spm_def.h>
#include <board_arm_def.h> #include <board_arm_def.h>
...@@ -40,6 +51,9 @@ ...@@ -40,6 +51,9 @@
#define PLAT_ARM_TRUSTED_DRAM_BASE 0x06000000 #define PLAT_ARM_TRUSTED_DRAM_BASE 0x06000000
#define PLAT_ARM_TRUSTED_DRAM_SIZE 0x02000000 /* 32 MB */ #define PLAT_ARM_TRUSTED_DRAM_SIZE 0x02000000 /* 32 MB */
/* virtual address used by dynamic mem_protect for chunk_base */
#define PLAT_ARM_MEM_PROTEC_VA_FRAME 0xc0000000
/* No SCP in FVP */ /* No SCP in FVP */
#define PLAT_ARM_SCP_TZC_DRAM1_SIZE ULL(0x0) #define PLAT_ARM_SCP_TZC_DRAM1_SIZE ULL(0x0)
...@@ -48,7 +62,7 @@ ...@@ -48,7 +62,7 @@
/* /*
* Load address of BL33 for this platform port * Load address of BL33 for this platform port
*/ */
#define PLAT_ARM_NS_IMAGE_OFFSET (ARM_DRAM1_BASE + 0x8000000) #define PLAT_ARM_NS_IMAGE_OFFSET (ARM_DRAM1_BASE + U(0x8000000))
/* /*
......
...@@ -7,6 +7,18 @@ ...@@ -7,6 +7,18 @@
#ifndef __PLATFORM_DEF_H__ #ifndef __PLATFORM_DEF_H__
#define __PLATFORM_DEF_H__ #define __PLATFORM_DEF_H__
/* Enable the dynamic translation tables library. */
#ifdef AARCH32
# if defined(IMAGE_BL32) && RESET_TO_SP_MIN
# define PLAT_XLAT_TABLES_DYNAMIC 1
# endif
#else
# if defined(IMAGE_BL31) && RESET_TO_BL31
# define PLAT_XLAT_TABLES_DYNAMIC 1
# endif
#endif /* AARCH32 */
#include <arm_def.h> #include <arm_def.h>
#include <board_arm_def.h> #include <board_arm_def.h>
#include <board_css_def.h> #include <board_css_def.h>
...@@ -44,6 +56,9 @@ ...@@ -44,6 +56,9 @@
/* Use the bypass address */ /* Use the bypass address */
#define PLAT_ARM_TRUSTED_ROM_BASE V2M_FLASH0_BASE + BL1_ROM_BYPASS_OFFSET #define PLAT_ARM_TRUSTED_ROM_BASE V2M_FLASH0_BASE + BL1_ROM_BYPASS_OFFSET
/* virtual address used by dynamic mem_protect for chunk_base */
#define PLAT_ARM_MEM_PROTEC_VA_FRAME 0xc0000000
/* /*
* Actual ROM size on Juno is 64 KB, but TBB currently requires at least 80 KB * Actual ROM size on Juno is 64 KB, but TBB currently requires at least 80 KB
* in debug mode. We can test TBB on Juno bypassing the ROM and using 128 KB of * in debug mode. We can test TBB on Juno bypassing the ROM and using 128 KB of
...@@ -90,7 +105,7 @@ ...@@ -90,7 +105,7 @@
#endif #endif
#ifdef IMAGE_BL32 #ifdef IMAGE_BL32
# define PLAT_ARM_MMAP_ENTRIES 5 # define PLAT_ARM_MMAP_ENTRIES 6
# define MAX_XLAT_TABLES 4 # define MAX_XLAT_TABLES 4
#endif #endif
......
...@@ -219,7 +219,7 @@ void arm_bl2_platform_setup(void) ...@@ -219,7 +219,7 @@ void arm_bl2_platform_setup(void)
plat_arm_security_setup(); plat_arm_security_setup();
#if defined(PLAT_ARM_MEM_PROT_ADDR) #if defined(PLAT_ARM_MEM_PROT_ADDR)
arm_nor_psci_do_mem_protect(); arm_nor_psci_do_static_mem_protect();
#endif #endif
} }
......
...@@ -206,6 +206,10 @@ void arm_bl31_platform_setup(void) ...@@ -206,6 +206,10 @@ void arm_bl31_platform_setup(void)
*/ */
plat_arm_security_setup(); plat_arm_security_setup();
#if defined(PLAT_ARM_MEM_PROT_ADDR)
arm_nor_psci_do_dyn_mem_protect();
#endif /* PLAT_ARM_MEM_PROT_ADDR */
#endif /* RESET_TO_BL31 */ #endif /* RESET_TO_BL31 */
/* Enable and initialize the System level generic timer */ /* Enable and initialize the System level generic timer */
......
...@@ -12,10 +12,22 @@ ...@@ -12,10 +12,22 @@
#include <psci.h> #include <psci.h>
#include <utils.h> #include <utils.h>
/*
* DRAM1 is used also to load the NS boot loader. For this reason we
* cannot clear the full DRAM1, because in that case we would clear
* the NS images (especially for RESET_TO_BL31 and RESET_TO_SPMIN cases).
* For this reason we reserve 64 MB for the NS images and protect the RAM
* until the end of DRAM1.
* We limit the size of DRAM2 to 1 GB to avoid big delays while booting
*/
#define DRAM1_NS_IMAGE_LIMIT (PLAT_ARM_NS_IMAGE_OFFSET + (32 << TWO_MB_SHIFT))
#define DRAM1_PROTECTED_SIZE (ARM_NS_DRAM1_END+1u - DRAM1_NS_IMAGE_LIMIT)
static mem_region_t arm_ram_ranges[] = { static mem_region_t arm_ram_ranges[] = {
{ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_SIZE}, {DRAM1_NS_IMAGE_LIMIT, DRAM1_PROTECTED_SIZE},
#ifdef AARCH64 #ifdef AARCH64
{ARM_DRAM2_BASE, ARM_DRAM2_SIZE}, {ARM_DRAM2_BASE, 1u << ONE_GB_SHIFT},
#endif #endif
}; };
...@@ -29,7 +41,7 @@ int arm_psci_read_mem_protect(int *enabled) ...@@ -29,7 +41,7 @@ int arm_psci_read_mem_protect(int *enabled)
int tmp; int tmp;
tmp = *(int *) PLAT_ARM_MEM_PROT_ADDR; tmp = *(int *) PLAT_ARM_MEM_PROT_ADDR;
*enabled = (tmp == 1); *enabled = (tmp == 1) ? 1 : 0;
return 0; return 0;
} }
...@@ -46,7 +58,7 @@ int arm_nor_psci_write_mem_protect(int val) ...@@ -46,7 +58,7 @@ int arm_nor_psci_write_mem_protect(int val)
return -1; return -1;
} }
if (enable) { if (enable != 0) {
/* /*
* If we want to write a value different than 0 * If we want to write a value different than 0
* then we have to erase the full block because * then we have to erase the full block because
...@@ -71,15 +83,47 @@ int arm_nor_psci_write_mem_protect(int val) ...@@ -71,15 +83,47 @@ int arm_nor_psci_write_mem_protect(int val)
* Function used for required psci operations performed when * Function used for required psci operations performed when
* system boots * system boots
******************************************************************************/ ******************************************************************************/
void arm_nor_psci_do_mem_protect(void) /*
* PLAT_MEM_PROTECT_VA_FRAME is a address specifically
* selected in a way that is not needed an additional
* translation table for memprotect. It happens because
* we use a chunk of size 2MB and it means that it can
* be mapped in a level 2 table and the level 2 table
* for 0xc0000000 is already used and the entry for
* 0xc0000000 is not used.
*/
#if defined(PLAT_XLAT_TABLES_DYNAMIC)
void arm_nor_psci_do_dyn_mem_protect(void)
{ {
int enable; int enable;
arm_psci_read_mem_protect(&enable); arm_psci_read_mem_protect(&enable);
if (!enable) if (enable == 0)
return; return;
INFO("PSCI: Overwritting non secure memory\n");
clear_mem_regions(arm_ram_ranges, ARRAY_SIZE(arm_ram_ranges)); INFO("PSCI: Overwriting non secure memory\n");
clear_map_dyn_mem_regions(arm_ram_ranges,
ARRAY_SIZE(arm_ram_ranges),
PLAT_ARM_MEM_PROTEC_VA_FRAME,
1 << TWO_MB_SHIFT);
}
#endif
/*******************************************************************************
* Function used for required psci operations performed when
* system boots and dynamic memory is not used.
******************************************************************************/
void arm_nor_psci_do_static_mem_protect(void)
{
int enable;
arm_psci_read_mem_protect(&enable);
if (enable == 0)
return;
INFO("PSCI: Overwriting non secure memory\n");
clear_mem_regions(arm_ram_ranges,
ARRAY_SIZE(arm_ram_ranges));
arm_nor_psci_write_mem_protect(0); arm_nor_psci_write_mem_protect(0);
} }
......
...@@ -162,6 +162,11 @@ void sp_min_platform_setup(void) ...@@ -162,6 +162,11 @@ void sp_min_platform_setup(void)
*/ */
#if RESET_TO_SP_MIN #if RESET_TO_SP_MIN
plat_arm_security_setup(); plat_arm_security_setup();
#if defined(PLAT_ARM_MEM_PROT_ADDR)
arm_nor_psci_do_dyn_mem_protect();
#endif /* PLAT_ARM_MEM_PROT_ADDR */
#endif #endif
/* Enable and initialize the System level generic timer */ /* Enable and initialize the System level generic timer */
......
/* /*
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -303,11 +303,8 @@ plat_psci_ops_t plat_arm_psci_pm_ops = { ...@@ -303,11 +303,8 @@ plat_psci_ops_t plat_arm_psci_pm_ops = {
.translate_power_state_by_mpidr = css_translate_power_state_by_mpidr, .translate_power_state_by_mpidr = css_translate_power_state_by_mpidr,
.get_node_hw_state = css_node_hw_state, .get_node_hw_state = css_node_hw_state,
.get_sys_suspend_power_state = css_get_sys_suspend_power_state, .get_sys_suspend_power_state = css_get_sys_suspend_power_state,
/*
* mem_protect is not supported in RESET_TO_BL31 and RESET_TO_SP_MIN, #if defined(PLAT_ARM_MEM_PROT_ADDR)
* as that would require mapping in all of NS DRAM into BL31 or BL32.
*/
#if defined(PLAT_ARM_MEM_PROT_ADDR) && !RESET_TO_BL31 && !RESET_TO_SP_MIN
.mem_protect_chk = arm_psci_mem_protect_chk, .mem_protect_chk = arm_psci_mem_protect_chk,
.read_mem_protect = arm_psci_read_mem_protect, .read_mem_protect = arm_psci_read_mem_protect,
.write_mem_protect = arm_nor_psci_write_mem_protect, .write_mem_protect = arm_nor_psci_write_mem_protect,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment