diff options
author | Julian Hall <julian.hall@arm.com> | 2021-06-24 16:34:23 +0100 |
---|---|---|
committer | Gyorgy Szing <Gyorgy.Szing@arm.com> | 2021-10-05 22:55:45 +0200 |
commit | d03aced2891b8cffdba0517d3119958df0d3b46c (patch) | |
tree | 0315ad14b8338be079c9e4193349116ae6307616 | |
parent | f57289645f3254d9184f3fd676b1a5154794ef1c (diff) | |
download | trusted-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
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 } |