diff options
author | Jelle Sels <jelle.sels@arm.com> | 2021-03-22 16:57:56 +0100 |
---|---|---|
committer | Jérôme Forissier <jerome@forissier.org> | 2021-11-05 11:09:56 +0100 |
commit | 3a7bfc345c1a7cd0abe02b6e5554b25720b86a15 (patch) | |
tree | 5517fa8de23e1bb6fb11dc73a2d7318efd0b895a /core | |
parent | e9907fd739e0b46e0f62f571a36ceaee44fc55f3 (diff) |
core: Add FFA_PARTITION_INFO
FFA_PARTITION_INFO is used to query all the Secure Partitions loaded in
the system.
Signed-off-by: Jelle Sels <jelle.sels@arm.com>
Acked-by: Etienne Carriere <etienne.carriere@linaro.org>
Acked-by: Jens Wiklander <jens.wiklander@linaro.org>
Diffstat (limited to 'core')
-rw-r--r-- | core/arch/arm/include/ffa.h | 11 | ||||
-rw-r--r-- | core/arch/arm/include/kernel/secure_partition.h | 5 | ||||
-rw-r--r-- | core/arch/arm/include/kernel/thread_spmc.h | 6 | ||||
-rw-r--r-- | core/arch/arm/kernel/secure_partition.c | 41 | ||||
-rw-r--r-- | core/arch/arm/kernel/spmc_sp_handler.c | 6 | ||||
-rw-r--r-- | core/arch/arm/kernel/thread_spmc.c | 123 |
6 files changed, 166 insertions, 26 deletions
diff --git a/core/arch/arm/include/ffa.h b/core/arch/arm/include/ffa.h index 20a009ca..0aa91943 100644 --- a/core/arch/arm/include/ffa.h +++ b/core/arch/arm/include/ffa.h @@ -95,6 +95,17 @@ /* Special value for MBZ parameters */ #define FFA_PARAM_MBZ U(0x0) +/* + * Flags used for the FFA_PARTITION_INFO_GET return message: + * BIT(0): Supports receipt of direct requests + * BIT(1): Can send direct requests + * BIT(2): Cannot send and receive indirect messages + * BIT(3): Does not support receipt of notifications + * BIT(4-5): Partition ID is a PE endpoint ID + */ +#define FFA_PARTITION_DIRECT_REQ_RECV_SUPPORT BIT(0) +#define FFA_PARTITION_DIRECT_REQ_SEND_SUPPORT BIT(1) + #ifndef __ASSEMBLER__ /* Constituent memory region descriptor */ struct ffa_address_range { diff --git a/core/arch/arm/include/kernel/secure_partition.h b/core/arch/arm/include/kernel/secure_partition.h index e153faa6..25937f4c 100644 --- a/core/arch/arm/include/kernel/secure_partition.h +++ b/core/arch/arm/include/kernel/secure_partition.h @@ -7,6 +7,7 @@ #include <assert.h> #include <config.h> +#include <ffa.h> #include <kernel/embedded_ts.h> #include <kernel/thread_spmc.h> #include <kernel/user_mode_ctx_struct.h> @@ -73,6 +74,10 @@ static inline struct sp_ctx *to_sp_ctx(struct ts_ctx *ctx) struct sp_session *sp_get_session(uint32_t session_id); TEE_Result sp_enter(struct thread_smc_args *args, struct sp_session *sp); +TEE_Result sp_partition_info_get_all(struct ffa_partition_info *fpi, + size_t *elem_count); + +TEE_Result sp_find_session_id(const TEE_UUID *uuid, uint32_t *session_id); #define for_each_secure_partition(_sp) \ SCATTERED_ARRAY_FOREACH(_sp, sp_images, struct embedded_ts) diff --git a/core/arch/arm/include/kernel/thread_spmc.h b/core/arch/arm/include/kernel/thread_spmc.h index 3e361c23..38f8abd8 100644 --- a/core/arch/arm/include/kernel/thread_spmc.h +++ b/core/arch/arm/include/kernel/thread_spmc.h @@ -5,6 +5,7 @@ #ifndef __KERNEL_THREAD_SPMC_H #define __KERNEL_THREAD_SPMC_H +#include <ffa.h> #include <kernel/thread.h> /* FF-A endpoint base ID when OP-TEE is used as a S-EL1 endpoint */ @@ -25,4 +26,9 @@ void spmc_handle_version(struct thread_smc_args *args); void spmc_set_args(struct thread_smc_args *args, uint32_t fid, uint32_t src_dst, uint32_t w2, uint32_t w3, uint32_t w4, uint32_t w5); +void spmc_handle_partition_info_get(struct thread_smc_args *args, + struct ffa_rxtx *rxtx); +void spmc_fill_partition_entry(struct ffa_partition_info *fpi, + uint16_t endpoint_id, + uint16_t execution_context); #endif /* __KERNEL_THREAD_SPMC_H */ diff --git a/core/arch/arm/kernel/secure_partition.c b/core/arch/arm/kernel/secure_partition.c index b064c27b..977f1e51 100644 --- a/core/arch/arm/kernel/secure_partition.c +++ b/core/arch/arm/kernel/secure_partition.c @@ -56,6 +56,23 @@ static void set_sp_ctx_ops(struct ts_ctx *ctx) ctx->ops = &sp_ops; } +TEE_Result sp_find_session_id(const TEE_UUID *uuid, uint32_t *session_id) +{ + struct sp_session *s = NULL; + + TAILQ_FOREACH(s, &open_sp_sessions, link) { + if (!memcmp(&s->ts_sess.ctx->uuid, uuid, sizeof(*uuid))) { + if (s->state == sp_dead) + return TEE_ERROR_TARGET_DEAD; + + *session_id = s->endpoint_id; + return TEE_SUCCESS; + } + } + + return TEE_ERROR_ITEM_NOT_FOUND; +} + struct sp_session *sp_get_session(uint32_t session_id) { struct sp_session *s = NULL; @@ -68,6 +85,30 @@ struct sp_session *sp_get_session(uint32_t session_id) return NULL; } +TEE_Result sp_partition_info_get_all(struct ffa_partition_info *fpi, + size_t *elem_count) +{ + size_t in_count = *elem_count; + struct sp_session *s = NULL; + size_t count = 0; + + TAILQ_FOREACH(s, &open_sp_sessions, link) { + if (s->state == sp_dead) + continue; + if (count < in_count) { + spmc_fill_partition_entry(fpi, s->endpoint_id, 1); + fpi++; + } + count++; + } + + *elem_count = count; + if (count > in_count) + return TEE_ERROR_SHORT_BUFFER; + + return TEE_SUCCESS; +} + static void sp_init_info(struct sp_ctx *ctx, struct thread_smc_args *args) { struct sp_ffa_init_info *info = NULL; diff --git a/core/arch/arm/kernel/spmc_sp_handler.c b/core/arch/arm/kernel/spmc_sp_handler.c index fcf86509..041e4351 100644 --- a/core/arch/arm/kernel/spmc_sp_handler.c +++ b/core/arch/arm/kernel/spmc_sp_handler.c @@ -276,6 +276,12 @@ void spmc_sp_msg_handler(struct thread_smc_args *args, handle_features(args); sp_enter(args, caller_sp); break; + case FFA_PARTITION_INFO_GET: + ts_push_current_session(&caller_sp->ts_sess); + spmc_handle_partition_info_get(args, &caller_sp->rxtx); + ts_pop_current_session(); + sp_enter(args, caller_sp); + break; default: EMSG("Unhandled FFA function ID %#"PRIx32, (uint32_t)args->a0); diff --git a/core/arch/arm/kernel/thread_spmc.c b/core/arch/arm/kernel/thread_spmc.c index 1901a3a7..0cea7380 100644 --- a/core/arch/arm/kernel/thread_spmc.c +++ b/core/arch/arm/kernel/thread_spmc.c @@ -24,6 +24,7 @@ #include <string.h> #include <sys/queue.h> #include <tee/entry_std.h> +#include <tee/uuid.h> #include <util.h> #include "thread_private.h" @@ -326,46 +327,116 @@ static bool is_my_uuid(uint32_t w0, uint32_t w1, uint32_t w2, uint32_t w3) w2 == 0x02005ebc && w3 == 0x1bc5d5a5; } -static void handle_partition_info_get(struct thread_smc_args *args, - struct ffa_rxtx *rxtx) +void spmc_fill_partition_entry(struct ffa_partition_info *fpi, + uint16_t endpoint_id, uint16_t execution_context) { - uint32_t ret_fid = 0; - int rc = 0; + fpi->id = endpoint_id; + /* Number of execution contexts implemented by this partition */ + fpi->execution_context = execution_context; - if (!is_nil_uuid(args->a1, args->a2, args->a3, args->a4) && - !is_my_uuid(args->a1, args->a2, args->a3, args->a4)) { - ret_fid = FFA_ERROR; - rc = FFA_INVALID_PARAMETERS; - goto out; + fpi->partition_properties = FFA_PARTITION_DIRECT_REQ_RECV_SUPPORT | + FFA_PARTITION_DIRECT_REQ_SEND_SUPPORT; +} + +static uint32_t handle_partition_info_get_all(size_t *elem_count, + struct ffa_rxtx *rxtx) +{ + struct ffa_partition_info *fpi = rxtx->tx; + + /* Add OP-TEE SP */ + spmc_fill_partition_entry(fpi, my_endpoint_id, CFG_TEE_CORE_NB_CORE); + rxtx->tx_is_mine = false; + *elem_count = 1; + fpi++; + + if (IS_ENABLED(CFG_SECURE_PARTITION)) { + size_t count = (rxtx->size / sizeof(*fpi)) - 1; + + if (sp_partition_info_get_all(fpi, &count)) + return FFA_NO_MEMORY; + *elem_count += count; } - cpu_spin_lock(&rxtx->spinlock); - if (rxtx->size && rxtx->tx_is_mine) { - struct ffa_partition_info *fpi = rxtx->tx; + return FFA_OK; +} - fpi->id = my_endpoint_id; - fpi->execution_context = CFG_TEE_CORE_NB_CORE; - /* - * Supports receipt of direct requests. - * Can send direct requests. - */ - fpi->partition_properties = BIT(0) | BIT(1); +void spmc_handle_partition_info_get(struct thread_smc_args *args, + struct ffa_rxtx *rxtx) +{ + uint32_t ret_fid = FFA_ERROR; + uint32_t rc = 0; + uint32_t endpoint_id = my_endpoint_id; + struct ffa_partition_info *fpi = NULL; - ret_fid = FFA_SUCCESS_32; - rc = 1; - rxtx->tx_is_mine = false; - } else { - ret_fid = FFA_ERROR; + cpu_spin_lock(&rxtx->spinlock); + + if (!rxtx->size || !rxtx->tx_is_mine) { if (rxtx->size) rc = FFA_BUSY; else rc = FFA_DENIED; /* TX buffer not setup yet */ + goto out; } - cpu_spin_unlock(&rxtx->spinlock); + + fpi = rxtx->tx; + + if (rxtx->size < sizeof(*fpi)) { + ret_fid = FFA_ERROR; + rc = FFA_NO_MEMORY; + goto out; + } + + if (is_nil_uuid(args->a1, args->a2, args->a3, args->a4)) { + size_t elem_count = 0; + + ret_fid = handle_partition_info_get_all(&elem_count, rxtx); + + if (ret_fid) { + rc = ret_fid; + ret_fid = FFA_ERROR; + } else { + ret_fid = FFA_SUCCESS_32; + rc = elem_count; + } + + goto out; + } + + if (is_my_uuid(args->a1, args->a2, args->a3, args->a4)) { + spmc_fill_partition_entry(fpi, endpoint_id, + CFG_TEE_CORE_NB_CORE); + } else if (IS_ENABLED(CFG_SECURE_PARTITION)) { + uint32_t uuid_array[4] = { 0 }; + TEE_UUID uuid = { }; + TEE_Result res = TEE_SUCCESS; + + uuid_array[0] = args->a1; + uuid_array[1] = args->a2; + uuid_array[2] = args->a3; + uuid_array[3] = args->a4; + tee_uuid_from_octets(&uuid, (uint8_t *)uuid_array); + + res = sp_find_session_id(&uuid, &endpoint_id); + if (res != TEE_SUCCESS) { + ret_fid = FFA_ERROR; + rc = FFA_INVALID_PARAMETERS; + goto out; + } + spmc_fill_partition_entry(fpi, endpoint_id, 1); + } else { + ret_fid = FFA_ERROR; + rc = FFA_INVALID_PARAMETERS; + goto out; + } + + ret_fid = FFA_SUCCESS_32; + rxtx->tx_is_mine = false; + rc = 1; out: spmc_set_args(args, ret_fid, FFA_PARAM_MBZ, rc, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ); + cpu_spin_unlock(&rxtx->spinlock); } #endif /*CFG_CORE_SEL1_SPMC*/ @@ -871,7 +942,7 @@ void thread_spmc_msg_recv(struct thread_smc_args *args) spmc_handle_rx_release(args, &nw_rxtx); break; case FFA_PARTITION_INFO_GET: - handle_partition_info_get(args, &nw_rxtx); + spmc_handle_partition_info_get(args, &nw_rxtx); break; #endif /*CFG_CORE_SEL1_SPMC*/ case FFA_INTERRUPT: |