Merge changes from topic "mec" into integration

* changes:
  feat(qemu): add plat_rmmd_mecid_key_update()
  feat(rmmd): add RMM_MECID_KEY_UPDATE call
This commit is contained in:
Soby Mathew 2025-03-20 10:26:23 +01:00 committed by TrustedFirmware Code Review
commit 4848824548
10 changed files with 161 additions and 5 deletions

View file

@ -52,8 +52,8 @@ are explained below:
- ``RES0``: Bit 31 of the version number is reserved 0 as to maintain
consistency with the versioning schemes used in other parts of RMM.
This document specifies the 0.4 version of Boot Interface ABI and RMM-EL3
services specification and the 0.4 version of the Boot Manifest.
This document specifies the 0.5 version of Boot Interface ABI and RMM-EL3
services specification and the 0.5 version of the Boot Manifest.
.. _rmm_el3_boot_interface:
@ -671,6 +671,54 @@ a failure. The errors are ordered by condition check.
``E_RMM_OK``,No errors detected
RMM_MECID_KEY_UPDATE command
============================
This command updates the tweak for the encryption key/programs a new encryption key
associated with a given MECID. After the execution of this command, all memory
accesses associated with the MECID are encrypted/decrypted using the new key.
This command is available from v0.5 of the RMM-EL3 interface.
FID
---
``0xC40001B6``
Input values
------------
.. csv-table:: Input values for RMM_MECID_KEY_UPDATE
:header: "Name", "Register", "Field", "Type", "Description"
:widths: 1 1 1 1 5
fid,x0,[63:0],UInt64,Command FID
mecid,x1,[15:0],UInt64,"mecid is a 16-bit value between 0 and 65,535 that identifies the MECID for which the encryption key is to be updated. Value has to be a valid MECID as per field MECIDWidthm1 read from MECIDR_EL2. Bits [63:16] must be 0."
Output values
-------------
.. csv-table:: Output values for RMM_MECID_KEY_UPDATE
:header: "Name", "Register", "Field", "Type", "Description"
:widths: 1 1 1 1 5
Result,x0,[63:0],Error Code,Command return status. Valid for all opcodes listed in input values
Failure conditions
------------------
The table below shows all the possible error codes returned in ``Result`` upon
a failure. The errors are ordered by condition check.
.. csv-table:: Failure conditions for RMM_MECID_KEY_UPDATE
:header: "ID", "Condition"
:widths: 1 5
``E_RMM_INVAL``,"if mecid is invalid (larger than 65,535 or than the maximum MECID width, determined by MECIDR_EL2.MECIDWidthm1)"
``E_RMM_UNK``,"An unknown error occurred whilst processing the command or the SMC is not present if interface version is <0.5"
``E_RMM_OK``,No errors detected
RMM-EL3 world switch register save restore convention
_____________________________________________________

View file

@ -2350,6 +2350,24 @@ RMM image and stores it in the area specified by manifest.
When ENABLE_RME is disabled, this function is not used.
Function : plat_rmm_mecid_key_update() [when ENABLE_RME == 1]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
Argument : uint16_t
Return : int
This function is invoked by BL31's RMMD when there is a request from the RMM
monitor to update the tweak for the encryption key associated to a MECID.
The first parameter (``uint16_t mecid``) contains the MECID for which the
encryption key is to be updated.
Return value is 0 upon success and -EFAULT otherwise.
This function needs to be implemented by a platform if it enables RME.
Function : plat_rmmd_el3_token_sign_push_req() [mandatory when RMMD_ENABLE_EL3_TOKEN_SIGN == 1]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View file

@ -1585,4 +1585,11 @@
#define CLUSTERPMCR_N_SHIFT U(11)
#define CLUSTERPMCR_N_MASK U(0x1f)
/*******************************************************************************
* FEAT_MEC - Memory Encryption Contexts
******************************************************************************/
#define MECIDR_EL2 S3_4_C10_C8_7
#define MECIDR_EL2_MECIDWidthm1_MASK U(0xf)
#define MECIDR_EL2_MECIDWidthm1_SHIFT U(0)
#endif /* ARCH_H */

View file

@ -753,6 +753,9 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(gpccr_el3, GPCCR_EL3)
DEFINE_RENAME_SYSREG_RW_FUNCS(fpmr, FPMR)
/* FEAT_MEC Registers */
DEFINE_RENAME_SYSREG_READ_FUNC(mecidr_el2, MECIDR_EL2)
#define IS_IN_EL(x) \
(GET_EL(read_CurrentEl()) == MODE_EL##x)

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -398,6 +398,7 @@ int plat_rmmd_el3_token_sign_push_req(
int plat_rmmd_el3_token_sign_pull_resp(struct el3_token_sign_response *resp);
size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared);
int plat_rmmd_load_manifest(struct rmm_manifest *manifest);
int plat_rmmd_mecid_key_update(uint16_t mecid);
#endif
/*******************************************************************************

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2021-2025, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -161,6 +161,18 @@
#define RMM_EL3_TOKEN_SIGN_PULL_RESP_OP U(2)
#define RMM_EL3_TOKEN_SIGN_GET_RAK_PUB_OP U(3)
/* Starting RMM-EL3 interface version 0.5 */
/*
* Function code to support update of MEC keys.
* The arguments of this SMC are:
* arg0 - Function ID.
* arg1 - MECID
* The return arguments are:
* ret0 - Status/Error
*/
#define RMM_MECID_KEY_UPDATE SMC64_RMMD_EL3_FID(U(6))
/* ECC Curve types for attest key generation */
#define ATTEST_KEY_CURVE_ECC_SECP384R1 U(0)
@ -188,7 +200,7 @@
* Increase this when a bug is fixed, or a feature is added without
* breaking compatibility.
*/
#define RMM_EL3_IFC_VERSION_MINOR (U(4))
#define RMM_EL3_IFC_VERSION_MINOR (U(5))
#define RMM_EL3_INTERFACE_VERSION \
(((RMM_EL3_IFC_VERSION_MAJOR << 16) & 0x7FFFF) | \

View file

@ -7,6 +7,8 @@
#include <assert.h>
#include <string.h>
#include <arch.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/arm/cci.h>
#include <drivers/arm/ccn.h>
@ -775,4 +777,16 @@ int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
return 0;
}
/*
* Update encryption key associated with @mecid.
*/
int plat_rmmd_mecid_key_update(uint16_t mecid)
{
/*
* FVP does not provide an interface to change the encryption key associated
* with MECID. Hence always return success.
*/
return 0;
}
#endif /* ENABLE_RME */

View file

@ -187,6 +187,17 @@ int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
return 0;
}
/*
* Update encryption key associated with @mecid.
*/
int plat_rmmd_mecid_key_update(uint16_t mecid)
{
/*
* TODO
*/
return 0;
}
int plat_rse_comms_init(void)
{
struct mhu_addr mhu_addresses;

View file

@ -400,6 +400,18 @@ int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
return 0;
}
/*
* Update encryption key associated with @mecid.
*/
int plat_rmmd_mecid_key_update(uint16_t mecid)
{
/*
* QEMU does not provide an interface to change the encryption key
* associated with MECID. Hence always return success.
*/
return 0;
}
#endif /* ENABLE_RME */
/**

View file

@ -470,6 +470,33 @@ static int rmm_el3_ifc_get_feat_register(uint64_t feat_reg_idx,
return E_RMM_OK;
}
/*
* Update encryption key associated with @mecid.
*/
static int rmmd_mecid_key_update(uint64_t mecid)
{
uint64_t mecid_width, mecid_width_mask;
int ret;
/*
* Check whether the mecid parameter is at most MECIDR_EL2.MECIDWidthm1 + 1
* in length.
*/
mecid_width = ((read_mecidr_el2() >> MECIDR_EL2_MECIDWidthm1_SHIFT) &
MECIDR_EL2_MECIDWidthm1_MASK) + 1;
mecid_width_mask = ((1 << mecid_width) - 1);
if ((mecid & ~mecid_width_mask) != 0U) {
return E_RMM_INVAL;
}
ret = plat_rmmd_mecid_key_update(mecid);
if (ret != 0) {
return E_RMM_UNK;
}
return E_RMM_OK;
}
/*******************************************************************************
* This function handles RMM-EL3 interface SMCs
******************************************************************************/
@ -519,6 +546,9 @@ uint64_t rmmd_rmm_el3_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
VERBOSE("RMMD: running rmmd_rmm_sync_exit\n");
rmmd_rmm_sync_exit(x1);
case RMM_MECID_KEY_UPDATE:
ret = rmmd_mecid_key_update(x1);
SMC_RET1(handle, ret);
default:
WARN("RMMD: Unsupported RMM-EL3 call 0x%08x\n", smc_fid);
SMC_RET1(handle, SMC_UNK);