diff --git a/docs/components/realm-management-extension.rst b/docs/components/realm-management-extension.rst index f228e6b57..39186b425 100644 --- a/docs/components/realm-management-extension.rst +++ b/docs/components/realm-management-extension.rst @@ -237,7 +237,7 @@ Use the following command to run the tests on FVP. -C bp.ve_sysregs.exit_on_shutdown=1 \ -C cache_state_modelled=1 \ -C bp.dram_size=4 \ - -C bp.secure_memory=1 \ + -C bp.secure_memory=0 \ -C pci.pci_smmuv3.mmu.SMMU_ROOT_IDR0=3 \ -C pci.pci_smmuv3.mmu.SMMU_ROOT_IIDR=0x43B \ -C pci.pci_smmuv3.mmu.root_register_page_offset=0x20000 \ diff --git a/include/lib/smccc.h b/include/lib/smccc.h index 8fd609314..c4931058d 100644 --- a/include/lib/smccc.h +++ b/include/lib/smccc.h @@ -111,6 +111,8 @@ #define SMC_OK ULL(0) #define SMC_UNK -1 #define SMC_PREEMPTED -2 /* Not defined by the SMCCC */ +#define SMC_DENIED -3 /* Not defined by the SMCCC */ +#define SMC_INVALID_PARAM -4 /* Not defined by the SMCCC */ /* Return codes for Arm Architecture Service SMC calls */ #define SMC_ARCH_CALL_SUCCESS 0 diff --git a/include/plat/arm/common/arm_sip_svc.h b/include/plat/arm/common/arm_sip_svc.h index 266092e30..a6fd42bac 100644 --- a/include/plat/arm/common/arm_sip_svc.h +++ b/include/plat/arm/common/arm_sip_svc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019,2021-2023, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2019,2021-2024, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -42,6 +42,16 @@ #define ARM_SIP_SET_INTERRUPT_PENDING U(0x82000100) #endif +/** + * Arm SiP Service Call for the SPM to leverage RME to protect a give memory range. + * Protected memory range is one whose PAS was made secure. + * Unprotect relates to reverting a protect operation. + */ +#if SPMD_SPM_AT_SEL2 && ENABLE_RME +#define PLAT_PROTECT_MEM_SMC64 0xC2000101 +#define PLAT_UNPROTECT_MEM_SMC64 0xC2000102 +#endif + /* SiP handler specific to each Arm platform. */ uintptr_t plat_arm_sip_handler(uint32_t smc_fid, u_register_t x1, diff --git a/plat/arm/common/plat_arm_sip_svc.c b/plat/arm/common/plat_arm_sip_svc.c index b1dab165b..d496d2e11 100644 --- a/plat/arm/common/plat_arm_sip_svc.c +++ b/plat/arm/common/plat_arm_sip_svc.c @@ -1,10 +1,11 @@ /* - * Copyright (c) 2023, Arm Limited. All rights reserved. + * Copyright (c) 2023-2024, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include +#include #include #include @@ -12,10 +13,73 @@ #include #include +#if ENABLE_RME && SPMD_SPM_AT_SEL2 +#include +#endif + #if ENABLE_SPMD_LP #include #endif +#if (ENABLE_RME == 1) && (defined(SPD_spmd) && SPMD_SPM_AT_SEL2 == 1) +static uint64_t plat_protect_memory(bool protect, + bool secure_origin, + const uint64_t base, + const size_t size, + void *handle) +{ + uint64_t ret = SMC_INVALID_PARAM; + uint64_t last_updated = 0; + + if (!secure_origin) { + SMC_RET1(handle, SMC_UNK); + /* Shall not be reached. */ + } + + if ((base % PAGE_SIZE_4KB) != 0U && + (size % PAGE_SIZE_4KB) != 0U) { + VERBOSE("Base address must be aligned to 4k.\n"); + SMC_RET1(handle, SMC_INVALID_PARAM); + /* Shall not be reached. */ + } + + if ((ULONG_MAX - base) < size) { + VERBOSE("Base + Size results in overflow.\n"); + SMC_RET1(handle, SMC_INVALID_PARAM); + /* Shall not be reached. */ + } + + for (uint64_t it = base; it < (base + size); it += PAGE_SIZE_4KB) { + /* + * If protect is true, add memory to secure PAS. + * Else unprotect it, making part of non-secure PAS. + */ + ret = protect + ? gpt_delegate_pas(it, PAGE_SIZE_4KB, + SMC_FROM_SECURE) + : gpt_undelegate_pas(it, PAGE_SIZE_4KB, + SMC_FROM_SECURE); + + switch (ret) { + case 0: + last_updated = it; + break; + case -EINVAL: + SMC_RET2(handle, SMC_INVALID_PARAM, last_updated); + break; /* Shall not be reached. */ + case -EPERM: + SMC_RET2(handle, SMC_DENIED, last_updated); + break; /* Shall not be reached. */ + default: + ERROR("Unexpected return\n"); + panic(); + } + } + + SMC_RET1(handle, SMC_OK); +} +#endif /* ENABLE_RME && SPMD_SPM_AT_SEL2 */ + uintptr_t plat_arm_sip_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2, @@ -25,13 +89,14 @@ uintptr_t plat_arm_sip_handler(uint32_t smc_fid, void *handle, u_register_t flags) { -#if PLAT_TEST_SPM bool secure_origin; /* Determine which security state this SMC originated from */ secure_origin = is_caller_secure(flags); + (void) secure_origin; switch (smc_fid) { +#if PLAT_TEST_SPM case ARM_SIP_SET_INTERRUPT_PENDING: if (!secure_origin) { SMC_RET1(handle, SMC_UNK); @@ -42,11 +107,20 @@ uintptr_t plat_arm_sip_handler(uint32_t smc_fid, SMC_RET1(handle, SMC_OK); break; /* Not reached */ - default: - break; - } #endif +#if (ENABLE_RME == 1) && (defined(SPD_spmd) && SPMD_SPM_AT_SEL2 == 1) + case PLAT_PROTECT_MEM_SMC64: + INFO("Sip Call - Protect memory\n"); + return plat_protect_memory(true, secure_origin, x1, x2, handle); + break; + case PLAT_UNPROTECT_MEM_SMC64: + INFO("Sip Call - Unprotect memory\n"); + return plat_protect_memory(false, secure_origin, x1, x2, handle); + break; +#endif + } + #if ENABLE_SPMD_LP return plat_spmd_logical_sp_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags); diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index 5d19868a2..e200b80ef 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -844,7 +844,7 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, unsigned int linear_id = plat_my_core_pos(); spmd_spm_core_context_t *ctx = spmd_get_context(); bool secure_origin; - int32_t ret; + int ret; uint32_t input_version; /* Determine which security state this SMC originated from */