From patchwork Wed Jun 1 08:27:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Etienne Carriere X-Patchwork-Id: 577786 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:8f0c:0:0:0:0 with SMTP id mq12csp358951mab; Wed, 1 Jun 2022 01:28:41 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyCatZe63KC4mLum3eMPE8nw0BQO7pzfO6VXOuoCsp1SKbBh08Lrb6BZPgJm0Sx3z+zmlrv X-Received: by 2002:a92:c70f:0:b0:2d3:956a:b0e7 with SMTP id a15-20020a92c70f000000b002d3956ab0e7mr10561007ilp.320.1654072121148; Wed, 01 Jun 2022 01:28:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1654072121; cv=none; d=google.com; s=arc-20160816; b=TkWGnqTc7pcOp1yXUXLmi+yf2vnCUApPYpb+eD6Fmsjig0KFLQA2E1GEX6UQ7VBXTk NcVTt+BLbdSuBxNana5kLDumgXFFQjA8MsUS7o4zJtCDYd+lDHZ/IZUn3OlJn8UVvm7K Bb7bjXh2klr6xkMkMJOtJEaPJET6KKCIjIMQBpyMNGZOroyKKBWU1BREsJUTV3a/ceHw CdroH6HzQt6Mfl2na81nqB8L3v4YtGFNPgXPsD+eq9TUnwp+qu52Kkdq6qthlR9TlljU KdC9UJwpiGiHf0Lmm6g43cnh1fxzMYT8Ra4UvRwg0alFTu9kQ7+B40gJ6lsbzQcG4kkl lHBQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:message-id:date:subject:cc:to:from:dkim-signature; bh=3u1ybH7X7Fx5XYqAu+hrz8QYjVyzBg49OwcTo80+/PY=; b=wxh1KTGPhBOBAg2UKReds8f5ZUgL11ytNGoZnjkcXcFNITOphIMrdNLzRSH4ot+Cj6 2T9q/ALpTQI0W9apASLc5WDLXzVNYclmMk3+jZJ9tfMqXtK/CtZEHc5dJ1Z3SUcbsTBi CPle7YxOY3SSngUb5f+up7gT3gEUnf9uuAkQrDKPMvLYfDLt1qQPa2u7ykHMzhOvkb9c QAFrUFJOiMUQvCX4yH4CcxAV6HJGI+tBRnuYzn8zT4FbHaBR6HG6GnNFvq87bJVkSyhe AsoSj2IVcBVFs7qgdyhRIzEsC/mJ3L/X6hVxsgMXsplD/3LZyL6sk1/u284T3ph5hUXR OA5A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="rxzL/L0O"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id n16-20020a027150000000b0033132d66533si1112333jaf.32.2022.06.01.01.28.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 Jun 2022 01:28:41 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="rxzL/L0O"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 625F98427B; Wed, 1 Jun 2022 10:28:33 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="rxzL/L0O"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id EA26984282; Wed, 1 Jun 2022 10:28:30 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-wr1-x429.google.com (mail-wr1-x429.google.com [IPv6:2a00:1450:4864:20::429]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id C84E88426E for ; Wed, 1 Jun 2022 10:28:26 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=etienne.carriere@linaro.org Received: by mail-wr1-x429.google.com with SMTP id q7so1263129wrg.5 for ; Wed, 01 Jun 2022 01:28:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=3u1ybH7X7Fx5XYqAu+hrz8QYjVyzBg49OwcTo80+/PY=; b=rxzL/L0OkpgmHAQ8PsN58QsFeSsqzB12DgsB4cUoIICTfdIdSQuzOjEjGXP193lFZc dMV8mH6f0a4MC+MxdlMsTc64T0tUV5kN/NTvoay9LrUM/q9uSriLUg0a3g/cmpfFTzOS DTuqB5BnDbNgpkLmbWO4LEabK9legtVFfMZtqcbQywtuoZxfWmo+TTcPSYAcl4j/7dIf Ufyoz3LFv0b8SwwFMFEUOm0/oLcU1WAeRtP2zyVs/rpM+Rt751Zfqn8DfHHMyWTMJgEF N6JbqRwh37wsBNQpxmWOLaFnnEmHSOLqNb4A7V30SQT4EQgy+YDCPFt3UHvYxmENod/P eGoQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=3u1ybH7X7Fx5XYqAu+hrz8QYjVyzBg49OwcTo80+/PY=; b=bZ/Ki214r/CjFbHIsD3UFEsGDI4VHbSv1GXsBA5/ne9RIfky9HzvQfySHebnlBVbqL yZWY/R4MwllRihxo9Yzf9GwnFSHkzOACPNNE5GVrgu+C3yhRO015CId5bg5Az3D47YpD x1qMAImx4Ml9gXvK2Y39ChW6swK0VKpSavJ1/on8/ud4l2CBtN5aTXy+/DZ/aUN2JSUS FTjnQSsqxKjZtWV5NW9pSXz6apfdIWBkuUyMIGr+g+CAn4kQJmMco+2caZI0Randl1ZD Fla/eNjg9Dz4pwBnP/C/4GhFJjGb9RMOK6A77Xf7Sqnqrv8G5TaGESuyrvLe+8VUmj9C g+TQ== X-Gm-Message-State: AOAM533s8RVDH33lbSwhJgUM3HFg0juxYK73kc8LwSlW0JlGbO/dsATU 8YyNijGml3MJ8VBfOTf0EEUtZHIarp8nOg== X-Received: by 2002:a5d:540a:0:b0:20e:69db:4dc5 with SMTP id g10-20020a5d540a000000b0020e69db4dc5mr51440717wrv.337.1654072105999; Wed, 01 Jun 2022 01:28:25 -0700 (PDT) Received: from lmecxl1178.lme.st.com ([2a04:cec0:117a:a94e:2216:1d3f:505:2dfb]) by smtp.gmail.com with ESMTPSA id c11-20020a056000104b00b0021006e1a965sm890893wrx.50.2022.06.01.01.28.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 Jun 2022 01:28:25 -0700 (PDT) From: Etienne Carriere To: u-boot@lists.denx.de Cc: Etienne Carriere , Jens Wiklander , Patrick Delaunay Subject: [PATCH 1/2] drivers: tee: optee: discover OP-TEE services Date: Wed, 1 Jun 2022 10:27:51 +0200 Message-Id: <20220601082752.301602-1-etienne.carriere@linaro.org> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean This change defines resources for OP-TEE service drivers to register themselves for being bound to when OP-TEE firmware reports the related service is supported. OP-TEE services are discovered during optee driver probe sequence. Discovery of optee services and binding to related U-Boot drivers is embedded upon configuration switch CONFIG_OPTEE_SERVICE_DISCOVERY. Cc: Jens Wiklander Cc: Patrick Delaunay Signed-off-by: Etienne Carriere --- drivers/tee/optee/Kconfig | 8 ++ drivers/tee/optee/core.c | 187 +++++++++++++++++++++++++++++++++++- include/tee/optee_service.h | 29 ++++++ 3 files changed, 223 insertions(+), 1 deletion(-) create mode 100644 include/tee/optee_service.h diff --git a/drivers/tee/optee/Kconfig b/drivers/tee/optee/Kconfig index d03028070b..9dc65b0501 100644 --- a/drivers/tee/optee/Kconfig +++ b/drivers/tee/optee/Kconfig @@ -37,6 +37,14 @@ config OPTEE_TA_SCP03 help Enables support for controlling (enabling, provisioning) the Secure Channel Protocol 03 operation in the OP-TEE SCP03 TA. + +config OPTEE_SERVICE_DISCOVERY + bool "OP-TEE service discovery" + default y + help + This implements automated driver binding of OP-TEE service drivers by + requesting OP-TEE firmware to enumerate its hosted services. + endmenu endif diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c index a89d62aaf0..86a32f2a81 100644 --- a/drivers/tee/optee/core.c +++ b/drivers/tee/optee/core.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "optee_smc.h" #include "optee_msg.h" @@ -22,6 +23,25 @@ #define PAGELIST_ENTRIES_PER_PAGE \ ((OPTEE_MSG_NONCONTIG_PAGE_SIZE / sizeof(u64)) - 1) +/* + * PTA_DEVICE_ENUM interface exposed by OP-TEE to discover enumerated services + */ +#define PTA_DEVICE_ENUM { 0x7011a688, 0xddde, 0x4053, \ + { 0xa5, 0xa9, 0x7b, 0x3c, 0x4d, 0xdf, 0x13, 0xb8 } } +/* + * PTA_CMD_GET_DEVICES - List services without supplicant dependencies + * + * [out] memref[0]: List of the UUIDs of service enumerated by OP-TEE + */ +#define PTA_CMD_GET_DEVICES 0x0 + +/* + * PTA_CMD_GET_DEVICES_SUPP - List services depending on tee supplicant + * + * [out] memref[0]: List of the UUIDs of service enumerated by OP-TEE + */ +#define PTA_CMD_GET_DEVICES_SUPP 0x1 + typedef void (optee_invoke_fn)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, @@ -42,6 +62,152 @@ struct rpc_param { u32 a7; }; +#ifdef CONFIG_OPTEE_SERVICE_DISCOVERY +static struct optee_service *find_service_driver(const struct tee_optee_ta_uuid *uuid) +{ + struct optee_service *service; + u8 loc_uuid[TEE_UUID_LEN]; + size_t service_cnt, idx; + + service_cnt = ll_entry_count(struct optee_service, optee_service); + service = ll_entry_start(struct optee_service, optee_service); + + for (idx = 0; idx < service_cnt; idx++, service++) { + tee_optee_ta_uuid_to_octets(loc_uuid, &service->uuid); + if (!memcmp(uuid, loc_uuid, sizeof(uuid))) + return service; + } + + return NULL; +} + +static int bind_service_list(struct udevice *dev, struct tee_shm *service_list, size_t count) +{ + const struct tee_optee_ta_uuid *service_uuid = (const void *)service_list->addr; + struct optee_service *service; + size_t idx; + int ret; + + for (idx = 0; idx < count; idx++) { + service = find_service_driver(service_uuid + idx); + if (!service) + continue; + + ret = device_bind_driver(dev, service->driver_name, service->driver_name, NULL); + if (ret) { + dev_warn(dev, "%s was not bound: %d, ignored\n", service->driver_name, ret); + continue; + } + } + + return 0; +} + +static int __enum_services(struct udevice *dev, struct tee_shm *shm, u32 *shm_size, u32 tee_sess) +{ + struct tee_invoke_arg arg = { }; + struct tee_param param = { }; + int ret = 0; + + arg.func = PTA_CMD_GET_DEVICES; + arg.session = tee_sess; + + /* Fill invoke cmd params */ + param.attr = TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT; + param.u.memref.shm = shm; + param.u.memref.size = *shm_size; + + ret = tee_invoke_func(dev, &arg, 1, ¶m); + if (ret || (arg.ret && arg.ret != TEE_ERROR_SHORT_BUFFER)) { + dev_err(dev, "PTA_CMD_GET_DEVICES invoke function err: 0x%x\n", arg.ret); + return -EINVAL; + } + + *shm_size = param.u.memref.size; + + return 0; +} + +static int enum_services(struct udevice *dev, struct tee_shm **shm, size_t *count, u32 tee_sess) +{ + size_t shm_size = 0; + int ret; + + ret = __enum_services(dev, NULL, &shm_size, tee_sess); + if (ret) + return ret; + + ret = tee_shm_alloc(dev, shm_size, 0, shm); + if (ret) { + dev_err(dev, "Failed to allocated shared memory: %d\n", ret); + return ret; + } + + ret = __enum_services(dev, *shm, &shm_size, tee_sess); + if (ret) + tee_shm_free(*shm); + else + *count = shm_size / sizeof(struct tee_optee_ta_uuid); + + return ret; +} + +static int open_session(struct udevice *dev, u32 *tee_sess) +{ + const struct tee_optee_ta_uuid pta_uuid = PTA_DEVICE_ENUM; + struct tee_open_session_arg arg = { }; + int ret; + + tee_optee_ta_uuid_to_octets(arg.uuid, &pta_uuid); + + ret = tee_open_session(dev, &arg, 0, NULL); + if (ret || arg.ret) { + if (!ret) + ret = -EIO; + return ret; + } + + *tee_sess = arg.session; + + return 0; +} + +static void close_session(struct udevice *dev, u32 tee_sess) +{ + tee_close_session(dev, tee_sess); +} + +static int bind_service_drivers(struct udevice *dev) +{ + struct tee_shm *service_list = NULL; + size_t service_count; + u32 tee_sess; + int ret; + + ret = open_session(dev, &tee_sess); + if (ret) + return ret; + + ret = enum_services(dev, &service_list, &service_count, tee_sess); + if (ret) + goto close_session; + + ret = bind_service_list(dev, service_list, service_count); + + tee_shm_free(service_list); + +close_session: + close_session(dev, tee_sess); + + return ret; +} +#else +static int bind_service_drivers(struct udevice *dev) +{ + return 0; +} +#endif /* CONFIG_OPTEE_SERVICE_DISCOVERY */ + /** * reg_pair_to_ptr() - Make a pointer of 2 32-bit values * @reg0: High bits of the pointer @@ -638,11 +804,19 @@ static int optee_of_to_plat(struct udevice *dev) return 0; } +#ifdef CONFIG_OPTEE_SERVICE_DISCOVERY +static int optee_bind(struct udevice *dev) +{ + dev_or_flags(dev, DM_FLAG_PROBE_AFTER_BIND); + + return 0; +} +#endif + static int optee_probe(struct udevice *dev) { struct optee_pdata *pdata = dev_get_plat(dev); u32 sec_caps; - struct udevice *child; int ret; if (!is_optee_api(pdata->invoke_fn)) { @@ -668,15 +842,23 @@ static int optee_probe(struct udevice *dev) return -ENOENT; } + ret = bind_service_drivers(dev); + if (ret) + return ret; + +#ifndef CONFIG_OPTEE_SERVICE_DISCOVERY /* * in U-Boot, the discovery of TA on the TEE bus is not supported: * only bind the drivers associated to the supported OP-TEE TA */ if (IS_ENABLED(CONFIG_RNG_OPTEE)) { + struct udevice *child; + ret = device_bind_driver(dev, "optee-rng", "optee-rng", &child); if (ret) return ret; } +#endif return 0; } @@ -692,6 +874,9 @@ U_BOOT_DRIVER(optee) = { .of_match = optee_match, .of_to_plat = optee_of_to_plat, .probe = optee_probe, +#ifdef CONFIG_OPTEE_SERVICE_DISCOVERY + .bind = optee_bind, +#endif .ops = &optee_ops, .plat_auto = sizeof(struct optee_pdata), .priv_auto = sizeof(struct optee_private), diff --git a/include/tee/optee_service.h b/include/tee/optee_service.h new file mode 100644 index 0000000000..31732979da --- /dev/null +++ b/include/tee/optee_service.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * (C) Copyright 2022 Linaro Limited + */ + +#ifndef _OPTEE_SERVICE_H +#define _OPTEE_SERVICE_H + +/* + * struct optee_service - Discoverable OP-TEE service + * + * @driver_name - Name of the related driver + * @uuid - UUID of the OP-TEE service related to the driver + * + * Use macro OPTEE_SERVICE_DRIVER() to register a driver related to an + * OP-TEE service discovered when driver asks OP-TEE services enumaration. + */ +struct optee_service { + const char *driver_name; + const struct tee_optee_ta_uuid uuid; +}; + +#define OPTEE_SERVICE_DRIVER(__name) \ + ll_entry_declare(struct optee_service, __name, optee_service) + +#define OPTEE_SERVICE_DRIVER_GET(__name) \ + ll_entry_get(struct optee_service, __name, optee_service) + +#endif /* _OPTEE_SERVICE_H */