feat(fvp): added calls to unprotect/protect memory

Added SiP calls to FVP platform to protect/unprotect a
memory range.
These leverage rme features to change the PAS of a given
memory range from non-secure to secure.

The mentioned call is leveraged by the SPMC in the memory
sharing flow, when memory is shared from the normal world
onto the secure world.

More details in the SPM related patches.

Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
Signed-off-by: J-Alves <joao.alves@arm.com>
Change-Id: Iaf15d8603a549d247ffb1fc14c16bfb94d0e178a
This commit is contained in:
J-Alves 2023-10-04 17:16:45 +01:00
parent 17bef2248d
commit 6873088c2c
4 changed files with 93 additions and 7 deletions

View file

@ -111,6 +111,8 @@
#define SMC_OK ULL(0) #define SMC_OK ULL(0)
#define SMC_UNK -1 #define SMC_UNK -1
#define SMC_PREEMPTED -2 /* Not defined by the SMCCC */ #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 */ /* Return codes for Arm Architecture Service SMC calls */
#define SMC_ARCH_CALL_SUCCESS 0 #define SMC_ARCH_CALL_SUCCESS 0

View file

@ -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 * SPDX-License-Identifier: BSD-3-Clause
*/ */
@ -42,6 +42,16 @@
#define ARM_SIP_SET_INTERRUPT_PENDING U(0x82000100) #define ARM_SIP_SET_INTERRUPT_PENDING U(0x82000100)
#endif #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. */ /* SiP handler specific to each Arm platform. */
uintptr_t plat_arm_sip_handler(uint32_t smc_fid, uintptr_t plat_arm_sip_handler(uint32_t smc_fid,
u_register_t x1, u_register_t x1,

View file

@ -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 * SPDX-License-Identifier: BSD-3-Clause
*/ */
#include <stdint.h> #include <stdint.h>
#include <errno.h>
#include <common/debug.h> #include <common/debug.h>
#include <common/runtime_svc.h> #include <common/runtime_svc.h>
@ -12,10 +13,73 @@
#include <plat/arm/common/arm_sip_svc.h> #include <plat/arm/common/arm_sip_svc.h>
#include <plat/common/platform.h> #include <plat/common/platform.h>
#if ENABLE_RME && SPMD_SPM_AT_SEL2
#include <lib/gpt_rme/gpt_rme.h>
#endif
#if ENABLE_SPMD_LP #if ENABLE_SPMD_LP
#include <services/el3_spmd_logical_sp.h> #include <services/el3_spmd_logical_sp.h>
#endif #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, uintptr_t plat_arm_sip_handler(uint32_t smc_fid,
u_register_t x1, u_register_t x1,
u_register_t x2, u_register_t x2,
@ -25,13 +89,14 @@ uintptr_t plat_arm_sip_handler(uint32_t smc_fid,
void *handle, void *handle,
u_register_t flags) u_register_t flags)
{ {
#if PLAT_TEST_SPM
bool secure_origin; bool secure_origin;
/* Determine which security state this SMC originated from */ /* Determine which security state this SMC originated from */
secure_origin = is_caller_secure(flags); secure_origin = is_caller_secure(flags);
(void) secure_origin;
switch (smc_fid) { switch (smc_fid) {
#if PLAT_TEST_SPM
case ARM_SIP_SET_INTERRUPT_PENDING: case ARM_SIP_SET_INTERRUPT_PENDING:
if (!secure_origin) { if (!secure_origin) {
SMC_RET1(handle, SMC_UNK); SMC_RET1(handle, SMC_UNK);
@ -42,11 +107,20 @@ uintptr_t plat_arm_sip_handler(uint32_t smc_fid,
SMC_RET1(handle, SMC_OK); SMC_RET1(handle, SMC_OK);
break; /* Not reached */ break; /* Not reached */
default:
break;
}
#endif #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 #if ENABLE_SPMD_LP
return plat_spmd_logical_sp_smc_handler(smc_fid, x1, x2, x3, x4, return plat_spmd_logical_sp_smc_handler(smc_fid, x1, x2, x3, x4,
cookie, handle, flags); cookie, handle, flags);

View file

@ -844,7 +844,7 @@ uint64_t spmd_smc_handler(uint32_t smc_fid,
unsigned int linear_id = plat_my_core_pos(); unsigned int linear_id = plat_my_core_pos();
spmd_spm_core_context_t *ctx = spmd_get_context(); spmd_spm_core_context_t *ctx = spmd_get_context();
bool secure_origin; bool secure_origin;
int32_t ret; int ret;
uint32_t input_version; uint32_t input_version;
/* Determine which security state this SMC originated from */ /* Determine which security state this SMC originated from */