aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Hall <julian.hall@arm.com>2021-06-24 16:34:23 +0100
committerGyorgy Szing <Gyorgy.Szing@arm.com>2021-10-05 22:55:45 +0200
commitd03aced2891b8cffdba0517d3119958df0d3b46c (patch)
tree0315ad14b8338be079c9e4193349116ae6307616
parentf57289645f3254d9184f3fd676b1a5154794ef1c (diff)
downloadtrusted-services-d03aced2891b8cffdba0517d3119958df0d3b46c.tar.gz
Extend ffa service location to support interface id
To support multiple services co-located in a single SP, the service location strategy for locating FFA accessed services has been extended to provide the interface id as well as the partition id for a discovered service endpoint. Signed-off-by: Julian Hall <julian.hall@arm.com> Change-Id: Idc0ee431dcf0809cdad1d795e85545ea12b79981
-rw-r--r--components/service/locator/linux/ffa/linuxffa_location_strategy.c217
-rw-r--r--components/service/locator/linux/ffa/linuxffa_service_context.c9
-rw-r--r--components/service/locator/linux/ffa/linuxffa_service_context.h8
3 files changed, 134 insertions, 100 deletions
diff --git a/components/service/locator/linux/ffa/linuxffa_location_strategy.c b/components/service/locator/linux/ffa/linuxffa_location_strategy.c
index 96e73d7df..8fce44eb5 100644
--- a/components/service/locator/linux/ffa/linuxffa_location_strategy.c
+++ b/components/service/locator/linux/ffa/linuxffa_location_strategy.c
@@ -29,139 +29,168 @@
*/
#define MAX_PARTITION_INSTANCES (4)
-static struct service_context *query(const char *sn, int *status);
-static size_t suggest_tf_org_partition_uuids(const char *sn, struct uuid_canonical *uuids, size_t uuid_limit);
-static size_t use_ffa_partition_uuid(const char *sn, struct uuid_canonical *uuids, size_t uuid_limit);
-static bool discover_partition(const char *sn, struct uuid_canonical *uuid, const char *dev_path, uint16_t *partition_id);
+/*
+ * Structure to specify the location of a service endpoint reachable via FFA.
+ */
+struct ffa_service_location
+{
+ struct uuid_canonical uuid;
+ uint16_t iface_id;
+};
+
+
+static struct service_context *query(const char *sn,
+ int *status);
+static size_t suggest_tf_org_partition_uuids(const char *sn,
+ struct ffa_service_location *candidates, size_t candidate_limit);
+static size_t use_ffa_partition_uuid(const char *sn,
+ struct ffa_service_location *candidates, size_t candidate_limit);
+static bool discover_partition(const char *sn,
+ struct uuid_canonical *uuid, const char *dev_path, uint16_t *partition_id);
const struct service_location_strategy *linuxffa_location_strategy(void)
{
- static const struct service_location_strategy strategy = { query };
- return &strategy;
+ static const struct service_location_strategy strategy = { query };
+ return &strategy;
}
static struct service_context *query(const char *sn, int *status)
{
- struct service_context *result = NULL;
- struct uuid_canonical uuids[MAX_PARTITION_SUGGESTIONS];
- size_t num_suggestons = 0;
- size_t suggeston_index;
+ struct service_context *result = NULL;
+ struct ffa_service_location candidate_locations[MAX_PARTITION_SUGGESTIONS];
+ size_t num_suggestons = 0;
+ size_t suggeston_index;
+
+ /* Determine one or more candidate partition UUIDs from the specified service name. */
+ if (sn_check_authority(sn, "trustedfirmware.org")) {
+ num_suggestons =
+ suggest_tf_org_partition_uuids(sn, candidate_locations, MAX_PARTITION_SUGGESTIONS);
+ }
+ else if (sn_check_authority(sn, "ffa")) {
+ num_suggestons =
+ use_ffa_partition_uuid(sn, candidate_locations, MAX_PARTITION_SUGGESTIONS);
+ }
+
+ /* Attempt to discover suitable partitions */
+ for (suggeston_index = 0; suggeston_index < num_suggestons; ++suggeston_index) {
+
+ uint16_t partition_id;
+ const char *dev_path = "/sys/kernel/debug/arm_ffa_user";
+
+ if (discover_partition(sn, &candidate_locations[suggeston_index].uuid,
+ dev_path, &partition_id)) {
+
+ struct linuxffa_service_context *new_context =
+ linuxffa_service_context_create(dev_path,
+ partition_id, candidate_locations[suggeston_index].iface_id);
+
+ if (new_context) result = &new_context->service_context;
+ break;
+ }
+ }
+
+ return result;
+}
- /* Determine one or more candidate partition UUIDs from the specified service name. */
- if (sn_check_authority(sn, "trustedfirmware.org")) {
- num_suggestons = suggest_tf_org_partition_uuids(sn, uuids, MAX_PARTITION_SUGGESTIONS);
- }
- else if (sn_check_authority(sn, "ffa")) {
- num_suggestons = use_ffa_partition_uuid(sn, uuids, MAX_PARTITION_SUGGESTIONS);
- }
+/*
+ * Returns a list of partition UUIDs and interface IDs to identify partitions that
+ * could potentially host the requested service. This mapping is based trustedfirmware.org
+ * ffa partition UUIDs. There may be multiple UUIDs because of different depeloyment decisions
+ * such as dedicated SP, SP hosting multple services.
+ */
+static size_t suggest_tf_org_partition_uuids(const char *sn,
+ struct ffa_service_location *candidates, size_t candidate_limit)
+{
+ const struct service_to_uuid
+ {
+ const char *service;
+ const char *uuid;
+ uint16_t iface_id;
+ }
+ partition_lookup[] =
+ {
+ {"crypto", "d9df52d5-16a2-4bb2-9aa4-d26d3b84e8c0", 0},
+ {"internal-trusted-storage", "dc1eef48-b17a-4ccf-ac8b-dfcff7711b14", 0},
+ {"protected-storage", "751bf801-3dde-4768-a514-0f10aeed1790", 0},
+ {"test-runner", "33c75baf-ac6a-4fe4-8ac7-e9909bee2d17", 0},
+ {"attestation", "a1baf155-8876-4695-8f7c-54955e8db974", 0},
+ {NULL, NULL, 0}
+ };
- /* Attempt to discover suitable partitions */
- for (suggeston_index = 0; suggeston_index < num_suggestons; ++suggeston_index) {
+ const struct service_to_uuid *entry = &partition_lookup[0];
+ size_t num_suggestions = 0;
- uint16_t partition_id;
- const char *dev_path = "/sys/kernel/debug/arm_ffa_user";
+ while (entry->service && (num_suggestions < candidate_limit)) {
- if (discover_partition(sn, &uuids[suggeston_index], dev_path, &partition_id)) {
+ if (sn_check_service(sn, entry->service)) {
- struct linuxffa_service_context *new_context = linuxffa_service_context_create(dev_path, partition_id);
+ memcpy(candidates[num_suggestions].uuid.characters, entry->uuid,
+ UUID_CANONICAL_FORM_LEN + 1);
- if (new_context) result = &new_context->service_context;
- break;
- }
- }
+ candidates[num_suggestions].iface_id = entry->iface_id;
- return result;
-}
+ ++num_suggestions;
+ }
-/*
- * Returns a list of partition UUIDs to identify partitions that could potentially host the
- * requested service. This mapping is based trustedfirmware.org ffa partition UUIDs. There
- * may be multiple UUIDs because of different depeloyment decisions such as dedicated SP,
- * SP hosting multple services.
- */
-static size_t suggest_tf_org_partition_uuids(const char *sn, struct uuid_canonical *uuids, size_t uuid_limit)
-{
- const struct service_to_uuid
- {
- const char *service;
- const char *uuid;
- }
- partition_lookup[] =
- {
- {"crypto", "d9df52d5-16a2-4bb2-9aa4-d26d3b84e8c0"},
- {"internal-trusted-storage", "dc1eef48-b17a-4ccf-ac8b-dfcff7711b14"},
- {"protected-storage", "751bf801-3dde-4768-a514-0f10aeed1790"},
- {"test-runner", "33c75baf-ac6a-4fe4-8ac7-e9909bee2d17"},
- {"attestation", "a1baf155-8876-4695-8f7c-54955e8db974"},
- {NULL, NULL}
- };
-
- const struct service_to_uuid *entry = &partition_lookup[0];
- size_t num_suggestions = 0;
-
- while (entry->service && (num_suggestions < uuid_limit)) {
-
- if (sn_check_service(sn, entry->service)) {
-
- memcpy(uuids[num_suggestions].characters, entry->uuid, UUID_CANONICAL_FORM_LEN + 1);
- ++num_suggestions;
- }
-
- ++entry;
- }
-
- return num_suggestions;
+ ++entry;
+ }
+
+ return num_suggestions;
}
/*
* When an ffa service name where the service field is an explicit UUID is used, the UUID
* is used directly for partition discovery.
*/
-static size_t use_ffa_partition_uuid(const char *sn, struct uuid_canonical *uuids, size_t uuid_limit)
+static size_t use_ffa_partition_uuid(const char *sn,
+ struct ffa_service_location *candidates, size_t candidate_limit)
{
- size_t num_suggestions = 0;
+ size_t num_suggestions = 0;
+
+ if ((num_suggestions < candidate_limit) &&
+ (sn_read_service(sn, candidates[num_suggestions].uuid.characters,
+ UUID_CANONICAL_FORM_LEN + 1) == UUID_CANONICAL_FORM_LEN)) {
- if ((num_suggestions < uuid_limit) &&
- (sn_read_service(sn, uuids[num_suggestions].characters, UUID_CANONICAL_FORM_LEN + 1) == UUID_CANONICAL_FORM_LEN)) {
+ candidates[num_suggestions].iface_id = 0;
- ++num_suggestions;
- }
+ ++num_suggestions;
+ }
- return num_suggestions;
+ return num_suggestions;
}
/*
* Attempt to discover the partition that hosts the requested service instance.
*/
-static bool discover_partition(const char *sn, struct uuid_canonical *uuid,
- const char *dev_path, uint16_t *partition_id)
+static bool discover_partition(const char *sn,
+ struct uuid_canonical *uuid, const char *dev_path, uint16_t *partition_id)
{
- bool discovered = false;
+ bool discovered = false;
- if (uuid_is_valid(uuid->characters) == UUID_CANONICAL_FORM_LEN) {
+ if (uuid_is_valid(uuid->characters) == UUID_CANONICAL_FORM_LEN) {
- struct ffarpc_caller ffarpc_caller;
- unsigned int required_instance = sn_get_service_instance(sn);
+ struct ffarpc_caller ffarpc_caller;
+ unsigned int required_instance = sn_get_service_instance(sn);
- if (!ffarpc_caller_check_version())
- return false;
+ if (!ffarpc_caller_check_version())
+ return false;
- ffarpc_caller_init(&ffarpc_caller, dev_path);
+ ffarpc_caller_init(&ffarpc_caller, dev_path);
- uint16_t discovered_partitions[MAX_PARTITION_INSTANCES];
- size_t discovered_count;
+ uint16_t discovered_partitions[MAX_PARTITION_INSTANCES];
+ size_t discovered_count;
- discovered_count = ffarpc_caller_discover(&ffarpc_caller, uuid,
- discovered_partitions, MAX_PARTITION_INSTANCES);
+ discovered_count = ffarpc_caller_discover(&ffarpc_caller, uuid,
+ discovered_partitions, MAX_PARTITION_INSTANCES);
- if ((discovered_count > 0) && (required_instance < discovered_count)) {
+ if ((discovered_count > 0) && (required_instance < discovered_count)) {
- *partition_id = discovered_partitions[required_instance];
- discovered = true;
- }
+ *partition_id = discovered_partitions[required_instance];
+ discovered = true;
+ }
- ffarpc_caller_deinit(&ffarpc_caller);
- }
+ ffarpc_caller_deinit(&ffarpc_caller);
+ }
- return discovered;
+ return discovered;
}
diff --git a/components/service/locator/linux/ffa/linuxffa_service_context.c b/components/service/locator/linux/ffa/linuxffa_service_context.c
index 524259328..ae558412c 100644
--- a/components/service/locator/linux/ffa/linuxffa_service_context.c
+++ b/components/service/locator/linux/ffa/linuxffa_service_context.c
@@ -15,7 +15,7 @@ static void linuxffa_service_context_relinquish(void *context);
struct linuxffa_service_context *linuxffa_service_context_create(const char *dev_path,
- uint16_t partition_id)
+ uint16_t partition_id, uint16_t iface_id)
{
struct linuxffa_service_context *new_context =
(struct linuxffa_service_context*)malloc(sizeof(struct linuxffa_service_context));
@@ -23,6 +23,7 @@ struct linuxffa_service_context *linuxffa_service_context_create(const char *dev
if (new_context) {
new_context->ffa_dev_path = dev_path;
new_context->partition_id = partition_id;
+ new_context->iface_id = iface_id;
new_context->service_context.context = new_context;
new_context->service_context.open = linuxffa_service_context_open;
@@ -37,13 +38,15 @@ static rpc_session_handle linuxffa_service_context_open(void *context, struct rp
{
struct linuxffa_service_context *this_context = (struct linuxffa_service_context*)context;
rpc_session_handle session_handle = NULL;
- struct ffarpc_caller *ffarpc_caller = (struct ffarpc_caller*)malloc(sizeof(struct ffarpc_caller));
+ struct ffarpc_caller *ffarpc_caller =
+ (struct ffarpc_caller*)malloc(sizeof(struct ffarpc_caller));
if (ffarpc_caller) {
int status;
*caller = ffarpc_caller_init(ffarpc_caller, this_context->ffa_dev_path);
- status = ffarpc_caller_open(ffarpc_caller, this_context->partition_id, 0);
+ status = ffarpc_caller_open(ffarpc_caller,
+ this_context->partition_id, this_context->iface_id);
if (status == 0) {
/* Successfully opened session */
diff --git a/components/service/locator/linux/ffa/linuxffa_service_context.h b/components/service/locator/linux/ffa/linuxffa_service_context.h
index a16fe13ea..d2e6753c7 100644
--- a/components/service/locator/linux/ffa/linuxffa_service_context.h
+++ b/components/service/locator/linux/ffa/linuxffa_service_context.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -23,13 +23,15 @@ struct linuxffa_service_context
struct service_context service_context;
const char *ffa_dev_path;
uint16_t partition_id;
+ uint16_t iface_id;
};
/*
* Factory method to create a service context associated with theh specified
- * partition id.
+ * partition id and RPC interface instance.
*/
-struct linuxffa_service_context *linuxffa_service_context_create(const char *dev_path, uint16_t partition_id);
+struct linuxffa_service_context *linuxffa_service_context_create(const char *dev_path,
+ uint16_t partition_id, uint16_t iface_id);
#ifdef __cplusplus
}