Merge changes from topic "ffa_el3_spmc" into integration

* changes:
  feat(spmc): add helper to obtain a partitions FF-A version
  feat(spmd): enable SPMD to forward FFA_VERSION to EL3 SPMC
  feat(spmc): enable handling FFA_VERSION ABI
  feat(spmc): add helper function to obtain endpoint mailbox
  feat(spmc): add helper function to obtain hyp structure
  feat(spmc): enable parsing of messaging methods from manifest
This commit is contained in:
Olivier Deprez 2022-05-10 15:18:36 +02:00 committed by TrustedFirmware Code Review
commit 3d70568089
4 changed files with 118 additions and 2 deletions

View File

@ -38,6 +38,7 @@
#define FFA_VERSION_MINOR_SHIFT 0
#define FFA_VERSION_MINOR_MASK U(0xFFFF)
#define FFA_VERSION_BIT31_MASK U(0x1u << 31)
#define FFA_VERSION_MASK U(0xFFFFFFFF)
#define MAKE_FFA_VERSION(major, minor) \

View File

@ -221,4 +221,10 @@ bool is_ffa_secure_id_valid(uint16_t partition_id);
*/
struct el3_lp_desc *get_el3_lp_array(void);
/*
* Helper function to obtain the RX/TX buffer pair descriptor of the Hypervisor
* or OS kernel in the normal world or the last SP that was run.
*/
struct mailbox *spmc_get_mbox_desc(bool secure_origin);
#endif /* SPMC_H */

View File

@ -72,7 +72,7 @@ struct sp_exec_ctx *spmc_get_sp_ec(struct secure_partition_desc *sp)
/* Helper function to get pointer to SP context from its ID. */
struct secure_partition_desc *spmc_get_sp_ctx(uint16_t id)
{
/* Check for SWd Partitions. */
/* Check for Secure World Partitions. */
for (unsigned int i = 0U; i < SECURE_PARTITION_COUNT; i++) {
if (sp_desc[i].sp_id == id) {
return &(sp_desc[i]);
@ -81,6 +81,29 @@ struct secure_partition_desc *spmc_get_sp_ctx(uint16_t id)
return NULL;
}
/*
* Helper function to obtain the descriptor of the Hypervisor or OS kernel.
* We assume that the first descriptor is reserved for this entity.
*/
struct ns_endpoint_desc *spmc_get_hyp_ctx(void)
{
return &(ns_ep_desc[0]);
}
/*
* Helper function to obtain the RX/TX buffer pair descriptor of the Hypervisor
* or OS kernel in the normal world or the last SP that was run.
*/
struct mailbox *spmc_get_mbox_desc(bool secure_origin)
{
/* Obtain the RX/TX buffer pair descriptor. */
if (secure_origin) {
return &(spmc_get_current_sp_ctx()->mailbox);
} else {
return &(spmc_get_hyp_ctx()->mailbox);
}
}
/******************************************************************************
* This function returns to the place where spmc_sp_synchronous_entry() was
* called originally.
@ -491,6 +514,59 @@ static uint64_t ffa_error_handler(uint32_t smc_fid,
return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
}
static uint64_t ffa_version_handler(uint32_t smc_fid,
bool secure_origin,
uint64_t x1,
uint64_t x2,
uint64_t x3,
uint64_t x4,
void *cookie,
void *handle,
uint64_t flags)
{
uint32_t requested_version = x1 & FFA_VERSION_MASK;
if (requested_version & FFA_VERSION_BIT31_MASK) {
/* Invalid encoding, return an error. */
SMC_RET1(handle, FFA_ERROR_NOT_SUPPORTED);
/* Execution stops here. */
}
/* Determine the caller to store the requested version. */
if (secure_origin) {
/*
* Ensure that the SP is reporting the same version as
* specified in its manifest. If these do not match there is
* something wrong with the SP.
* TODO: Should we abort the SP? For now assert this is not
* case.
*/
assert(requested_version ==
spmc_get_current_sp_ctx()->ffa_version);
} else {
/*
* If this is called by the normal world, record this
* information in its descriptor.
*/
spmc_get_hyp_ctx()->ffa_version = requested_version;
}
SMC_RET1(handle, MAKE_FFA_VERSION(FFA_VERSION_MAJOR,
FFA_VERSION_MINOR));
}
/*******************************************************************************
* Helper function to obtain the FF-A version of the calling partition.
******************************************************************************/
uint32_t get_partition_ffa_version(bool secure_origin)
{
if (secure_origin) {
return spmc_get_current_sp_ctx()->ffa_version;
} else {
return spmc_get_hyp_ctx()->ffa_version;
}
}
/*******************************************************************************
* This function will parse the Secure Partition Manifest. From manifest, it
* will fetch details for preparing Secure partition image context and secure
@ -544,6 +620,23 @@ static int sp_manifest_parse(void *sp_manifest, int offset,
sp->execution_state = config_32;
ret = fdt_read_uint32(sp_manifest, node,
"messaging-method", &config_32);
if (ret != 0) {
ERROR("Missing Secure Partition messaging method.\n");
return ret;
}
/* Validate this entry, we currently only support direct messaging. */
if ((config_32 & ~(FFA_PARTITION_DIRECT_REQ_RECV |
FFA_PARTITION_DIRECT_REQ_SEND)) != 0U) {
WARN("Invalid Secure Partition messaging method (0x%x)\n",
config_32);
return -EINVAL;
}
sp->properties = config_32;
ret = fdt_read_uint32(sp_manifest, node,
"execution-ctx-count", &config_32);
@ -866,6 +959,10 @@ uint64_t spmc_smc_handler(uint32_t smc_fid,
{
switch (smc_fid) {
case FFA_VERSION:
return ffa_version_handler(smc_fid, secure_origin, x1, x2, x3,
x4, cookie, handle, flags);
case FFA_MSG_SEND_DIRECT_REQ_SMC32:
case FFA_MSG_SEND_DIRECT_REQ_SMC64:
return direct_req_smc_handler(smc_fid, secure_origin, x1, x2,

View File

@ -626,7 +626,8 @@ uint64_t spmd_smc_handler(uint32_t smc_fid,
* If caller is secure and SPMC was initialized,
* return FFA_VERSION of SPMD.
* If caller is non secure and SPMC was initialized,
* return SPMC's version.
* forward to the EL3 SPMC if enabled, otherwise return
* the SPMC version if implemented at a lower EL.
* Sanity check to "input_version".
* If the EL3 SPMC is enabled, ignore the SPMC state as
* this is not used.
@ -635,6 +636,17 @@ uint64_t spmd_smc_handler(uint32_t smc_fid,
(!is_spmc_at_el3() && (ctx->state == SPMC_STATE_RESET))) {
ret = FFA_ERROR_NOT_SUPPORTED;
} else if (!secure_origin) {
if (is_spmc_at_el3()) {
/*
* Forward the call directly to the EL3 SPMC, if
* enabled, as we don't need to wrap the call in
* a direct request.
*/
return spmd_smc_forward(smc_fid, secure_origin,
x1, x2, x3, x4, cookie,
handle, flags);
}
gp_regs_t *gpregs = get_gpregs_ctx(&ctx->cpu_ctx);
uint64_t rc;