aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Hall <julian.hall@arm.com>2021-08-13 10:47:31 +0100
committerGyorgy Szing <Gyorgy.Szing@arm.com>2021-10-06 00:49:15 +0200
commitc203872fe81bbef0c66f0b0d86ccbb84743238f1 (patch)
treec23f188a49dbc4bf7eaf667b45f72ff65aeb6f6c
parentec7e5843250cf64ca08c4ddb14f39a3acd2aee81 (diff)
downloadtrusted-services-c203872fe81bbef0c66f0b0d86ccbb84743238f1.tar.gz
Add service locator strategy for SP to SP discoverytopics/spmc_test
Using the service locator framework, a new service locator strategy is added that is suitable for use from within an SP to discover other service endpoints reachable via FFA. The required destination SP may be hardcoded in the client SP or passed in as a configuration parameter. Signed-off-by: Julian Hall <julian.hall@arm.com> Change-Id: If8cd3cd60e43b0f150c5f850211152fec0139f07
-rw-r--r--components/service/locator/sp/component.cmake13
-rw-r--r--components/service/locator/sp/ffa/component.cmake14
-rw-r--r--components/service/locator/sp/ffa/spffa_location_strategy.c99
-rw-r--r--components/service/locator/sp/ffa/spffa_location_strategy.h27
-rw-r--r--components/service/locator/sp/ffa/spffa_service_context.c82
-rw-r--r--components/service/locator/sp/ffa/spffa_service_context.h40
-rw-r--r--components/service/locator/sp/sp_env.c18
7 files changed, 293 insertions, 0 deletions
diff --git a/components/service/locator/sp/component.cmake b/components/service/locator/sp/component.cmake
new file mode 100644
index 000000000..7337b3b61
--- /dev/null
+++ b/components/service/locator/sp/component.cmake
@@ -0,0 +1,13 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+ message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+target_sources(${TGT} PRIVATE
+ "${CMAKE_CURRENT_LIST_DIR}/sp_env.c"
+ )
diff --git a/components/service/locator/sp/ffa/component.cmake b/components/service/locator/sp/ffa/component.cmake
new file mode 100644
index 000000000..6cdfccd16
--- /dev/null
+++ b/components/service/locator/sp/ffa/component.cmake
@@ -0,0 +1,14 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+ message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+target_sources(${TGT} PRIVATE
+ "${CMAKE_CURRENT_LIST_DIR}/spffa_location_strategy.c"
+ "${CMAKE_CURRENT_LIST_DIR}/spffa_service_context.c"
+ )
diff --git a/components/service/locator/sp/ffa/spffa_location_strategy.c b/components/service/locator/sp/ffa/spffa_location_strategy.c
new file mode 100644
index 000000000..71319d949
--- /dev/null
+++ b/components/service/locator/sp/ffa/spffa_location_strategy.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include "spffa_location_strategy.h"
+#include "spffa_service_context.h"
+#include <common/uuid/uuid.h>
+#include <service/locator/service_name.h>
+#include <rpc/ffarpc/caller/sp/ffarpc_caller.h>
+#include <trace.h>
+
+static struct service_context *query(const char *sn, int *status);
+static bool discover_partition(const struct uuid_octets *uuid, uint16_t *partition_id);
+
+const struct service_location_strategy *spffa_location_strategy(void)
+{
+ static const struct service_location_strategy strategy = { query };
+ return &strategy;
+}
+
+/**
+ * This service location strategy is intended for locating other service
+ * endpoints reachable via FFA from within a client secure partition where
+ * associated service endpoints are explicitly defined by configuration data.
+ * The service to locate is specified by a service name that consists of a
+ * UUID and an optional instance number. If pesent, the instance number
+ * is treated as the destination RPC interface id. If not specified,
+ * an interface id of zero is assumed.
+ */
+static struct service_context *query(const char *sn, int *status)
+{
+ struct service_context *result = NULL;
+
+ /* This strategy only locates endpoints reachable via FFA */
+ if (sn_check_authority(sn, "ffa")) {
+
+ struct uuid_canonical uuid;
+
+ if (sn_read_service(sn, uuid.characters, UUID_CANONICAL_FORM_LEN + 1) &&
+ uuid_is_valid(uuid.characters)) {
+
+ uint16_t partition_id;
+ struct uuid_octets uuid_octets;
+
+ uuid_parse_to_octets(uuid.characters, uuid_octets.octets, UUID_OCTETS_LEN);
+
+ if (discover_partition(&uuid_octets, &partition_id)) {
+
+ unsigned int iface_id =
+ sn_get_service_instance(sn);
+
+ struct spffa_service_context *new_context =
+ spffa_service_context_create(partition_id, iface_id);
+
+ if (new_context) {
+
+ result = &new_context->service_context;
+ }
+ else {
+
+ EMSG("locate query: context create failed");
+ }
+ }
+ else {
+
+ EMSG("locate query: partition not discovered");
+ }
+ }
+ else {
+
+ EMSG("locate query: invalid uuid");
+ }
+ }
+
+ return result;
+}
+
+static bool discover_partition(const struct uuid_octets *uuid, uint16_t *partition_id)
+{
+ bool discovered = false;
+ struct ffarpc_caller ffarpc_caller;
+ uint16_t discovered_partitions[1];
+
+ ffarpc_caller_init(&ffarpc_caller);
+
+ if (ffarpc_caller_discover(uuid->octets,
+ discovered_partitions, sizeof(discovered_partitions)/sizeof(uint16_t))) {
+
+ *partition_id = discovered_partitions[0];
+ discovered = true;
+ }
+
+ ffarpc_caller_deinit(&ffarpc_caller);
+
+ return discovered;
+}
diff --git a/components/service/locator/sp/ffa/spffa_location_strategy.h b/components/service/locator/sp/ffa/spffa_location_strategy.h
new file mode 100644
index 000000000..edaf76b30
--- /dev/null
+++ b/components/service/locator/sp/ffa/spffa_location_strategy.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPFFA_LOCATION_STRATEGY_H
+#define SPFFA_LOCATION_STRATEGY_H
+
+#include <service_locator.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Returns a service_location_strategy for locating a service instance
+ * hosted in a secure partition, accessed using FFA from another secure
+ * partition.
+ */
+const struct service_location_strategy *spffa_location_strategy(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SPFFA_LOCATION_STRATEGY_H */
diff --git a/components/service/locator/sp/ffa/spffa_service_context.c b/components/service/locator/sp/ffa/spffa_service_context.c
new file mode 100644
index 000000000..21cf72fd6
--- /dev/null
+++ b/components/service/locator/sp/ffa/spffa_service_context.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "spffa_service_context.h"
+#include <rpc/ffarpc/caller/sp/ffarpc_caller.h>
+#include <stdlib.h>
+
+/* Concrete service_context methods */
+static rpc_session_handle spffa_service_context_open(void *context, struct rpc_caller **caller);
+static void spffa_service_context_close(void *context, rpc_session_handle session_handle);
+static void spffa_service_context_relinquish(void *context);
+
+
+struct spffa_service_context *spffa_service_context_create(
+ uint16_t partition_id, uint16_t iface_id)
+{
+ struct spffa_service_context *new_context =
+ (struct spffa_service_context*)malloc(sizeof(struct spffa_service_context));
+
+ if (new_context) {
+ new_context->partition_id = partition_id;
+ new_context->iface_id = iface_id;
+
+ new_context->service_context.context = new_context;
+ new_context->service_context.open = spffa_service_context_open;
+ new_context->service_context.close = spffa_service_context_close;
+ new_context->service_context.relinquish = spffa_service_context_relinquish;
+ }
+
+ return new_context;
+}
+
+static rpc_session_handle spffa_service_context_open(void *context, struct rpc_caller **caller)
+{
+ struct spffa_service_context *this_context = (struct spffa_service_context*)context;
+ rpc_session_handle session_handle = NULL;
+ struct ffarpc_caller *ffarpc_caller =
+ (struct ffarpc_caller*)malloc(sizeof(struct ffarpc_caller));
+
+ if (ffarpc_caller) {
+
+ *caller = ffarpc_caller_init(ffarpc_caller);
+ int status = ffarpc_caller_open(ffarpc_caller,
+ this_context->partition_id, this_context->iface_id);
+
+ if (status == 0) {
+ /* Successfully opened session */
+ session_handle = ffarpc_caller;
+ }
+ else {
+ /* Failed to open session */
+ ffarpc_caller_close(ffarpc_caller);
+ ffarpc_caller_deinit(ffarpc_caller);
+ free(ffarpc_caller);
+ }
+ }
+
+ return session_handle;
+}
+
+static void spffa_service_context_close(void *context, rpc_session_handle session_handle)
+{
+ struct ffarpc_caller *ffarpc_caller = (struct ffarpc_caller*)session_handle;
+
+ (void)context;
+
+ if (ffarpc_caller) {
+
+ ffarpc_caller_close(ffarpc_caller);
+ ffarpc_caller_deinit(ffarpc_caller);
+ free(ffarpc_caller);
+ }
+}
+
+static void spffa_service_context_relinquish(void *context)
+{
+ struct spffa_service_context *this_context = (struct spffa_service_context*)context;
+ free(this_context);
+}
diff --git a/components/service/locator/sp/ffa/spffa_service_context.h b/components/service/locator/sp/ffa/spffa_service_context.h
new file mode 100644
index 000000000..26e6fb9d6
--- /dev/null
+++ b/components/service/locator/sp/ffa/spffa_service_context.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPFFA_SERVICE_CONTEXT_H
+#define SPFFA_SERVICE_CONTEXT_H
+
+#include <service_locator.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * A service_context that represents a service instance located in
+ * a partition, accessed via FFA. This service_context is suitable
+ * for use by client applications running in a secure partition.
+ */
+struct spffa_service_context
+{
+ struct service_context service_context;
+ uint16_t partition_id;
+ uint16_t iface_id;
+};
+
+/*
+ * Factory method to create a service context associated with the specified
+ * partition id and RPC interface instance.
+ */
+struct spffa_service_context *spffa_service_context_create(
+ uint16_t partition_id,
+ uint16_t iface_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SPFFA_SERVICE_CONTEXT_H */
diff --git a/components/service/locator/sp/sp_env.c b/components/service/locator/sp/sp_env.c
new file mode 100644
index 000000000..51507cb35
--- /dev/null
+++ b/components/service/locator/sp/sp_env.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <service_locator.h>
+#include <service/locator/sp/ffa/spffa_location_strategy.h>
+
+
+void service_locator_envinit(void)
+{
+ /*
+ * Register all service location strategies that could be used
+ * to locate services from a secure partition.
+ */
+ service_locator_register_strategy(spffa_location_strategy());
+}