From e1168bc37563d1f18d6d2a6dc4ed468eadf673f2 Mon Sep 17 00:00:00 2001 From: Levi Yun Date: Wed, 13 Nov 2024 08:35:47 +0000 Subject: [PATCH] feat(el3_spmc): ffa error handling in direct msg When an FFA_ERROR happens while handling a direct message from normal world, return to normal world with FFA_ERROR. Otherwise, the system would re-enter the secure partition with FFA_ERROR. Change-Id: I3d9a68a41b4815c1a8e10354cfcf68fec9f4b800 Signed-off-by: Levi Yun --- services/std_svc/spm/el3_spmc/spmc_main.c | 28 +++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/services/std_svc/spm/el3_spmc/spmc_main.c b/services/std_svc/spm/el3_spmc/spmc_main.c index 9004ef276..b0d6ba66d 100644 --- a/services/std_svc/spm/el3_spmc/spmc_main.c +++ b/services/std_svc/spm/el3_spmc/spmc_main.c @@ -696,6 +696,8 @@ static uint64_t ffa_error_handler(uint32_t smc_fid, { struct secure_partition_desc *sp; unsigned int idx; + uint16_t dst_id = ffa_endpoint_destination(x1); + bool cancel_dir_req = false; /* Check that the response did not originate from the Normal world. */ if (!secure_origin) { @@ -723,6 +725,32 @@ static uint64_t ffa_error_handler(uint32_t smc_fid, panic(); } + if (sp->runtime_el == S_EL0) { + spin_lock(&sp->rt_state_lock); + } + + if (sp->ec[idx].rt_state == RT_STATE_RUNNING && + sp->ec[idx].rt_model == RT_MODEL_DIR_REQ) { + sp->ec[idx].rt_state = RT_STATE_WAITING; + sp->ec[idx].dir_req_origin_id = INV_SP_ID; + sp->ec[idx].dir_req_funcid = 0x00; + cancel_dir_req = true; + } + + if (sp->runtime_el == S_EL0) { + spin_unlock(&sp->rt_state_lock); + } + + if (cancel_dir_req) { + if (dst_id == FFA_SPMC_ID) { + spmc_sp_synchronous_exit(&sp->ec[idx], x4); + /* Should not get here. */ + panic(); + } else + return spmc_smc_return(smc_fid, secure_origin, x1, x2, x3, x4, + handle, cookie, flags, dst_id); + } + return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED); }