From 20fae0a7ce7fd407cd3efb7745017ee6ab605159 Mon Sep 17 00:00:00 2001 From: Marc Bonnici Date: Mon, 29 Nov 2021 17:17:29 +0000 Subject: [PATCH] feat(spmc): add function to determine the return path from the SPMC Use knowledge of the target partition ID and source security state to determine which route should be used to exit the SPMC. There are 3 exit paths: 1) Return to the normal world via the SPMD, this will take care of switching contexts if required. 2) Return to the secure world when the call originated in the normal world and therefore switch contexts. 3) Return to the secure world when the call originated in the secure world, therefore we can return directly. Signed-off-by: Marc Bonnici Change-Id: I4037f3a8a8519e2c9f1876be92806d2c41d0d154 --- services/std_svc/spm/el3_spmc/spmc_main.c | 40 +++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/services/std_svc/spm/el3_spmc/spmc_main.c b/services/std_svc/spm/el3_spmc/spmc_main.c index ddfae95e1..8470cf342 100644 --- a/services/std_svc/spm/el3_spmc/spmc_main.c +++ b/services/std_svc/spm/el3_spmc/spmc_main.c @@ -136,6 +136,46 @@ bool is_ffa_secure_id_valid(uint16_t partition_id) return true; } +/******************************************************************************* + * This function either forwards the request to the other world or returns + * with an ERET depending on the source of the call. + ******************************************************************************/ +static uint64_t spmc_smc_return(uint32_t smc_fid, + bool secure_origin, + uint64_t x1, + uint64_t x2, + uint64_t x3, + uint64_t x4, + void *handle, + void *cookie, + uint64_t flags, + uint16_t dst_id) +{ + /* If the destination is in the normal world always go via the SPMD. */ + if (ffa_is_normal_world_id(dst_id)) { + return spmd_smc_handler(smc_fid, x1, x2, x3, x4, + cookie, handle, flags); + } + /* + * If the caller is secure and we want to return to the secure world, + * ERET directly. + */ + else if (secure_origin && ffa_is_secure_world_id(dst_id)) { + SMC_RET5(handle, smc_fid, x1, x2, x3, x4); + } + /* If we originated in the normal world then switch contexts. */ + else if (!secure_origin && ffa_is_secure_world_id(dst_id)) { + return spmd_smc_switch_state(smc_fid, secure_origin, x1, x2, + x3, x4, handle); + } else { + /* Unknown State. */ + panic(); + } + + /* Shouldn't be Reached. */ + return 0; +} + /******************************************************************************* * This function will parse the Secure Partition Manifest. From manifest, it * will fetch details for preparing Secure partition image context and secure