From 42bf4152d8a79f89f5456dee63a1f364fbce2dd6 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Tue, 29 Jan 2019 11:19:36 +0530 Subject: tee: add supp_nowait flag in tee_context struct This flag indicates that requests in this context should not wait for tee-supplicant daemon to be started if not present and just return with an error code. It is needed for requests which should be non-blocking in nature like ones arising from TEE based kernel drivers or any in kernel api that uses TEE internal client interface. Signed-off-by: Sumit Garg Reviewed-by: Daniel Thompson Signed-off-by: Jens Wiklander --- drivers/tee/optee/supp.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/tee/optee') diff --git a/drivers/tee/optee/supp.c b/drivers/tee/optee/supp.c index 43626e15703a..92f56b8645e3 100644 --- a/drivers/tee/optee/supp.c +++ b/drivers/tee/optee/supp.c @@ -88,10 +88,18 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params, { struct optee *optee = tee_get_drvdata(ctx->teedev); struct optee_supp *supp = &optee->supp; - struct optee_supp_req *req = kzalloc(sizeof(*req), GFP_KERNEL); + struct optee_supp_req *req; bool interruptable; u32 ret; + /* + * Return in case there is no supplicant available and + * non-blocking request. + */ + if (!supp->ctx && ctx->supp_nowait) + return TEEC_ERROR_COMMUNICATION; + + req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) return TEEC_ERROR_OUT_OF_MEMORY; -- cgit v1.2.3-55-g7522 From c3fa24af92445c419c19df5981ab4e41a3ae3361 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Tue, 29 Jan 2019 11:19:37 +0530 Subject: tee: optee: add TEE bus device enumeration support OP-TEE provides a pseudo TA to enumerate TAs which can act as devices/ services for TEE bus. So implement device enumeration using invoke function: PTA_CMD_GET_DEVICES provided by pseudo TA to fetch array of device UUIDs. Also register these enumerated devices with TEE bus as "optee-clntX" device. Signed-off-by: Sumit Garg Reviewed-by: Daniel Thompson [jw: fix optee_enumerate_devices() with no devices found] Signed-off-by: Jens Wiklander --- drivers/tee/optee/Makefile | 1 + drivers/tee/optee/core.c | 4 + drivers/tee/optee/device.c | 155 ++++++++++++++++++++++++++++++++++++++ drivers/tee/optee/optee_private.h | 3 + 4 files changed, 163 insertions(+) create mode 100644 drivers/tee/optee/device.c (limited to 'drivers/tee/optee') diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile index 48d262ae2f04..56263ae3b1d7 100644 --- a/drivers/tee/optee/Makefile +++ b/drivers/tee/optee/Makefile @@ -5,3 +5,4 @@ optee-objs += call.o optee-objs += rpc.o optee-objs += supp.o optee-objs += shm_pool.o +optee-objs += device.o diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c index e5efce3c08e2..ac59c77841a4 100644 --- a/drivers/tee/optee/core.c +++ b/drivers/tee/optee/core.c @@ -634,6 +634,10 @@ static struct optee *optee_probe(struct device_node *np) if (optee->sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM) pr_info("dynamic shared memory is enabled\n"); + rc = optee_enumerate_devices(); + if (rc) + goto err; + pr_info("initialized driver\n"); return optee; err: diff --git a/drivers/tee/optee/device.c b/drivers/tee/optee/device.c new file mode 100644 index 000000000000..5e4938bbef2b --- /dev/null +++ b/drivers/tee/optee/device.c @@ -0,0 +1,155 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 Linaro Ltd. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include "optee_private.h" + +/* + * Get device UUIDs + * + * [out] memref[0] Array of device UUIDs + * + * Return codes: + * TEE_SUCCESS - Invoke command success + * TEE_ERROR_BAD_PARAMETERS - Incorrect input param + * TEE_ERROR_SHORT_BUFFER - Output buffer size less than required + */ +#define PTA_CMD_GET_DEVICES 0x0 + +static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data) +{ + if (ver->impl_id == TEE_IMPL_ID_OPTEE) + return 1; + else + return 0; +} + +static int get_devices(struct tee_context *ctx, u32 session, + struct tee_shm *device_shm, u32 *shm_size) +{ + u32 ret = 0; + struct tee_ioctl_invoke_arg inv_arg = {0}; + struct tee_param param[4] = {0}; + + /* Invoke PTA_CMD_GET_DEVICES function */ + inv_arg.func = PTA_CMD_GET_DEVICES; + inv_arg.session = session; + inv_arg.num_params = 4; + + /* Fill invoke cmd params */ + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT; + param[0].u.memref.shm = device_shm; + param[0].u.memref.size = *shm_size; + param[0].u.memref.shm_offs = 0; + + ret = tee_client_invoke_func(ctx, &inv_arg, param); + if ((ret < 0) || ((inv_arg.ret != TEEC_SUCCESS) && + (inv_arg.ret != TEEC_ERROR_SHORT_BUFFER))) { + pr_err("PTA_CMD_GET_DEVICES invoke function err: %x\n", + inv_arg.ret); + return -EINVAL; + } + + *shm_size = param[0].u.memref.size; + + return 0; +} + +static int optee_register_device(const uuid_t *device_uuid, u32 device_id) +{ + struct tee_client_device *optee_device = NULL; + int rc; + + optee_device = kzalloc(sizeof(*optee_device), GFP_KERNEL); + if (!optee_device) + return -ENOMEM; + + optee_device->dev.bus = &tee_bus_type; + dev_set_name(&optee_device->dev, "optee-clnt%u", device_id); + uuid_copy(&optee_device->id.uuid, device_uuid); + + rc = device_register(&optee_device->dev); + if (rc) { + pr_err("device registration failed, err: %d\n", rc); + kfree(optee_device); + } + + return rc; +} + +int optee_enumerate_devices(void) +{ + const uuid_t pta_uuid = + UUID_INIT(0x7011a688, 0xddde, 0x4053, + 0xa5, 0xa9, 0x7b, 0x3c, 0x4d, 0xdf, 0x13, 0xb8); + struct tee_ioctl_open_session_arg sess_arg = {0}; + struct tee_shm *device_shm = NULL; + const uuid_t *device_uuid = NULL; + struct tee_context *ctx = NULL; + u32 shm_size = 0, idx, num_devices = 0; + int rc; + + /* Open context with OP-TEE driver */ + ctx = tee_client_open_context(NULL, optee_ctx_match, NULL, NULL); + if (IS_ERR(ctx)) + return -ENODEV; + + /* Open session with device enumeration pseudo TA */ + memcpy(sess_arg.uuid, pta_uuid.b, TEE_IOCTL_UUID_LEN); + sess_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC; + sess_arg.num_params = 0; + + rc = tee_client_open_session(ctx, &sess_arg, NULL); + if ((rc < 0) || (sess_arg.ret != TEEC_SUCCESS)) { + /* Device enumeration pseudo TA not found */ + rc = 0; + goto out_ctx; + } + + rc = get_devices(ctx, sess_arg.session, NULL, &shm_size); + if (rc < 0 || !shm_size) + goto out_sess; + + device_shm = tee_shm_alloc(ctx, shm_size, + TEE_SHM_MAPPED | TEE_SHM_DMA_BUF); + if (IS_ERR(device_shm)) { + pr_err("tee_shm_alloc failed\n"); + rc = PTR_ERR(device_shm); + goto out_sess; + } + + rc = get_devices(ctx, sess_arg.session, device_shm, &shm_size); + if (rc < 0) + goto out_shm; + + device_uuid = tee_shm_get_va(device_shm, 0); + if (IS_ERR(device_uuid)) { + pr_err("tee_shm_get_va failed\n"); + rc = PTR_ERR(device_uuid); + goto out_shm; + } + + num_devices = shm_size / sizeof(uuid_t); + + for (idx = 0; idx < num_devices; idx++) { + rc = optee_register_device(&device_uuid[idx], idx); + if (rc) + goto out_shm; + } + +out_shm: + tee_shm_free(device_shm); +out_sess: + tee_client_close_session(ctx, sess_arg.session); +out_ctx: + tee_client_close_context(ctx); + + return rc; +} diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h index 35e79386c556..a5e84afd5013 100644 --- a/drivers/tee/optee/optee_private.h +++ b/drivers/tee/optee/optee_private.h @@ -28,6 +28,7 @@ #define TEEC_ERROR_BAD_PARAMETERS 0xFFFF0006 #define TEEC_ERROR_COMMUNICATION 0xFFFF000E #define TEEC_ERROR_OUT_OF_MEMORY 0xFFFF000C +#define TEEC_ERROR_SHORT_BUFFER 0xFFFF0010 #define TEEC_ORIGIN_COMMS 0x00000002 @@ -181,6 +182,8 @@ void optee_free_pages_list(void *array, size_t num_entries); void optee_fill_pages_list(u64 *dst, struct page **pages, int num_pages, size_t page_offset); +int optee_enumerate_devices(void); + /* * Small helpers */ -- cgit v1.2.3-55-g7522 From 50ceca6894adb834126ae644920902473bdc2d33 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 19 Feb 2019 02:15:20 -0700 Subject: tee: optee: Initialize some structs using memset instead of braces Clang warns: drivers/tee/optee/device.c:39:31: warning: suggest braces around initialization of subobject [-Wmissing-braces] struct tee_param param[4] = {0}; ^ {} drivers/tee/optee/device.c:92:48: warning: suggest braces around initialization of subobject [-Wmissing-braces] struct tee_ioctl_open_session_arg sess_arg = {0}; ^ {} 2 warnings generated. One way to fix these warnings is to add additional braces like Clang suggests; however, there has been a bit of push back from some maintainers, who just prefer memset as it is unambiguous, doesn't depend on a particular compiler version, and properly initializes all subobjects [1][2]. Do that here so there are no more warnings. [1]: https://lore.kernel.org/lkml/022e41c0-8465-dc7a-a45c-64187ecd9684@amd.com/ [2]: https://lore.kernel.org/lkml/20181128.215241.702406654469517539.davem@davemloft.net/ Fixes: c3fa24af9244 ("tee: optee: add TEE bus device enumeration support") Link: https://github.com/ClangBuiltLinux/linux/issues/370 Signed-off-by: Nathan Chancellor Reviewed-by: Sumit Garg Signed-off-by: Arnd Bergmann --- drivers/tee/optee/device.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers/tee/optee') diff --git a/drivers/tee/optee/device.c b/drivers/tee/optee/device.c index 5e4938bbef2b..167839b371f2 100644 --- a/drivers/tee/optee/device.c +++ b/drivers/tee/optee/device.c @@ -35,8 +35,11 @@ static int get_devices(struct tee_context *ctx, u32 session, struct tee_shm *device_shm, u32 *shm_size) { u32 ret = 0; - struct tee_ioctl_invoke_arg inv_arg = {0}; - struct tee_param param[4] = {0}; + struct tee_ioctl_invoke_arg inv_arg; + struct tee_param param[4]; + + memset(&inv_arg, 0, sizeof(inv_arg)); + memset(¶m, 0, sizeof(param)); /* Invoke PTA_CMD_GET_DEVICES function */ inv_arg.func = PTA_CMD_GET_DEVICES; @@ -89,13 +92,15 @@ int optee_enumerate_devices(void) const uuid_t pta_uuid = UUID_INIT(0x7011a688, 0xddde, 0x4053, 0xa5, 0xa9, 0x7b, 0x3c, 0x4d, 0xdf, 0x13, 0xb8); - struct tee_ioctl_open_session_arg sess_arg = {0}; + struct tee_ioctl_open_session_arg sess_arg; struct tee_shm *device_shm = NULL; const uuid_t *device_uuid = NULL; struct tee_context *ctx = NULL; u32 shm_size = 0, idx, num_devices = 0; int rc; + memset(&sess_arg, 0, sizeof(sess_arg)); + /* Open context with OP-TEE driver */ ctx = tee_client_open_context(NULL, optee_ctx_match, NULL, NULL); if (IS_ERR(ctx)) -- cgit v1.2.3-55-g7522 From 62ade1bed27c26c2ea9280174ae6d6c7a9e825b2 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Tue, 19 Feb 2019 15:04:28 +0800 Subject: tee: optee: Fix unsigned comparison with less than zero The return from the call to tee_client_invoke_func can be a negative error code however this is being assigned to an unsigned variable 'ret' hence the check is always false. Fix this by making 'ret' an int. Detected by Coccinelle ("Unsigned expression compared with zero: ret < 0") Fixes: c3fa24af9244 ("tee: optee: add TEE bus device enumeration support") Signed-off-by: YueHaibing Reviewed-by: Sumit Garg Signed-off-by: Arnd Bergmann --- drivers/tee/optee/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/tee/optee') diff --git a/drivers/tee/optee/device.c b/drivers/tee/optee/device.c index 167839b371f2..e3a148521ec1 100644 --- a/drivers/tee/optee/device.c +++ b/drivers/tee/optee/device.c @@ -34,7 +34,7 @@ static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data) static int get_devices(struct tee_context *ctx, u32 session, struct tee_shm *device_shm, u32 *shm_size) { - u32 ret = 0; + int ret = 0; struct tee_ioctl_invoke_arg inv_arg; struct tee_param param[4]; -- cgit v1.2.3-55-g7522 From 32356d309c22a9497e612ed437d66407e15935f3 Mon Sep 17 00:00:00 2001 From: Jerome Forissier Date: Fri, 8 Feb 2019 16:42:06 +0100 Subject: tee: optee: update optee_msg.h and optee_smc.h to dual license The files optee_msg.h and optee_smc.h (under drivers/tee/optee) contain information originating from the OP-TEE OS project [1] [2], where the licensing terms are BSD 2-Clause. Therefore, apply a dual license to those files. Link: [1] https://github.com/OP-TEE/optee_os/blob/master/core/include/optee_msg.h Link: [2] https://github.com/OP-TEE/optee_os/blob/master/core/arch/arm/include/sm/optee_smc.h Signed-off-by: Jerome Forissier Signed-off-by: Jens Wiklander --- drivers/tee/optee/optee_msg.h | 26 ++------------------------ drivers/tee/optee/optee_smc.h | 26 ++------------------------ 2 files changed, 4 insertions(+), 48 deletions(-) (limited to 'drivers/tee/optee') diff --git a/drivers/tee/optee/optee_msg.h b/drivers/tee/optee/optee_msg.h index 30504901be80..795bc19ae17a 100644 --- a/drivers/tee/optee/optee_msg.h +++ b/drivers/tee/optee/optee_msg.h @@ -1,28 +1,6 @@ +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) */ /* - * Copyright (c) 2015-2016, Linaro Limited - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * Copyright (c) 2015-2019, Linaro Limited */ #ifndef _OPTEE_MSG_H #define _OPTEE_MSG_H diff --git a/drivers/tee/optee/optee_smc.h b/drivers/tee/optee/optee_smc.h index bbf0cf028c16..c72122d9c997 100644 --- a/drivers/tee/optee/optee_smc.h +++ b/drivers/tee/optee/optee_smc.h @@ -1,28 +1,6 @@ +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) */ /* - * Copyright (c) 2015-2016, Linaro Limited - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * Copyright (c) 2015-2019, Linaro Limited */ #ifndef OPTEE_SMC_H #define OPTEE_SMC_H -- cgit v1.2.3-55-g7522