Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tee: add Qualcomm TEE driver

Introduce qcomtee_object, which represents an object in both QTEE and
the kernel. QTEE clients can invoke an instance of qcomtee_object to
access QTEE services. If this invocation produces a new object in QTEE,
an instance of qcomtee_object will be returned.

Similarly, QTEE can request services from by issuing a callback
request, which invokes an instance of qcomtee_object.

Implement initial support for exporting qcomtee_object to userspace
and QTEE, enabling the invocation of objects hosted in QTEE and userspace
through the TEE subsystem.

Tested-by: Neil Armstrong <neil.armstrong@linaro.org>
Tested-by: Harshal Dev <quic_hdev@quicinc.com>
Acked-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
Signed-off-by: Amirreza Zarrabi <amirreza.zarrabi@oss.qualcomm.com>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>

authored by

Amirreza Zarrabi and committed by
Jens Wiklander
d6e29083 bd513930

+3537
+6
MAINTAINERS
··· 20856 20856 F: drivers/net/ethernet/qualcomm/rmnet/ 20857 20857 F: include/linux/if_rmnet.h 20858 20858 20859 + QUALCOMM TEE (QCOMTEE) DRIVER 20860 + M: Amirreza Zarrabi <amirreza.zarrabi@oss.qualcomm.com> 20861 + L: linux-arm-msm@vger.kernel.org 20862 + S: Maintained 20863 + F: drivers/tee/qcomtee/ 20864 + 20859 20865 QUALCOMM TRUST ZONE MEMORY ALLOCATOR 20860 20866 M: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> 20861 20867 L: linux-arm-msm@vger.kernel.org
+1
drivers/tee/Kconfig
··· 21 21 source "drivers/tee/optee/Kconfig" 22 22 source "drivers/tee/amdtee/Kconfig" 23 23 source "drivers/tee/tstee/Kconfig" 24 + source "drivers/tee/qcomtee/Kconfig" 24 25 25 26 endif
+1
drivers/tee/Makefile
··· 7 7 obj-$(CONFIG_OPTEE) += optee/ 8 8 obj-$(CONFIG_AMDTEE) += amdtee/ 9 9 obj-$(CONFIG_ARM_TSTEE) += tstee/ 10 + obj-$(CONFIG_QCOMTEE) += qcomtee/
+12
drivers/tee/qcomtee/Kconfig
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + # Qualcomm Trusted Execution Environment Configuration 3 + config QCOMTEE 4 + tristate "Qualcomm TEE Support" 5 + depends on !CPU_BIG_ENDIAN 6 + select QCOM_SCM 7 + select QCOM_TZMEM_MODE_SHMBRIDGE 8 + help 9 + This option enables the Qualcomm Trusted Execution Environment (QTEE) 10 + driver. It provides an API to access services offered by QTEE and 11 + its loaded Trusted Applications (TAs). Additionally, it facilitates 12 + the export of userspace services provided by supplicants to QTEE.
+7
drivers/tee/qcomtee/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + obj-$(CONFIG_QCOMTEE) += qcomtee.o 3 + qcomtee-objs += async.o 4 + qcomtee-objs += call.o 5 + qcomtee-objs += core.o 6 + qcomtee-objs += shm.o 7 + qcomtee-objs += user_obj.o
+182
drivers/tee/qcomtee/async.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4 + */ 5 + 6 + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 7 + 8 + #include "qcomtee.h" 9 + 10 + #define QCOMTEE_ASYNC_VERSION_1_0 0x00010000U /* Maj: 0x0001, Min: 0x0000. */ 11 + #define QCOMTEE_ASYNC_VERSION_1_1 0x00010001U /* Maj: 0x0001, Min: 0x0001. */ 12 + #define QCOMTEE_ASYNC_VERSION_1_2 0x00010002U /* Maj: 0x0001, Min: 0x0002. */ 13 + #define QCOMTEE_ASYNC_VERSION_CURRENT QCOMTEE_ASYNC_VERSION_1_2 14 + 15 + #define QCOMTEE_ASYNC_VERSION_MAJOR(n) upper_16_bits(n) 16 + #define QCOMTEE_ASYNC_VERSION_MINOR(n) lower_16_bits(n) 17 + 18 + #define QCOMTEE_ASYNC_VERSION_CURRENT_MAJOR \ 19 + QCOMTEE_ASYNC_VERSION_MAJOR(QCOMTEE_ASYNC_VERSION_CURRENT) 20 + #define QCOMTEE_ASYNC_VERSION_CURRENT_MINOR \ 21 + QCOMTEE_ASYNC_VERSION_MINOR(QCOMTEE_ASYNC_VERSION_CURRENT) 22 + 23 + /** 24 + * struct qcomtee_async_msg_hdr - Asynchronous message header format. 25 + * @version: current async protocol version of the remote endpoint. 26 + * @op: async operation. 27 + * 28 + * @version specifies the endpoint's (QTEE or driver) supported async protocol. 29 + * For example, if QTEE sets @version to %QCOMTEE_ASYNC_VERSION_1_1, QTEE 30 + * handles operations supported in %QCOMTEE_ASYNC_VERSION_1_1 or 31 + * %QCOMTEE_ASYNC_VERSION_1_0. @op determines the message format. 32 + */ 33 + struct qcomtee_async_msg_hdr { 34 + u32 version; 35 + u32 op; 36 + }; 37 + 38 + /* Size of an empty async message. */ 39 + #define QCOMTEE_ASYNC_MSG_ZERO sizeof(struct qcomtee_async_msg_hdr) 40 + 41 + /** 42 + * struct qcomtee_async_release_msg - Release asynchronous message. 43 + * @hdr: message header as &struct qcomtee_async_msg_hdr. 44 + * @counts: number of objects in @object_ids. 45 + * @object_ids: array of object IDs that should be released. 46 + * 47 + * Available in Maj = 0x0001, Min >= 0x0000. 48 + */ 49 + struct qcomtee_async_release_msg { 50 + struct qcomtee_async_msg_hdr hdr; 51 + u32 counts; 52 + u32 object_ids[] __counted_by(counts); 53 + }; 54 + 55 + /** 56 + * qcomtee_get_async_buffer() - Get the start of the asynchronous message. 57 + * @oic: context used for the current invocation. 58 + * @async_buffer: return buffer to extract from or fill in async messages. 59 + * 60 + * If @oic is used for direct object invocation, the whole outbound buffer 61 + * is available for the async message. If @oic is used for a callback request, 62 + * the tail of the outbound buffer (after the callback request message) is 63 + * available for the async message. 64 + * 65 + * The start of the async buffer is aligned, see qcomtee_msg_offset_align(). 66 + */ 67 + static void qcomtee_get_async_buffer(struct qcomtee_object_invoke_ctx *oic, 68 + struct qcomtee_buffer *async_buffer) 69 + { 70 + struct qcomtee_msg_callback *msg; 71 + unsigned int offset; 72 + int i; 73 + 74 + if (!(oic->flags & QCOMTEE_OIC_FLAG_BUSY)) { 75 + /* The outbound buffer is empty. Using the whole buffer. */ 76 + offset = 0; 77 + } else { 78 + msg = (struct qcomtee_msg_callback *)oic->out_msg.addr; 79 + 80 + /* Start offset in a message for buffer arguments. */ 81 + offset = qcomtee_msg_buffer_args(struct qcomtee_msg_callback, 82 + qcomtee_msg_args(msg)); 83 + 84 + /* Add size of IB arguments. */ 85 + qcomtee_msg_for_each_input_buffer(i, msg) 86 + offset += qcomtee_msg_offset_align(msg->args[i].b.size); 87 + 88 + /* Add size of OB arguments. */ 89 + qcomtee_msg_for_each_output_buffer(i, msg) 90 + offset += qcomtee_msg_offset_align(msg->args[i].b.size); 91 + } 92 + 93 + async_buffer->addr = oic->out_msg.addr + offset; 94 + async_buffer->size = oic->out_msg.size - offset; 95 + } 96 + 97 + /** 98 + * async_release() - Process QTEE async release requests. 99 + * @oic: context used for the current invocation. 100 + * @msg: async message for object release. 101 + * @size: size of the async buffer available. 102 + * 103 + * Return: Size of the outbound buffer used when processing @msg. 104 + */ 105 + static size_t async_release(struct qcomtee_object_invoke_ctx *oic, 106 + struct qcomtee_async_msg_hdr *async_msg, 107 + size_t size) 108 + { 109 + struct qcomtee_async_release_msg *msg; 110 + struct qcomtee_object *object; 111 + int i; 112 + 113 + msg = (struct qcomtee_async_release_msg *)async_msg; 114 + 115 + for (i = 0; i < msg->counts; i++) { 116 + object = qcomtee_idx_erase(oic, msg->object_ids[i]); 117 + qcomtee_object_put(object); 118 + } 119 + 120 + return struct_size(msg, object_ids, msg->counts); 121 + } 122 + 123 + /** 124 + * qcomtee_fetch_async_reqs() - Fetch and process asynchronous messages. 125 + * @oic: context used for the current invocation. 126 + * 127 + * Calls handlers to process the requested operations in the async message. 128 + * Currently, only supports async release requests. 129 + */ 130 + void qcomtee_fetch_async_reqs(struct qcomtee_object_invoke_ctx *oic) 131 + { 132 + struct qcomtee_async_msg_hdr *async_msg; 133 + struct qcomtee_buffer async_buffer; 134 + size_t consumed, used = 0; 135 + u16 major_ver; 136 + 137 + qcomtee_get_async_buffer(oic, &async_buffer); 138 + 139 + while (async_buffer.size - used > QCOMTEE_ASYNC_MSG_ZERO) { 140 + async_msg = (struct qcomtee_async_msg_hdr *)(async_buffer.addr + 141 + used); 142 + /* 143 + * QTEE assumes that the unused space of the async buffer is 144 + * zeroed; so if version is zero, the buffer is unused. 145 + */ 146 + if (async_msg->version == 0) 147 + goto out; 148 + 149 + major_ver = QCOMTEE_ASYNC_VERSION_MAJOR(async_msg->version); 150 + /* Major version mismatch is a compatibility break. */ 151 + if (major_ver != QCOMTEE_ASYNC_VERSION_CURRENT_MAJOR) { 152 + pr_err("Async message version mismatch (%u != %u)\n", 153 + major_ver, QCOMTEE_ASYNC_VERSION_CURRENT_MAJOR); 154 + 155 + goto out; 156 + } 157 + 158 + switch (async_msg->op) { 159 + case QCOMTEE_MSG_OBJECT_OP_RELEASE: 160 + consumed = async_release(oic, async_msg, 161 + async_buffer.size - used); 162 + break; 163 + default: 164 + pr_err("Unsupported async message %u\n", async_msg->op); 165 + goto out; 166 + } 167 + 168 + /* Supported operation but unable to parse the message. */ 169 + if (!consumed) { 170 + pr_err("Unable to parse async message for op %u\n", 171 + async_msg->op); 172 + goto out; 173 + } 174 + 175 + /* Next async message. */ 176 + used += qcomtee_msg_offset_align(consumed); 177 + } 178 + 179 + out: 180 + /* Reset the async buffer so async requests do not loop to QTEE. */ 181 + memzero_explicit(async_buffer.addr, async_buffer.size); 182 + }
+813
drivers/tee/qcomtee/call.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4 + */ 5 + 6 + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 7 + 8 + #include <linux/slab.h> 9 + #include <linux/tee.h> 10 + #include <linux/platform_device.h> 11 + #include <linux/xarray.h> 12 + 13 + #include "qcomtee.h" 14 + 15 + static int find_qtee_object(struct qcomtee_object **object, unsigned long id, 16 + struct qcomtee_context_data *ctxdata) 17 + { 18 + int err = 0; 19 + 20 + guard(rcu)(); 21 + /* Object release is RCU protected. */ 22 + *object = idr_find(&ctxdata->qtee_objects_idr, id); 23 + if (!qcomtee_object_get(*object)) 24 + err = -EINVAL; 25 + 26 + return err; 27 + } 28 + 29 + static void del_qtee_object(unsigned long id, 30 + struct qcomtee_context_data *ctxdata) 31 + { 32 + struct qcomtee_object *object; 33 + 34 + scoped_guard(mutex, &ctxdata->qtee_lock) 35 + object = idr_remove(&ctxdata->qtee_objects_idr, id); 36 + 37 + qcomtee_object_put(object); 38 + } 39 + 40 + /** 41 + * qcomtee_context_add_qtee_object() - Add a QTEE object to the context. 42 + * @param: TEE parameter representing @object. 43 + * @object: QTEE object. 44 + * @ctx: context to add the object. 45 + * 46 + * It assumes @object is %QCOMTEE_OBJECT_TYPE_TEE and the caller has already 47 + * issued qcomtee_object_get() for @object. 48 + * 49 + * Return: On success, returns 0; on failure, returns < 0. 50 + */ 51 + int qcomtee_context_add_qtee_object(struct tee_param *param, 52 + struct qcomtee_object *object, 53 + struct tee_context *ctx) 54 + { 55 + int ret; 56 + struct qcomtee_context_data *ctxdata = ctx->data; 57 + 58 + scoped_guard(mutex, &ctxdata->qtee_lock) 59 + ret = idr_alloc(&ctxdata->qtee_objects_idr, object, 0, 0, 60 + GFP_KERNEL); 61 + if (ret < 0) 62 + return ret; 63 + 64 + param->u.objref.id = ret; 65 + /* QTEE Object: QCOMTEE_OBJREF_FLAG_TEE set. */ 66 + param->u.objref.flags = QCOMTEE_OBJREF_FLAG_TEE; 67 + 68 + return 0; 69 + } 70 + 71 + /* Retrieve the QTEE object added with qcomtee_context_add_qtee_object(). */ 72 + int qcomtee_context_find_qtee_object(struct qcomtee_object **object, 73 + struct tee_param *param, 74 + struct tee_context *ctx) 75 + { 76 + struct qcomtee_context_data *ctxdata = ctx->data; 77 + 78 + return find_qtee_object(object, param->u.objref.id, ctxdata); 79 + } 80 + 81 + /** 82 + * qcomtee_context_del_qtee_object() - Delete a QTEE object from the context. 83 + * @param: TEE parameter representing @object. 84 + * @ctx: context for deleting the object. 85 + * 86 + * The @param has been initialized by qcomtee_context_add_qtee_object(). 87 + */ 88 + void qcomtee_context_del_qtee_object(struct tee_param *param, 89 + struct tee_context *ctx) 90 + { 91 + struct qcomtee_context_data *ctxdata = ctx->data; 92 + /* 'qtee_objects_idr' stores QTEE objects only. */ 93 + if (param->u.objref.flags & QCOMTEE_OBJREF_FLAG_TEE) 94 + del_qtee_object(param->u.objref.id, ctxdata); 95 + } 96 + 97 + /** 98 + * qcomtee_objref_to_arg() - Convert OBJREF parameter to QTEE argument. 99 + * @arg: QTEE argument. 100 + * @param: TEE parameter. 101 + * @ctx: context in which the conversion should happen. 102 + * 103 + * It assumes @param is an OBJREF. 104 + * It does not set @arg.type; the caller should initialize it to a correct 105 + * &enum qcomtee_arg_type value. It gets the object's refcount in @arg; 106 + * the caller should manage to put it afterward. 107 + * 108 + * Return: On success, returns 0; on failure, returns < 0. 109 + */ 110 + int qcomtee_objref_to_arg(struct qcomtee_arg *arg, struct tee_param *param, 111 + struct tee_context *ctx) 112 + { 113 + int err = -EINVAL; 114 + 115 + arg->o = NULL_QCOMTEE_OBJECT; 116 + /* param is a NULL object: */ 117 + if (param->u.objref.id == TEE_OBJREF_NULL) 118 + return 0; 119 + 120 + /* param is a callback object: */ 121 + if (param->u.objref.flags & QCOMTEE_OBJREF_FLAG_USER) 122 + err = qcomtee_user_param_to_object(&arg->o, param, ctx); 123 + /* param is a QTEE object: */ 124 + else if (param->u.objref.flags & QCOMTEE_OBJREF_FLAG_TEE) 125 + err = qcomtee_context_find_qtee_object(&arg->o, param, ctx); 126 + 127 + /* 128 + * For callback objects, call qcomtee_object_get() to keep a temporary 129 + * copy for the driver, as these objects are released asynchronously 130 + * and may disappear even before returning from QTEE. 131 + * 132 + * - For direct object invocations, the matching put is called in 133 + * qcomtee_object_invoke() when parsing the QTEE response. 134 + * - For callback responses, put is called in qcomtee_user_object_notify() 135 + * after QTEE has received its copies. 136 + */ 137 + 138 + if (!err && (typeof_qcomtee_object(arg->o) == QCOMTEE_OBJECT_TYPE_CB)) 139 + qcomtee_object_get(arg->o); 140 + 141 + return err; 142 + } 143 + 144 + /** 145 + * qcomtee_objref_from_arg() - Convert QTEE argument to OBJREF param. 146 + * @param: TEE parameter. 147 + * @arg: QTEE argument. 148 + * @ctx: context in which the conversion should happen. 149 + * 150 + * It assumes @arg is of %QCOMTEE_ARG_TYPE_IO or %QCOMTEE_ARG_TYPE_OO. 151 + * It does not set @param.attr; the caller should initialize it to a 152 + * correct type. 153 + * 154 + * Return: On success, returns 0; on failure, returns < 0. 155 + */ 156 + int qcomtee_objref_from_arg(struct tee_param *param, struct qcomtee_arg *arg, 157 + struct tee_context *ctx) 158 + { 159 + struct qcomtee_object *object = arg->o; 160 + 161 + switch (typeof_qcomtee_object(object)) { 162 + case QCOMTEE_OBJECT_TYPE_NULL: 163 + param->u.objref.id = TEE_OBJREF_NULL; 164 + 165 + return 0; 166 + case QCOMTEE_OBJECT_TYPE_CB: 167 + /* object is a callback object: */ 168 + if (is_qcomtee_user_object(object)) 169 + return qcomtee_user_param_from_object(param, object, 170 + ctx); 171 + 172 + break; 173 + case QCOMTEE_OBJECT_TYPE_TEE: 174 + return qcomtee_context_add_qtee_object(param, object, ctx); 175 + 176 + case QCOMTEE_OBJECT_TYPE_ROOT: 177 + default: 178 + break; 179 + } 180 + 181 + return -EINVAL; 182 + } 183 + 184 + /** 185 + * qcomtee_params_to_args() - Convert TEE parameters to QTEE arguments. 186 + * @u: QTEE arguments. 187 + * @params: TEE parameters. 188 + * @num_params: number of elements in the parameter array. 189 + * @ctx: context in which the conversion should happen. 190 + * 191 + * It assumes @u has at least @num_params + 1 entries and has been initialized 192 + * with %QCOMTEE_ARG_TYPE_INV as &struct qcomtee_arg.type. 193 + * 194 + * Return: On success, returns 0; on failure, returns < 0. 195 + */ 196 + static int qcomtee_params_to_args(struct qcomtee_arg *u, 197 + struct tee_param *params, int num_params, 198 + struct tee_context *ctx) 199 + { 200 + int i; 201 + 202 + for (i = 0; i < num_params; i++) { 203 + switch (params[i].attr) { 204 + case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INPUT: 205 + case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_OUTPUT: 206 + u[i].flags = QCOMTEE_ARG_FLAGS_UADDR; 207 + u[i].b.uaddr = params[i].u.ubuf.uaddr; 208 + u[i].b.size = params[i].u.ubuf.size; 209 + 210 + if (params[i].attr == 211 + TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INPUT) 212 + u[i].type = QCOMTEE_ARG_TYPE_IB; 213 + else /* TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_OUTPUT */ 214 + u[i].type = QCOMTEE_ARG_TYPE_OB; 215 + 216 + break; 217 + case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INPUT: 218 + u[i].type = QCOMTEE_ARG_TYPE_IO; 219 + if (qcomtee_objref_to_arg(&u[i], &params[i], ctx)) 220 + goto out_failed; 221 + 222 + break; 223 + case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_OUTPUT: 224 + u[i].type = QCOMTEE_ARG_TYPE_OO; 225 + u[i].o = NULL_QCOMTEE_OBJECT; 226 + break; 227 + default: 228 + goto out_failed; 229 + } 230 + } 231 + 232 + return 0; 233 + 234 + out_failed: 235 + /* Undo qcomtee_objref_to_arg(). */ 236 + for (i--; i >= 0; i--) { 237 + if (u[i].type != QCOMTEE_ARG_TYPE_IO) 238 + continue; 239 + 240 + qcomtee_user_object_set_notify(u[i].o, false); 241 + /* See docs for qcomtee_objref_to_arg() for double put. */ 242 + if (typeof_qcomtee_object(u[i].o) == QCOMTEE_OBJECT_TYPE_CB) 243 + qcomtee_object_put(u[i].o); 244 + 245 + qcomtee_object_put(u[i].o); 246 + } 247 + 248 + return -EINVAL; 249 + } 250 + 251 + /** 252 + * qcomtee_params_from_args() - Convert QTEE arguments to TEE parameters. 253 + * @params: TEE parameters. 254 + * @u: QTEE arguments. 255 + * @num_params: number of elements in the parameter array. 256 + * @ctx: context in which the conversion should happen. 257 + * 258 + * @u should have already been initialized by qcomtee_params_to_args(). 259 + * This also represents the end of a QTEE invocation that started with 260 + * qcomtee_params_to_args() by releasing %QCOMTEE_ARG_TYPE_IO objects. 261 + * 262 + * Return: On success, returns 0; on failure, returns < 0. 263 + */ 264 + static int qcomtee_params_from_args(struct tee_param *params, 265 + struct qcomtee_arg *u, int num_params, 266 + struct tee_context *ctx) 267 + { 268 + int i, np; 269 + 270 + qcomtee_arg_for_each(np, u) { 271 + switch (u[np].type) { 272 + case QCOMTEE_ARG_TYPE_OB: 273 + /* TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_OUTPUT */ 274 + params[np].u.ubuf.size = u[np].b.size; 275 + 276 + break; 277 + case QCOMTEE_ARG_TYPE_IO: 278 + /* IEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INPUT */ 279 + qcomtee_object_put(u[np].o); 280 + 281 + break; 282 + case QCOMTEE_ARG_TYPE_OO: 283 + /* TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_OUTPUT */ 284 + if (qcomtee_objref_from_arg(&params[np], &u[np], ctx)) 285 + goto out_failed; 286 + 287 + break; 288 + case QCOMTEE_ARG_TYPE_IB: 289 + default: 290 + break; 291 + } 292 + } 293 + 294 + return 0; 295 + 296 + out_failed: 297 + /* Undo qcomtee_objref_from_arg(). */ 298 + for (i = 0; i < np; i++) { 299 + if (params[i].attr == TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_OUTPUT) 300 + qcomtee_context_del_qtee_object(&params[i], ctx); 301 + } 302 + 303 + /* Release any IO and OO objects not processed. */ 304 + for (; u[i].type && i < num_params; i++) { 305 + if (u[i].type == QCOMTEE_ARG_TYPE_OO || 306 + u[i].type == QCOMTEE_ARG_TYPE_IO) 307 + qcomtee_object_put(u[i].o); 308 + } 309 + 310 + return -EINVAL; 311 + } 312 + 313 + /* TEE Device Ops. */ 314 + 315 + static int qcomtee_params_check(struct tee_param *params, int num_params) 316 + { 317 + int io = 0, oo = 0, ib = 0, ob = 0; 318 + int i; 319 + 320 + /* QTEE can accept 64 arguments. */ 321 + if (num_params > QCOMTEE_ARGS_MAX) 322 + return -EINVAL; 323 + 324 + /* Supported parameter types. */ 325 + for (i = 0; i < num_params; i++) { 326 + switch (params[i].attr) { 327 + case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INPUT: 328 + ib++; 329 + break; 330 + case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_OUTPUT: 331 + ob++; 332 + break; 333 + case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INPUT: 334 + io++; 335 + break; 336 + case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_OUTPUT: 337 + oo++; 338 + break; 339 + default: 340 + return -EINVAL; 341 + } 342 + } 343 + 344 + /* QTEE can accept 16 arguments of each supported types. */ 345 + if (io > QCOMTEE_ARGS_PER_TYPE || oo > QCOMTEE_ARGS_PER_TYPE || 346 + ib > QCOMTEE_ARGS_PER_TYPE || ob > QCOMTEE_ARGS_PER_TYPE) 347 + return -EINVAL; 348 + 349 + return 0; 350 + } 351 + 352 + /* Check if an operation on ROOT_QCOMTEE_OBJECT from userspace is permitted. */ 353 + static int qcomtee_root_object_check(u32 op, struct tee_param *params, 354 + int num_params) 355 + { 356 + /* Some privileged operations recognized by QTEE. */ 357 + if (op == QCOMTEE_ROOT_OP_NOTIFY_DOMAIN_CHANGE || 358 + op == QCOMTEE_ROOT_OP_ADCI_ACCEPT || 359 + op == QCOMTEE_ROOT_OP_ADCI_SHUTDOWN) 360 + return -EINVAL; 361 + 362 + /* 363 + * QCOMTEE_ROOT_OP_REG_WITH_CREDENTIALS is to register with QTEE 364 + * by passing a credential object as input OBJREF. TEE_OBJREF_NULL as a 365 + * credential object represents a privileged client for QTEE and 366 + * is used by the kernel only. 367 + */ 368 + if (op == QCOMTEE_ROOT_OP_REG_WITH_CREDENTIALS && num_params == 2) { 369 + if (params[0].attr == TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INPUT && 370 + params[1].attr == TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_OUTPUT) { 371 + if (params[0].u.objref.id == TEE_OBJREF_NULL) 372 + return -EINVAL; 373 + } 374 + } 375 + 376 + return 0; 377 + } 378 + 379 + /** 380 + * qcomtee_object_invoke() - Invoke a QTEE object. 381 + * @ctx: TEE context. 382 + * @arg: ioctl arguments. 383 + * @params: parameters for the object. 384 + * 385 + * Return: On success, returns 0; on failure, returns < 0. 386 + */ 387 + static int qcomtee_object_invoke(struct tee_context *ctx, 388 + struct tee_ioctl_object_invoke_arg *arg, 389 + struct tee_param *params) 390 + { 391 + struct qcomtee_object_invoke_ctx *oic __free(kfree) = NULL; 392 + struct qcomtee_context_data *ctxdata = ctx->data; 393 + struct qcomtee_arg *u __free(kfree) = NULL; 394 + struct qcomtee_object *object; 395 + int i, ret, result; 396 + 397 + if (qcomtee_params_check(params, arg->num_params)) 398 + return -EINVAL; 399 + 400 + /* First, handle reserved operations: */ 401 + if (arg->op == QCOMTEE_MSG_OBJECT_OP_RELEASE) { 402 + del_qtee_object(arg->id, ctxdata); 403 + 404 + return 0; 405 + } 406 + 407 + /* Otherwise, invoke a QTEE object: */ 408 + oic = qcomtee_object_invoke_ctx_alloc(ctx); 409 + if (!oic) 410 + return -ENOMEM; 411 + 412 + /* +1 for ending QCOMTEE_ARG_TYPE_INV. */ 413 + u = kcalloc(arg->num_params + 1, sizeof(*u), GFP_KERNEL); 414 + if (!u) 415 + return -ENOMEM; 416 + 417 + /* Get an object to invoke. */ 418 + if (arg->id == TEE_OBJREF_NULL) { 419 + /* Use ROOT if TEE_OBJREF_NULL is invoked. */ 420 + if (qcomtee_root_object_check(arg->op, params, arg->num_params)) 421 + return -EINVAL; 422 + 423 + object = ROOT_QCOMTEE_OBJECT; 424 + } else if (find_qtee_object(&object, arg->id, ctxdata)) { 425 + return -EINVAL; 426 + } 427 + 428 + ret = qcomtee_params_to_args(u, params, arg->num_params, ctx); 429 + if (ret) 430 + goto out; 431 + 432 + ret = qcomtee_object_do_invoke(oic, object, arg->op, u, &result); 433 + if (ret) { 434 + qcomtee_arg_for_each_input_object(i, u) { 435 + qcomtee_user_object_set_notify(u[i].o, false); 436 + qcomtee_object_put(u[i].o); 437 + } 438 + 439 + goto out; 440 + } 441 + 442 + /* Prase QTEE response and put driver's object copies: */ 443 + 444 + if (!result) { 445 + /* Assume service is UNAVAIL if unable to process the result. */ 446 + if (qcomtee_params_from_args(params, u, arg->num_params, ctx)) 447 + result = QCOMTEE_MSG_ERROR_UNAVAIL; 448 + } else { 449 + /* 450 + * qcomtee_params_to_args() gets a copy of IO for the driver to 451 + * make sure they do not get released while in the middle of 452 + * invocation. On success (!result), qcomtee_params_from_args() 453 + * puts them; Otherwise, put them here. 454 + */ 455 + qcomtee_arg_for_each_input_object(i, u) 456 + qcomtee_object_put(u[i].o); 457 + } 458 + 459 + arg->ret = result; 460 + out: 461 + qcomtee_object_put(object); 462 + 463 + return ret; 464 + } 465 + 466 + /** 467 + * qcomtee_supp_recv() - Wait for a request for the supplicant. 468 + * @ctx: TEE context. 469 + * @op: requested operation on the object. 470 + * @num_params: number of elements in the parameter array. 471 + * @params: parameters for @op. 472 + * 473 + * The first parameter is a meta %TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT. 474 + * On input, it provides a user buffer. This buffer is used for parameters of 475 + * type %TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INPUT in qcomtee_cb_params_from_args(). 476 + * On output, the object ID and request ID are stored in the meta parameter. 477 + * 478 + * @num_params is updated to the number of parameters that actually exist 479 + * in @params on return. 480 + * 481 + * Return: On success, returns 0; on failure, returns < 0. 482 + */ 483 + static int qcomtee_supp_recv(struct tee_context *ctx, u32 *op, u32 *num_params, 484 + struct tee_param *params) 485 + { 486 + struct qcomtee_user_object_request_data data; 487 + void __user *uaddr; 488 + size_t ubuf_size; 489 + int i, ret; 490 + 491 + if (!*num_params) 492 + return -EINVAL; 493 + 494 + /* First parameter should be an INOUT + meta parameter. */ 495 + if (params->attr != 496 + (TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT | TEE_IOCTL_PARAM_ATTR_META)) 497 + return -EINVAL; 498 + 499 + /* Other parameters are none. */ 500 + for (i = 1; i < *num_params; i++) 501 + if (params[i].attr) 502 + return -EINVAL; 503 + 504 + if (!IS_ALIGNED(params->u.value.a, 8)) 505 + return -EINVAL; 506 + 507 + /* User buffer and size from meta parameter. */ 508 + uaddr = u64_to_user_ptr(params->u.value.a); 509 + ubuf_size = params->u.value.b; 510 + /* Process TEE parameters. +/-1 to ignore the meta parameter. */ 511 + ret = qcomtee_user_object_select(ctx, params + 1, *num_params - 1, 512 + uaddr, ubuf_size, &data); 513 + if (ret) 514 + return ret; 515 + 516 + params->u.value.a = data.object_id; 517 + params->u.value.b = data.id; 518 + params->u.value.c = 0; 519 + *op = data.op; 520 + *num_params = data.np + 1; 521 + 522 + return 0; 523 + } 524 + 525 + /** 526 + * qcomtee_supp_send() - Submit a response for a request. 527 + * @ctx: TEE context. 528 + * @errno: return value for the request. 529 + * @num_params: number of elements in the parameter array. 530 + * @params: returned parameters. 531 + * 532 + * The first parameter is a meta %TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT. 533 + * It specifies the request ID this response belongs to. 534 + * 535 + * Return: On success, returns 0; on failure, returns < 0. 536 + */ 537 + static int qcomtee_supp_send(struct tee_context *ctx, u32 errno, u32 num_params, 538 + struct tee_param *params) 539 + { 540 + int req_id; 541 + 542 + if (!num_params) 543 + return -EINVAL; 544 + 545 + /* First parameter should be an OUTPUT + meta parameter. */ 546 + if (params->attr != (TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT | 547 + TEE_IOCTL_PARAM_ATTR_META)) 548 + return -EINVAL; 549 + 550 + req_id = params->u.value.a; 551 + /* Process TEE parameters. +/-1 to ignore the meta parameter. */ 552 + return qcomtee_user_object_submit(ctx, params + 1, num_params - 1, 553 + req_id, errno); 554 + } 555 + 556 + static int qcomtee_open(struct tee_context *ctx) 557 + { 558 + struct qcomtee_context_data *ctxdata __free(kfree) = NULL; 559 + 560 + ctxdata = kzalloc(sizeof(*ctxdata), GFP_KERNEL); 561 + if (!ctxdata) 562 + return -ENOMEM; 563 + 564 + /* 565 + * In the QTEE driver, the same context is used to refcount resources 566 + * shared by QTEE. For example, teedev_ctx_get() is called for any 567 + * instance of callback objects (see qcomtee_user_param_to_object()). 568 + * 569 + * Maintain a copy of teedev for QTEE as it serves as a direct user of 570 + * this context. The teedev will be released in the context's release(). 571 + * 572 + * tee_device_unregister() will remain blocked until all contexts 573 + * are released. This includes contexts owned by the user, which are 574 + * closed by teedev_close_context(), as well as those owned by QTEE 575 + * closed by teedev_ctx_put() in object's release(). 576 + */ 577 + if (!tee_device_get(ctx->teedev)) 578 + return -EINVAL; 579 + 580 + idr_init(&ctxdata->qtee_objects_idr); 581 + mutex_init(&ctxdata->qtee_lock); 582 + idr_init(&ctxdata->reqs_idr); 583 + INIT_LIST_HEAD(&ctxdata->reqs_list); 584 + mutex_init(&ctxdata->reqs_lock); 585 + init_completion(&ctxdata->req_c); 586 + 587 + ctx->data = no_free_ptr(ctxdata); 588 + 589 + return 0; 590 + } 591 + 592 + /* Gets called when the user closes the device */ 593 + static void qcomtee_close_context(struct tee_context *ctx) 594 + { 595 + struct qcomtee_context_data *ctxdata = ctx->data; 596 + struct qcomtee_object *object; 597 + int id; 598 + 599 + /* Process QUEUED or PROCESSING requests. */ 600 + qcomtee_requests_destroy(ctxdata); 601 + /* Release QTEE objects. */ 602 + idr_for_each_entry(&ctxdata->qtee_objects_idr, object, id) 603 + qcomtee_object_put(object); 604 + } 605 + 606 + /* Gets called when the final reference to the context goes away. */ 607 + static void qcomtee_release(struct tee_context *ctx) 608 + { 609 + struct qcomtee_context_data *ctxdata = ctx->data; 610 + 611 + idr_destroy(&ctxdata->qtee_objects_idr); 612 + idr_destroy(&ctxdata->reqs_idr); 613 + kfree(ctxdata); 614 + 615 + /* There is nothing shared in this context with QTEE. */ 616 + tee_device_put(ctx->teedev); 617 + } 618 + 619 + static void qcomtee_get_version(struct tee_device *teedev, 620 + struct tee_ioctl_version_data *vers) 621 + { 622 + struct tee_ioctl_version_data v = { 623 + .impl_id = TEE_IMPL_ID_QTEE, 624 + .gen_caps = TEE_GEN_CAP_OBJREF, 625 + }; 626 + 627 + *vers = v; 628 + } 629 + 630 + /** 631 + * qcomtee_get_qtee_feature_list() - Query QTEE features versions. 632 + * @ctx: TEE context. 633 + * @id: ID of the feature to query. 634 + * @version: version of the feature. 635 + * 636 + * Used to query the verion of features supported by QTEE. 637 + */ 638 + static void qcomtee_get_qtee_feature_list(struct tee_context *ctx, u32 id, 639 + u32 *version) 640 + { 641 + struct qcomtee_object_invoke_ctx *oic __free(kfree); 642 + struct qcomtee_object *client_env, *service; 643 + struct qcomtee_arg u[3] = { 0 }; 644 + int result; 645 + 646 + oic = qcomtee_object_invoke_ctx_alloc(ctx); 647 + if (!oic) 648 + return; 649 + 650 + client_env = qcomtee_object_get_client_env(oic); 651 + if (client_env == NULL_QCOMTEE_OBJECT) 652 + return; 653 + 654 + /* Get ''FeatureVersions Service'' object. */ 655 + service = qcomtee_object_get_service(oic, client_env, 656 + QCOMTEE_FEATURE_VER_UID); 657 + if (service == NULL_QCOMTEE_OBJECT) 658 + goto out_failed; 659 + 660 + /* IB: Feature to query. */ 661 + u[0].b.addr = &id; 662 + u[0].b.size = sizeof(id); 663 + u[0].type = QCOMTEE_ARG_TYPE_IB; 664 + 665 + /* OB: Version returned. */ 666 + u[1].b.addr = version; 667 + u[1].b.size = sizeof(*version); 668 + u[1].type = QCOMTEE_ARG_TYPE_OB; 669 + 670 + qcomtee_object_do_invoke(oic, service, QCOMTEE_FEATURE_VER_OP_GET, u, 671 + &result); 672 + 673 + out_failed: 674 + qcomtee_object_put(service); 675 + qcomtee_object_put(client_env); 676 + } 677 + 678 + static const struct tee_driver_ops qcomtee_ops = { 679 + .get_version = qcomtee_get_version, 680 + .open = qcomtee_open, 681 + .close_context = qcomtee_close_context, 682 + .release = qcomtee_release, 683 + .object_invoke_func = qcomtee_object_invoke, 684 + .supp_recv = qcomtee_supp_recv, 685 + .supp_send = qcomtee_supp_send, 686 + }; 687 + 688 + static const struct tee_desc qcomtee_desc = { 689 + .name = "qcomtee", 690 + .ops = &qcomtee_ops, 691 + .owner = THIS_MODULE, 692 + }; 693 + 694 + static int qcomtee_probe(struct platform_device *pdev) 695 + { 696 + struct workqueue_struct *async_wq; 697 + struct tee_device *teedev; 698 + struct tee_shm_pool *pool; 699 + struct tee_context *ctx; 700 + struct qcomtee *qcomtee; 701 + int err; 702 + 703 + qcomtee = kzalloc(sizeof(*qcomtee), GFP_KERNEL); 704 + if (!qcomtee) 705 + return -ENOMEM; 706 + 707 + pool = qcomtee_shm_pool_alloc(); 708 + if (IS_ERR(pool)) { 709 + err = PTR_ERR(pool); 710 + 711 + goto err_free_qcomtee; 712 + } 713 + 714 + teedev = tee_device_alloc(&qcomtee_desc, NULL, pool, qcomtee); 715 + if (IS_ERR(teedev)) { 716 + err = PTR_ERR(teedev); 717 + 718 + goto err_pool_destroy; 719 + } 720 + 721 + qcomtee->teedev = teedev; 722 + qcomtee->pool = pool; 723 + err = tee_device_register(qcomtee->teedev); 724 + if (err) 725 + goto err_unreg_teedev; 726 + 727 + platform_set_drvdata(pdev, qcomtee); 728 + /* Start async wq. */ 729 + async_wq = alloc_ordered_workqueue("qcomtee_wq", 0); 730 + if (!async_wq) { 731 + err = -ENOMEM; 732 + 733 + goto err_unreg_teedev; 734 + } 735 + 736 + qcomtee->wq = async_wq; 737 + /* Driver context used for async operations of teedev. */ 738 + ctx = teedev_open(qcomtee->teedev); 739 + if (IS_ERR(ctx)) { 740 + err = PTR_ERR(ctx); 741 + 742 + goto err_dest_wq; 743 + } 744 + 745 + qcomtee->ctx = ctx; 746 + /* Init Object table. */ 747 + qcomtee->xa_last_id = 0; 748 + xa_init_flags(&qcomtee->xa_local_objects, XA_FLAGS_ALLOC); 749 + /* Get QTEE verion. */ 750 + qcomtee_get_qtee_feature_list(qcomtee->ctx, 751 + QCOMTEE_FEATURE_VER_OP_GET_QTEE_ID, 752 + &qcomtee->qtee_version); 753 + 754 + pr_info("QTEE version %u.%u.%u\n", 755 + QTEE_VERSION_GET_MAJOR(qcomtee->qtee_version), 756 + QTEE_VERSION_GET_MINOR(qcomtee->qtee_version), 757 + QTEE_VERSION_GET_PATCH(qcomtee->qtee_version)); 758 + 759 + return 0; 760 + 761 + err_dest_wq: 762 + destroy_workqueue(qcomtee->wq); 763 + err_unreg_teedev: 764 + tee_device_unregister(qcomtee->teedev); 765 + err_pool_destroy: 766 + tee_shm_pool_free(pool); 767 + err_free_qcomtee: 768 + kfree(qcomtee); 769 + 770 + return err; 771 + } 772 + 773 + /** 774 + * qcomtee_remove() - Device Removal Routine. 775 + * @pdev: platform device information struct. 776 + * 777 + * It is called by the platform subsystem to alert the driver that it should 778 + * release the device. 779 + * 780 + * QTEE does not provide an API to inform it about a callback object going away. 781 + * However, when releasing QTEE objects, any callback object sent to QTEE 782 + * previously would be released by QTEE as part of the object release. 783 + */ 784 + static void qcomtee_remove(struct platform_device *pdev) 785 + { 786 + struct qcomtee *qcomtee = platform_get_drvdata(pdev); 787 + 788 + teedev_close_context(qcomtee->ctx); 789 + /* Wait for RELEASE operations to be processed for QTEE objects. */ 790 + tee_device_unregister(qcomtee->teedev); 791 + destroy_workqueue(qcomtee->wq); 792 + tee_shm_pool_free(qcomtee->pool); 793 + kfree(qcomtee); 794 + } 795 + 796 + static const struct platform_device_id qcomtee_ids[] = { { "qcomtee", 0 }, {} }; 797 + MODULE_DEVICE_TABLE(platform, qcomtee_ids); 798 + 799 + static struct platform_driver qcomtee_platform_driver = { 800 + .probe = qcomtee_probe, 801 + .remove = qcomtee_remove, 802 + .driver = { 803 + .name = "qcomtee", 804 + }, 805 + .id_table = qcomtee_ids, 806 + }; 807 + 808 + module_platform_driver(qcomtee_platform_driver); 809 + 810 + MODULE_AUTHOR("Qualcomm"); 811 + MODULE_DESCRIPTION("QTEE driver"); 812 + MODULE_VERSION("1.0"); 813 + MODULE_LICENSE("GPL");
+906
drivers/tee/qcomtee/core.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4 + */ 5 + 6 + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 7 + 8 + #include <linux/firmware/qcom/qcom_scm.h> 9 + #include <linux/init.h> 10 + #include <linux/module.h> 11 + #include <linux/slab.h> 12 + #include <linux/uaccess.h> 13 + #include <linux/xarray.h> 14 + 15 + #include "qcomtee.h" 16 + 17 + /* QTEE root object. */ 18 + struct qcomtee_object qcomtee_object_root = { 19 + .name = "root", 20 + .object_type = QCOMTEE_OBJECT_TYPE_ROOT, 21 + .info.qtee_id = QCOMTEE_MSG_OBJECT_ROOT, 22 + }; 23 + 24 + /* Next argument of type @type after index @i. */ 25 + int qcomtee_next_arg_type(struct qcomtee_arg *u, int i, 26 + enum qcomtee_arg_type type) 27 + { 28 + while (u[i].type != QCOMTEE_ARG_TYPE_INV && u[i].type != type) 29 + i++; 30 + return i; 31 + } 32 + 33 + /* 34 + * QTEE expects IDs with the QCOMTEE_MSG_OBJECT_NS_BIT set for objects 35 + * of the QCOMTEE_OBJECT_TYPE_CB type. 36 + */ 37 + #define QCOMTEE_OBJECT_ID_START (QCOMTEE_MSG_OBJECT_NS_BIT + 1) 38 + #define QCOMTEE_OBJECT_ID_END (U32_MAX) 39 + 40 + #define QCOMTEE_OBJECT_SET(p, type, ...) \ 41 + __QCOMTEE_OBJECT_SET(p, type, ##__VA_ARGS__, 0UL) 42 + #define __QCOMTEE_OBJECT_SET(p, type, optr, ...) \ 43 + do { \ 44 + (p)->object_type = (type); \ 45 + (p)->info.qtee_id = (unsigned long)(optr); \ 46 + } while (0) 47 + 48 + static struct qcomtee_object * 49 + qcomtee_qtee_object_alloc(struct qcomtee_object_invoke_ctx *oic, 50 + unsigned int object_id) 51 + { 52 + struct qcomtee *qcomtee = tee_get_drvdata(oic->ctx->teedev); 53 + struct qcomtee_object *object; 54 + 55 + object = kzalloc(sizeof(*object), GFP_KERNEL); 56 + if (!object) 57 + return NULL_QCOMTEE_OBJECT; 58 + 59 + /* If failed, "no-name". */ 60 + object->name = kasprintf(GFP_KERNEL, "qcomtee-%u", object_id); 61 + QCOMTEE_OBJECT_SET(object, QCOMTEE_OBJECT_TYPE_TEE, object_id); 62 + kref_init(&object->refcount); 63 + /* A QTEE object requires a context for async operations. */ 64 + object->info.qcomtee_async_ctx = qcomtee->ctx; 65 + teedev_ctx_get(object->info.qcomtee_async_ctx); 66 + 67 + return object; 68 + } 69 + 70 + static void qcomtee_qtee_object_free(struct qcomtee_object *object) 71 + { 72 + /* See qcomtee_qtee_object_alloc(). */ 73 + teedev_ctx_put(object->info.qcomtee_async_ctx); 74 + 75 + kfree(object->name); 76 + kfree(object); 77 + } 78 + 79 + static void qcomtee_do_release_qtee_object(struct work_struct *work) 80 + { 81 + struct qcomtee_object *object; 82 + struct qcomtee *qcomtee; 83 + int ret, result; 84 + 85 + /* RELEASE does not require any argument. */ 86 + struct qcomtee_arg args[] = { { .type = QCOMTEE_ARG_TYPE_INV } }; 87 + 88 + object = container_of(work, struct qcomtee_object, work); 89 + qcomtee = tee_get_drvdata(object->info.qcomtee_async_ctx->teedev); 90 + /* Get the TEE context used for asynchronous operations. */ 91 + qcomtee->oic.ctx = object->info.qcomtee_async_ctx; 92 + 93 + ret = qcomtee_object_do_invoke_internal(&qcomtee->oic, object, 94 + QCOMTEE_MSG_OBJECT_OP_RELEASE, 95 + args, &result); 96 + 97 + /* Is it safe to retry the release? */ 98 + if (ret && ret != -ENODEV) { 99 + queue_work(qcomtee->wq, &object->work); 100 + } else { 101 + if (ret || result) 102 + pr_err("%s release failed, ret = %d (%x)\n", 103 + qcomtee_object_name(object), ret, result); 104 + qcomtee_qtee_object_free(object); 105 + } 106 + } 107 + 108 + static void qcomtee_release_qtee_object(struct qcomtee_object *object) 109 + { 110 + struct qcomtee *qcomtee = 111 + tee_get_drvdata(object->info.qcomtee_async_ctx->teedev); 112 + 113 + INIT_WORK(&object->work, qcomtee_do_release_qtee_object); 114 + queue_work(qcomtee->wq, &object->work); 115 + } 116 + 117 + static void qcomtee_object_release(struct kref *refcount) 118 + { 119 + struct qcomtee_object *object; 120 + const char *name; 121 + 122 + object = container_of(refcount, struct qcomtee_object, refcount); 123 + 124 + /* 125 + * qcomtee_object_get() is called in a RCU read lock. synchronize_rcu() 126 + * to avoid releasing the object while it is being accessed in 127 + * qcomtee_object_get(). 128 + */ 129 + synchronize_rcu(); 130 + 131 + switch (typeof_qcomtee_object(object)) { 132 + case QCOMTEE_OBJECT_TYPE_TEE: 133 + qcomtee_release_qtee_object(object); 134 + 135 + break; 136 + case QCOMTEE_OBJECT_TYPE_CB: 137 + name = object->name; 138 + 139 + if (object->ops->release) 140 + object->ops->release(object); 141 + 142 + kfree_const(name); 143 + 144 + break; 145 + case QCOMTEE_OBJECT_TYPE_ROOT: 146 + case QCOMTEE_OBJECT_TYPE_NULL: 147 + default: 148 + break; 149 + } 150 + } 151 + 152 + /** 153 + * qcomtee_object_get() - Increase the object's reference count. 154 + * @object: object to increase the reference count. 155 + * 156 + * Context: The caller should hold RCU read lock. 157 + */ 158 + int qcomtee_object_get(struct qcomtee_object *object) 159 + { 160 + if (object != NULL_QCOMTEE_OBJECT && object != ROOT_QCOMTEE_OBJECT) 161 + return kref_get_unless_zero(&object->refcount); 162 + 163 + return 0; 164 + } 165 + 166 + /** 167 + * qcomtee_object_put() - Decrease the object's reference count. 168 + * @object: object to decrease the reference count. 169 + */ 170 + void qcomtee_object_put(struct qcomtee_object *object) 171 + { 172 + if (object != NULL_QCOMTEE_OBJECT && object != ROOT_QCOMTEE_OBJECT) 173 + kref_put(&object->refcount, qcomtee_object_release); 174 + } 175 + 176 + static int qcomtee_idx_alloc(struct qcomtee_object_invoke_ctx *oic, u32 *idx, 177 + struct qcomtee_object *object) 178 + { 179 + struct qcomtee *qcomtee = tee_get_drvdata(oic->ctx->teedev); 180 + 181 + /* Every ID allocated here has QCOMTEE_MSG_OBJECT_NS_BIT set. */ 182 + return xa_alloc_cyclic(&qcomtee->xa_local_objects, idx, object, 183 + XA_LIMIT(QCOMTEE_OBJECT_ID_START, 184 + QCOMTEE_OBJECT_ID_END), 185 + &qcomtee->xa_last_id, GFP_KERNEL); 186 + } 187 + 188 + struct qcomtee_object *qcomtee_idx_erase(struct qcomtee_object_invoke_ctx *oic, 189 + u32 idx) 190 + { 191 + struct qcomtee *qcomtee = tee_get_drvdata(oic->ctx->teedev); 192 + 193 + if (idx < QCOMTEE_OBJECT_ID_START || idx > QCOMTEE_OBJECT_ID_END) 194 + return NULL_QCOMTEE_OBJECT; 195 + 196 + return xa_erase(&qcomtee->xa_local_objects, idx); 197 + } 198 + 199 + /** 200 + * qcomtee_object_id_get() - Get an ID for an object to send to QTEE. 201 + * @oic: context to use for the invocation. 202 + * @object: object to assign an ID. 203 + * @object_id: object ID. 204 + * 205 + * Called on the path to QTEE to construct the message; see 206 + * qcomtee_prepare_msg() and qcomtee_update_msg(). 207 + * 208 + * Return: On success, returns 0; on failure, returns < 0. 209 + */ 210 + static int qcomtee_object_id_get(struct qcomtee_object_invoke_ctx *oic, 211 + struct qcomtee_object *object, 212 + unsigned int *object_id) 213 + { 214 + u32 idx; 215 + 216 + switch (typeof_qcomtee_object(object)) { 217 + case QCOMTEE_OBJECT_TYPE_CB: 218 + if (qcomtee_idx_alloc(oic, &idx, object) < 0) 219 + return -ENOSPC; 220 + 221 + *object_id = idx; 222 + 223 + break; 224 + case QCOMTEE_OBJECT_TYPE_ROOT: 225 + case QCOMTEE_OBJECT_TYPE_TEE: 226 + *object_id = object->info.qtee_id; 227 + 228 + break; 229 + case QCOMTEE_OBJECT_TYPE_NULL: 230 + *object_id = QCOMTEE_MSG_OBJECT_NULL; 231 + 232 + break; 233 + } 234 + 235 + return 0; 236 + } 237 + 238 + /* Release object ID assigned in qcomtee_object_id_get. */ 239 + static void qcomtee_object_id_put(struct qcomtee_object_invoke_ctx *oic, 240 + unsigned int object_id) 241 + { 242 + qcomtee_idx_erase(oic, object_id); 243 + } 244 + 245 + /** 246 + * qcomtee_local_object_get() - Get the object referenced by the ID. 247 + * @oic: context to use for the invocation. 248 + * @object_id: object ID. 249 + * 250 + * It is called on the path from QTEE. 251 + * It is called on behalf of QTEE to obtain an instance of an object 252 + * for a given ID. It increases the object's reference count on success. 253 + * 254 + * Return: On error, returns %NULL_QCOMTEE_OBJECT. 255 + * On success, returns the object. 256 + */ 257 + static struct qcomtee_object * 258 + qcomtee_local_object_get(struct qcomtee_object_invoke_ctx *oic, 259 + unsigned int object_id) 260 + { 261 + struct qcomtee *qcomtee = tee_get_drvdata(oic->ctx->teedev); 262 + struct qcomtee_object *object; 263 + 264 + guard(rcu)(); 265 + object = xa_load(&qcomtee->xa_local_objects, object_id); 266 + /* It already checks for %NULL_QCOMTEE_OBJECT. */ 267 + qcomtee_object_get(object); 268 + 269 + return object; 270 + } 271 + 272 + /** 273 + * qcomtee_object_user_init() - Initialize an object for the user. 274 + * @object: object to initialize. 275 + * @ot: type of object as &enum qcomtee_object_type. 276 + * @ops: instance of callbacks. 277 + * @fmt: name assigned to the object. 278 + * 279 + * Return: On success, returns 0; on failure, returns < 0. 280 + */ 281 + int qcomtee_object_user_init(struct qcomtee_object *object, 282 + enum qcomtee_object_type ot, 283 + struct qcomtee_object_operations *ops, 284 + const char *fmt, ...) 285 + { 286 + va_list ap; 287 + int ret; 288 + 289 + kref_init(&object->refcount); 290 + QCOMTEE_OBJECT_SET(object, QCOMTEE_OBJECT_TYPE_NULL); 291 + 292 + va_start(ap, fmt); 293 + switch (ot) { 294 + case QCOMTEE_OBJECT_TYPE_NULL: 295 + ret = 0; 296 + 297 + break; 298 + case QCOMTEE_OBJECT_TYPE_CB: 299 + object->ops = ops; 300 + if (!object->ops->dispatch) 301 + return -EINVAL; 302 + 303 + /* If failed, "no-name". */ 304 + object->name = kvasprintf_const(GFP_KERNEL, fmt, ap); 305 + QCOMTEE_OBJECT_SET(object, QCOMTEE_OBJECT_TYPE_CB); 306 + 307 + ret = 0; 308 + break; 309 + case QCOMTEE_OBJECT_TYPE_ROOT: 310 + case QCOMTEE_OBJECT_TYPE_TEE: 311 + default: 312 + ret = -EINVAL; 313 + } 314 + va_end(ap); 315 + 316 + return ret; 317 + } 318 + 319 + /** 320 + * qcomtee_object_type() - Returns the type of object represented by an ID. 321 + * @object_id: object ID for the object. 322 + * 323 + * Similar to typeof_qcomtee_object(), but instead of receiving an object as 324 + * an argument, it receives an object ID. It is used internally on the return 325 + * path from QTEE. 326 + * 327 + * Return: Returns the type of object referenced by @object_id. 328 + */ 329 + static enum qcomtee_object_type qcomtee_object_type(unsigned int object_id) 330 + { 331 + if (object_id == QCOMTEE_MSG_OBJECT_NULL) 332 + return QCOMTEE_OBJECT_TYPE_NULL; 333 + 334 + if (object_id & QCOMTEE_MSG_OBJECT_NS_BIT) 335 + return QCOMTEE_OBJECT_TYPE_CB; 336 + 337 + return QCOMTEE_OBJECT_TYPE_TEE; 338 + } 339 + 340 + /** 341 + * qcomtee_object_qtee_init() - Initialize an object for QTEE. 342 + * @oic: context to use for the invocation. 343 + * @object: object returned. 344 + * @object_id: object ID received from QTEE. 345 + * 346 + * Return: On failure, returns < 0 and sets @object to %NULL_QCOMTEE_OBJECT. 347 + * On success, returns 0 348 + */ 349 + static int qcomtee_object_qtee_init(struct qcomtee_object_invoke_ctx *oic, 350 + struct qcomtee_object **object, 351 + unsigned int object_id) 352 + { 353 + int ret = 0; 354 + 355 + switch (qcomtee_object_type(object_id)) { 356 + case QCOMTEE_OBJECT_TYPE_NULL: 357 + *object = NULL_QCOMTEE_OBJECT; 358 + 359 + break; 360 + case QCOMTEE_OBJECT_TYPE_CB: 361 + *object = qcomtee_local_object_get(oic, object_id); 362 + if (*object == NULL_QCOMTEE_OBJECT) 363 + ret = -EINVAL; 364 + 365 + break; 366 + 367 + default: /* QCOMTEE_OBJECT_TYPE_TEE */ 368 + *object = qcomtee_qtee_object_alloc(oic, object_id); 369 + if (*object == NULL_QCOMTEE_OBJECT) 370 + ret = -ENOMEM; 371 + 372 + break; 373 + } 374 + 375 + return ret; 376 + } 377 + 378 + /* 379 + * ''Marshaling API'' 380 + * qcomtee_prepare_msg - Prepare the inbound buffer for sending to QTEE 381 + * qcomtee_update_args - Parse the QTEE response in the inbound buffer 382 + * qcomtee_prepare_args - Parse the QTEE request from the outbound buffer 383 + * qcomtee_update_msg - Update the outbound buffer with the response for QTEE 384 + */ 385 + 386 + static int qcomtee_prepare_msg(struct qcomtee_object_invoke_ctx *oic, 387 + struct qcomtee_object *object, u32 op, 388 + struct qcomtee_arg *u) 389 + { 390 + struct qcomtee_msg_object_invoke *msg; 391 + unsigned int object_id; 392 + int i, ib, ob, io, oo; 393 + size_t offset; 394 + 395 + /* Use the input message buffer in 'oic'. */ 396 + msg = oic->in_msg.addr; 397 + 398 + /* Start offset in a message for buffer arguments. */ 399 + offset = qcomtee_msg_buffer_args(struct qcomtee_msg_object_invoke, 400 + qcomtee_args_len(u)); 401 + 402 + /* Get the ID of the object being invoked. */ 403 + if (qcomtee_object_id_get(oic, object, &object_id)) 404 + return -ENOSPC; 405 + 406 + ib = 0; 407 + qcomtee_arg_for_each_input_buffer(i, u) { 408 + void *msgptr; /* Address of buffer payload: */ 409 + /* Overflow already checked in qcomtee_msg_buffers_alloc(). */ 410 + msg->args[ib].b.offset = offset; 411 + msg->args[ib].b.size = u[i].b.size; 412 + 413 + msgptr = qcomtee_msg_offset_to_ptr(msg, offset); 414 + /* Userspace client or kernel client!? */ 415 + if (!(u[i].flags & QCOMTEE_ARG_FLAGS_UADDR)) 416 + memcpy(msgptr, u[i].b.addr, u[i].b.size); 417 + else if (copy_from_user(msgptr, u[i].b.uaddr, u[i].b.size)) 418 + return -EINVAL; 419 + 420 + offset += qcomtee_msg_offset_align(u[i].b.size); 421 + ib++; 422 + } 423 + 424 + ob = ib; 425 + qcomtee_arg_for_each_output_buffer(i, u) { 426 + /* Overflow already checked in qcomtee_msg_buffers_alloc(). */ 427 + msg->args[ob].b.offset = offset; 428 + msg->args[ob].b.size = u[i].b.size; 429 + 430 + offset += qcomtee_msg_offset_align(u[i].b.size); 431 + ob++; 432 + } 433 + 434 + io = ob; 435 + qcomtee_arg_for_each_input_object(i, u) { 436 + if (qcomtee_object_id_get(oic, u[i].o, &msg->args[io].o)) { 437 + qcomtee_object_id_put(oic, object_id); 438 + for (io--; io >= ob; io--) 439 + qcomtee_object_id_put(oic, msg->args[io].o); 440 + 441 + return -ENOSPC; 442 + } 443 + 444 + io++; 445 + } 446 + 447 + oo = io; 448 + qcomtee_arg_for_each_output_object(i, u) 449 + oo++; 450 + 451 + /* Set object, operation, and argument counts. */ 452 + qcomtee_msg_init(msg, object_id, op, ib, ob, io, oo); 453 + 454 + return 0; 455 + } 456 + 457 + /** 458 + * qcomtee_update_args() - Parse the QTEE response in the inbound buffer. 459 + * @u: array of arguments for the invocation. 460 + * @oic: context to use for the invocation. 461 + * 462 + * @u must be the same as the one used in qcomtee_prepare_msg() when 463 + * initializing the inbound buffer. 464 + * 465 + * On failure, it continues processing the QTEE message. The caller should 466 + * do the necessary cleanup, including calling qcomtee_object_put() 467 + * on the output objects. 468 + * 469 + * Return: On success, returns 0; on failure, returns < 0. 470 + */ 471 + static int qcomtee_update_args(struct qcomtee_arg *u, 472 + struct qcomtee_object_invoke_ctx *oic) 473 + { 474 + struct qcomtee_msg_object_invoke *msg; 475 + int i, ib, ob, io, oo; 476 + int ret = 0; 477 + 478 + /* Use the input message buffer in 'oic'. */ 479 + msg = oic->in_msg.addr; 480 + 481 + ib = 0; 482 + qcomtee_arg_for_each_input_buffer(i, u) 483 + ib++; 484 + 485 + ob = ib; 486 + qcomtee_arg_for_each_output_buffer(i, u) { 487 + void *msgptr; /* Address of buffer payload: */ 488 + /* QTEE can override the size to a smaller value. */ 489 + u[i].b.size = msg->args[ob].b.size; 490 + 491 + msgptr = qcomtee_msg_offset_to_ptr(msg, msg->args[ob].b.offset); 492 + /* Userspace client or kernel client!? */ 493 + if (!(u[i].flags & QCOMTEE_ARG_FLAGS_UADDR)) 494 + memcpy(u[i].b.addr, msgptr, u[i].b.size); 495 + else if (copy_to_user(u[i].b.uaddr, msgptr, u[i].b.size)) 496 + ret = -EINVAL; 497 + 498 + ob++; 499 + } 500 + 501 + io = ob; 502 + qcomtee_arg_for_each_input_object(i, u) 503 + io++; 504 + 505 + oo = io; 506 + qcomtee_arg_for_each_output_object(i, u) { 507 + if (qcomtee_object_qtee_init(oic, &u[i].o, msg->args[oo].o)) 508 + ret = -EINVAL; 509 + 510 + oo++; 511 + } 512 + 513 + return ret; 514 + } 515 + 516 + /** 517 + * qcomtee_prepare_args() - Parse the QTEE request from the outbound buffer. 518 + * @oic: context to use for the invocation. 519 + * 520 + * It initializes &qcomtee_object_invoke_ctx->u based on the QTEE request in 521 + * the outbound buffer. It sets %QCOMTEE_ARG_TYPE_INV at the end of the array. 522 + * 523 + * On failure, it continues processing the QTEE message. The caller should 524 + * do the necessary cleanup, including calling qcomtee_object_put() 525 + * on the input objects. 526 + * 527 + * Return: On success, returns 0; on failure, returns < 0. 528 + */ 529 + static int qcomtee_prepare_args(struct qcomtee_object_invoke_ctx *oic) 530 + { 531 + struct qcomtee_msg_callback *msg; 532 + int i, ret = 0; 533 + 534 + /* Use the output message buffer in 'oic'. */ 535 + msg = oic->out_msg.addr; 536 + 537 + qcomtee_msg_for_each_input_buffer(i, msg) { 538 + oic->u[i].b.addr = 539 + qcomtee_msg_offset_to_ptr(msg, msg->args[i].b.offset); 540 + oic->u[i].b.size = msg->args[i].b.size; 541 + oic->u[i].type = QCOMTEE_ARG_TYPE_IB; 542 + } 543 + 544 + qcomtee_msg_for_each_output_buffer(i, msg) { 545 + oic->u[i].b.addr = 546 + qcomtee_msg_offset_to_ptr(msg, msg->args[i].b.offset); 547 + oic->u[i].b.size = msg->args[i].b.size; 548 + oic->u[i].type = QCOMTEE_ARG_TYPE_OB; 549 + } 550 + 551 + qcomtee_msg_for_each_input_object(i, msg) { 552 + if (qcomtee_object_qtee_init(oic, &oic->u[i].o, msg->args[i].o)) 553 + ret = -EINVAL; 554 + 555 + oic->u[i].type = QCOMTEE_ARG_TYPE_IO; 556 + } 557 + 558 + qcomtee_msg_for_each_output_object(i, msg) 559 + oic->u[i].type = QCOMTEE_ARG_TYPE_OO; 560 + 561 + /* End of Arguments. */ 562 + oic->u[i].type = QCOMTEE_ARG_TYPE_INV; 563 + 564 + return ret; 565 + } 566 + 567 + static int qcomtee_update_msg(struct qcomtee_object_invoke_ctx *oic) 568 + { 569 + struct qcomtee_msg_callback *msg; 570 + int i, ib, ob, io, oo; 571 + 572 + /* Use the output message buffer in 'oic'. */ 573 + msg = oic->out_msg.addr; 574 + 575 + ib = 0; 576 + qcomtee_arg_for_each_input_buffer(i, oic->u) 577 + ib++; 578 + 579 + ob = ib; 580 + qcomtee_arg_for_each_output_buffer(i, oic->u) { 581 + /* Only reduce size; never increase it. */ 582 + if (msg->args[ob].b.size < oic->u[i].b.size) 583 + return -EINVAL; 584 + 585 + msg->args[ob].b.size = oic->u[i].b.size; 586 + ob++; 587 + } 588 + 589 + io = ob; 590 + qcomtee_arg_for_each_input_object(i, oic->u) 591 + io++; 592 + 593 + oo = io; 594 + qcomtee_arg_for_each_output_object(i, oic->u) { 595 + if (qcomtee_object_id_get(oic, oic->u[i].o, &msg->args[oo].o)) { 596 + for (oo--; oo >= io; oo--) 597 + qcomtee_object_id_put(oic, msg->args[oo].o); 598 + 599 + return -ENOSPC; 600 + } 601 + 602 + oo++; 603 + } 604 + 605 + return 0; 606 + } 607 + 608 + /* Invoke a callback object. */ 609 + static void qcomtee_cb_object_invoke(struct qcomtee_object_invoke_ctx *oic, 610 + struct qcomtee_msg_callback *msg) 611 + { 612 + int i, errno; 613 + u32 op; 614 + 615 + /* Get the object being invoked. */ 616 + unsigned int object_id = msg->cxt; 617 + struct qcomtee_object *object; 618 + 619 + /* QTEE cannot invoke a NULL object or objects it hosts. */ 620 + if (qcomtee_object_type(object_id) == QCOMTEE_OBJECT_TYPE_NULL || 621 + qcomtee_object_type(object_id) == QCOMTEE_OBJECT_TYPE_TEE) { 622 + errno = -EINVAL; 623 + goto out; 624 + } 625 + 626 + object = qcomtee_local_object_get(oic, object_id); 627 + if (object == NULL_QCOMTEE_OBJECT) { 628 + errno = -EINVAL; 629 + goto out; 630 + } 631 + 632 + oic->object = object; 633 + 634 + /* Filter bits used by transport. */ 635 + op = msg->op & QCOMTEE_MSG_OBJECT_OP_MASK; 636 + 637 + switch (op) { 638 + case QCOMTEE_MSG_OBJECT_OP_RELEASE: 639 + qcomtee_object_id_put(oic, object_id); 640 + qcomtee_object_put(object); 641 + errno = 0; 642 + 643 + break; 644 + case QCOMTEE_MSG_OBJECT_OP_RETAIN: 645 + qcomtee_object_get(object); 646 + errno = 0; 647 + 648 + break; 649 + default: 650 + errno = qcomtee_prepare_args(oic); 651 + if (errno) { 652 + /* Release any object that arrived as input. */ 653 + qcomtee_arg_for_each_input_buffer(i, oic->u) 654 + qcomtee_object_put(oic->u[i].o); 655 + 656 + break; 657 + } 658 + 659 + errno = object->ops->dispatch(oic, object, op, oic->u); 660 + if (!errno) { 661 + /* On success, notify at the appropriate time. */ 662 + oic->flags |= QCOMTEE_OIC_FLAG_NOTIFY; 663 + } 664 + } 665 + 666 + out: 667 + 668 + oic->errno = errno; 669 + } 670 + 671 + static int 672 + qcomtee_object_invoke_ctx_invoke(struct qcomtee_object_invoke_ctx *oic, 673 + int *result, u64 *res_type) 674 + { 675 + phys_addr_t out_msg_paddr; 676 + phys_addr_t in_msg_paddr; 677 + int ret; 678 + u64 res; 679 + 680 + tee_shm_get_pa(oic->out_shm, 0, &out_msg_paddr); 681 + tee_shm_get_pa(oic->in_shm, 0, &in_msg_paddr); 682 + if (!(oic->flags & QCOMTEE_OIC_FLAG_BUSY)) 683 + ret = qcom_scm_qtee_invoke_smc(in_msg_paddr, oic->in_msg.size, 684 + out_msg_paddr, oic->out_msg.size, 685 + &res, res_type); 686 + else 687 + ret = qcom_scm_qtee_callback_response(out_msg_paddr, 688 + oic->out_msg.size, 689 + &res, res_type); 690 + 691 + if (ret) 692 + pr_err("QTEE returned with %d.\n", ret); 693 + else 694 + *result = (int)res; 695 + 696 + return ret; 697 + } 698 + 699 + /** 700 + * qcomtee_qtee_objects_put() - Put the callback objects in the argument array. 701 + * @u: array of arguments. 702 + * 703 + * When qcomtee_object_do_invoke_internal() is successfully invoked, 704 + * QTEE takes ownership of the callback objects. If the invocation fails, 705 + * qcomtee_object_do_invoke_internal() calls qcomtee_qtee_objects_put() 706 + * to mimic the release of callback objects by QTEE. 707 + */ 708 + static void qcomtee_qtee_objects_put(struct qcomtee_arg *u) 709 + { 710 + int i; 711 + 712 + qcomtee_arg_for_each_input_object(i, u) { 713 + if (typeof_qcomtee_object(u[i].o) == QCOMTEE_OBJECT_TYPE_CB) 714 + qcomtee_object_put(u[i].o); 715 + } 716 + } 717 + 718 + /** 719 + * qcomtee_object_do_invoke_internal() - Submit an invocation for an object. 720 + * @oic: context to use for the current invocation. 721 + * @object: object being invoked. 722 + * @op: requested operation on the object. 723 + * @u: array of arguments for the current invocation. 724 + * @result: result returned from QTEE. 725 + * 726 + * The caller is responsible for keeping track of the refcount for each 727 + * object, including @object. On return, the caller loses ownership of all 728 + * input objects of type %QCOMTEE_OBJECT_TYPE_CB. 729 + * 730 + * Return: On success, returns 0; on failure, returns < 0. 731 + */ 732 + int qcomtee_object_do_invoke_internal(struct qcomtee_object_invoke_ctx *oic, 733 + struct qcomtee_object *object, u32 op, 734 + struct qcomtee_arg *u, int *result) 735 + { 736 + struct qcomtee_msg_callback *cb_msg; 737 + struct qcomtee_object *qto; 738 + int i, ret, errno; 739 + u64 res_type; 740 + 741 + /* Allocate inbound and outbound buffers. */ 742 + ret = qcomtee_msg_buffers_alloc(oic, u); 743 + if (ret) { 744 + qcomtee_qtee_objects_put(u); 745 + 746 + return ret; 747 + } 748 + 749 + ret = qcomtee_prepare_msg(oic, object, op, u); 750 + if (ret) { 751 + qcomtee_qtee_objects_put(u); 752 + 753 + goto out; 754 + } 755 + 756 + /* Use input message buffer in 'oic'. */ 757 + cb_msg = oic->out_msg.addr; 758 + 759 + while (1) { 760 + if (oic->flags & QCOMTEE_OIC_FLAG_BUSY) { 761 + errno = oic->errno; 762 + if (!errno) 763 + errno = qcomtee_update_msg(oic); 764 + qcomtee_msg_set_result(cb_msg, errno); 765 + } 766 + 767 + /* Invoke the remote object. */ 768 + ret = qcomtee_object_invoke_ctx_invoke(oic, result, &res_type); 769 + /* Return form callback objects result submission: */ 770 + if (oic->flags & QCOMTEE_OIC_FLAG_BUSY) { 771 + qto = oic->object; 772 + if (qto) { 773 + if (oic->flags & QCOMTEE_OIC_FLAG_NOTIFY) { 774 + if (qto->ops->notify) 775 + qto->ops->notify(oic, qto, 776 + errno || ret); 777 + } 778 + 779 + /* Get is in qcomtee_cb_object_invoke(). */ 780 + qcomtee_object_put(qto); 781 + } 782 + 783 + oic->object = NULL_QCOMTEE_OBJECT; 784 + oic->flags &= ~(QCOMTEE_OIC_FLAG_BUSY | 785 + QCOMTEE_OIC_FLAG_NOTIFY); 786 + } 787 + 788 + if (ret) { 789 + /* 790 + * Unable to finished the invocation. 791 + * If QCOMTEE_OIC_FLAG_SHARED is not set, put 792 + * QCOMTEE_OBJECT_TYPE_CB input objects. 793 + */ 794 + if (!(oic->flags & QCOMTEE_OIC_FLAG_SHARED)) 795 + qcomtee_qtee_objects_put(u); 796 + else 797 + ret = -ENODEV; 798 + 799 + goto out; 800 + 801 + } else { 802 + /* 803 + * QTEE obtained ownership of QCOMTEE_OBJECT_TYPE_CB 804 + * input objects in 'u'. On further failure, QTEE is 805 + * responsible for releasing them. 806 + */ 807 + oic->flags |= QCOMTEE_OIC_FLAG_SHARED; 808 + } 809 + 810 + /* Is it a callback request? */ 811 + if (res_type != QCOMTEE_RESULT_INBOUND_REQ_NEEDED) { 812 + /* 813 + * Parse results. If failed, assume the service 814 + * was unavailable (i.e. QCOMTEE_MSG_ERROR_UNAVAIL) 815 + * and put output objects to initiate cleanup. 816 + */ 817 + if (!*result && qcomtee_update_args(u, oic)) { 818 + *result = QCOMTEE_MSG_ERROR_UNAVAIL; 819 + qcomtee_arg_for_each_output_object(i, u) 820 + qcomtee_object_put(u[i].o); 821 + } 822 + 823 + break; 824 + 825 + } else { 826 + oic->flags |= QCOMTEE_OIC_FLAG_BUSY; 827 + qcomtee_fetch_async_reqs(oic); 828 + qcomtee_cb_object_invoke(oic, cb_msg); 829 + } 830 + } 831 + 832 + qcomtee_fetch_async_reqs(oic); 833 + out: 834 + qcomtee_msg_buffers_free(oic); 835 + 836 + return ret; 837 + } 838 + 839 + int qcomtee_object_do_invoke(struct qcomtee_object_invoke_ctx *oic, 840 + struct qcomtee_object *object, u32 op, 841 + struct qcomtee_arg *u, int *result) 842 + { 843 + /* User can not set bits used by transport. */ 844 + if (op & ~QCOMTEE_MSG_OBJECT_OP_MASK) 845 + return -EINVAL; 846 + 847 + /* User can only invoke QTEE hosted objects. */ 848 + if (typeof_qcomtee_object(object) != QCOMTEE_OBJECT_TYPE_TEE && 849 + typeof_qcomtee_object(object) != QCOMTEE_OBJECT_TYPE_ROOT) 850 + return -EINVAL; 851 + 852 + /* User cannot directly issue these operations to QTEE. */ 853 + if (op == QCOMTEE_MSG_OBJECT_OP_RELEASE || 854 + op == QCOMTEE_MSG_OBJECT_OP_RETAIN) 855 + return -EINVAL; 856 + 857 + return qcomtee_object_do_invoke_internal(oic, object, op, u, result); 858 + } 859 + 860 + /** 861 + * qcomtee_object_get_client_env() - Get a privileged client env. object. 862 + * @oic: context to use for the current invocation. 863 + * 864 + * The caller should call qcomtee_object_put() on the returned object 865 + * to release it. 866 + * 867 + * Return: On error, returns %NULL_QCOMTEE_OBJECT. 868 + * On success, returns the object. 869 + */ 870 + struct qcomtee_object * 871 + qcomtee_object_get_client_env(struct qcomtee_object_invoke_ctx *oic) 872 + { 873 + struct qcomtee_arg u[3] = { 0 }; 874 + int ret, result; 875 + 876 + u[0].o = NULL_QCOMTEE_OBJECT; 877 + u[0].type = QCOMTEE_ARG_TYPE_IO; 878 + u[1].type = QCOMTEE_ARG_TYPE_OO; 879 + ret = qcomtee_object_do_invoke(oic, ROOT_QCOMTEE_OBJECT, 880 + QCOMTEE_ROOT_OP_REG_WITH_CREDENTIALS, u, 881 + &result); 882 + if (ret || result) 883 + return NULL_QCOMTEE_OBJECT; 884 + 885 + return u[1].o; 886 + } 887 + 888 + struct qcomtee_object * 889 + qcomtee_object_get_service(struct qcomtee_object_invoke_ctx *oic, 890 + struct qcomtee_object *client_env, u32 uid) 891 + { 892 + struct qcomtee_arg u[3] = { 0 }; 893 + int ret, result; 894 + 895 + u[0].b.addr = &uid; 896 + u[0].b.size = sizeof(uid); 897 + u[0].type = QCOMTEE_ARG_TYPE_IB; 898 + u[1].type = QCOMTEE_ARG_TYPE_OO; 899 + ret = qcomtee_object_do_invoke(oic, client_env, QCOMTEE_CLIENT_ENV_OPEN, 900 + u, &result); 901 + 902 + if (ret || result) 903 + return NULL_QCOMTEE_OBJECT; 904 + 905 + return u[1].o; 906 + }
+143
drivers/tee/qcomtee/qcomtee.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4 + */ 5 + 6 + #ifndef QCOMTEE_H 7 + #define QCOMTEE_H 8 + 9 + #include <linux/kobject.h> 10 + #include <linux/tee_core.h> 11 + 12 + #include "qcomtee_msg.h" 13 + #include "qcomtee_object.h" 14 + 15 + /* Flags relating to object reference. */ 16 + #define QCOMTEE_OBJREF_FLAG_TEE BIT(0) 17 + #define QCOMTEE_OBJREF_FLAG_USER BIT(1) 18 + 19 + /** 20 + * struct qcomtee - Main service struct. 21 + * @teedev: client device. 22 + * @pool: shared memory pool. 23 + * @ctx: driver private context. 24 + * @oic: context to use for the current driver invocation. 25 + * @wq: workqueue for QTEE async operations. 26 + * @xa_local_objects: array of objects exported to QTEE. 27 + * @xa_last_id: next ID to allocate. 28 + * @qtee_version: QTEE version. 29 + */ 30 + struct qcomtee { 31 + struct tee_device *teedev; 32 + struct tee_shm_pool *pool; 33 + struct tee_context *ctx; 34 + struct qcomtee_object_invoke_ctx oic; 35 + struct workqueue_struct *wq; 36 + struct xarray xa_local_objects; 37 + u32 xa_last_id; 38 + u32 qtee_version; 39 + }; 40 + 41 + void qcomtee_fetch_async_reqs(struct qcomtee_object_invoke_ctx *oic); 42 + struct qcomtee_object *qcomtee_idx_erase(struct qcomtee_object_invoke_ctx *oic, 43 + u32 idx); 44 + 45 + struct tee_shm_pool *qcomtee_shm_pool_alloc(void); 46 + void qcomtee_msg_buffers_free(struct qcomtee_object_invoke_ctx *oic); 47 + int qcomtee_msg_buffers_alloc(struct qcomtee_object_invoke_ctx *oic, 48 + struct qcomtee_arg *u); 49 + 50 + /** 51 + * qcomtee_object_do_invoke_internal() - Submit an invocation for an object. 52 + * @oic: context to use for the current invocation. 53 + * @object: object being invoked. 54 + * @op: requested operation on the object. 55 + * @u: array of arguments for the current invocation. 56 + * @result: result returned from QTEE. 57 + * 58 + * The caller is responsible for keeping track of the refcount for each 59 + * object, including @object. On return, the caller loses ownership of all 60 + * input objects of type %QCOMTEE_OBJECT_TYPE_CB. 61 + * 62 + * Return: On success, returns 0; on failure, returns < 0. 63 + */ 64 + int qcomtee_object_do_invoke_internal(struct qcomtee_object_invoke_ctx *oic, 65 + struct qcomtee_object *object, u32 op, 66 + struct qcomtee_arg *u, int *result); 67 + 68 + /** 69 + * struct qcomtee_context_data - Clients' or supplicants' context. 70 + * @qtee_objects_idr: QTEE objects in this context. 71 + * @qtee_lock: mutex for @qtee_objects_idr. 72 + * @reqs_idr: requests in this context that hold ID. 73 + * @reqs_list: FIFO for requests in PROCESSING or QUEUED state. 74 + * @reqs_lock: mutex for @reqs_idr, @reqs_list and request states. 75 + * @req_c: completion used when the supplicant is waiting for requests. 76 + * @released: state of this context. 77 + */ 78 + struct qcomtee_context_data { 79 + struct idr qtee_objects_idr; 80 + /* Synchronize access to @qtee_objects_idr. */ 81 + struct mutex qtee_lock; 82 + 83 + struct idr reqs_idr; 84 + struct list_head reqs_list; 85 + /* Synchronize access to @reqs_idr, @reqs_list and updating requests states. */ 86 + struct mutex reqs_lock; 87 + 88 + struct completion req_c; 89 + 90 + bool released; 91 + }; 92 + 93 + int qcomtee_context_add_qtee_object(struct tee_param *param, 94 + struct qcomtee_object *object, 95 + struct tee_context *ctx); 96 + int qcomtee_context_find_qtee_object(struct qcomtee_object **object, 97 + struct tee_param *param, 98 + struct tee_context *ctx); 99 + void qcomtee_context_del_qtee_object(struct tee_param *param, 100 + struct tee_context *ctx); 101 + 102 + int qcomtee_objref_to_arg(struct qcomtee_arg *arg, struct tee_param *param, 103 + struct tee_context *ctx); 104 + int qcomtee_objref_from_arg(struct tee_param *param, struct qcomtee_arg *arg, 105 + struct tee_context *ctx); 106 + 107 + /* OBJECTS: */ 108 + 109 + /* (1) User Object API. */ 110 + 111 + int is_qcomtee_user_object(struct qcomtee_object *object); 112 + void qcomtee_user_object_set_notify(struct qcomtee_object *object, bool notify); 113 + void qcomtee_requests_destroy(struct qcomtee_context_data *ctxdata); 114 + int qcomtee_user_param_to_object(struct qcomtee_object **object, 115 + struct tee_param *param, 116 + struct tee_context *ctx); 117 + int qcomtee_user_param_from_object(struct tee_param *param, 118 + struct qcomtee_object *object, 119 + struct tee_context *ctx); 120 + 121 + /** 122 + * struct qcomtee_user_object_request_data - Data for user object request. 123 + * @id: ID assigned to the request. 124 + * @object_id: Object ID being invoked by QTEE. 125 + * @op: Requested operation on object. 126 + * @np: Number of parameters in the request. 127 + */ 128 + struct qcomtee_user_object_request_data { 129 + int id; 130 + u64 object_id; 131 + u32 op; 132 + int np; 133 + }; 134 + 135 + int qcomtee_user_object_select(struct tee_context *ctx, 136 + struct tee_param *params, int num_params, 137 + void __user *uaddr, size_t size, 138 + struct qcomtee_user_object_request_data *data); 139 + int qcomtee_user_object_submit(struct tee_context *ctx, 140 + struct tee_param *params, int num_params, 141 + int req_id, int errno); 142 + 143 + #endif /* QCOMTEE_H */
+304
drivers/tee/qcomtee/qcomtee_msg.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4 + */ 5 + 6 + #ifndef QCOMTEE_MSG_H 7 + #define QCOMTEE_MSG_H 8 + 9 + #include <linux/bitfield.h> 10 + 11 + /** 12 + * DOC: ''Qualcomm TEE'' (QTEE) Transport Message 13 + * 14 + * There are two buffers shared with QTEE: inbound and outbound buffers. 15 + * The inbound buffer is used for direct object invocation, and the outbound 16 + * buffer is used to make a request from QTEE to the kernel; i.e., a callback 17 + * request. 18 + * 19 + * The unused tail of the outbound buffer is also used for sending and 20 + * receiving asynchronous messages. An asynchronous message is independent of 21 + * the current object invocation (i.e., contents of the inbound buffer) or 22 + * callback request (i.e., the head of the outbound buffer); see 23 + * qcomtee_get_async_buffer(). It is used by endpoints (QTEE or kernel) as an 24 + * optimization to reduce the number of context switches between the secure and 25 + * non-secure worlds. 26 + * 27 + * For instance, QTEE never sends an explicit callback request to release an 28 + * object in the kernel. Instead, it sends asynchronous release messages in the 29 + * outbound buffer when QTEE returns from the previous direct object invocation, 30 + * or appends asynchronous release messages after the current callback request. 31 + * 32 + * QTEE supports two types of arguments in a message: buffer and object 33 + * arguments. Depending on the direction of data flow, they could be input 34 + * buffer (IO) to QTEE, output buffer (OB) from QTEE, input object (IO) to QTEE, 35 + * or output object (OO) from QTEE. Object arguments hold object IDs. Buffer 36 + * arguments hold (offset, size) pairs into the inbound or outbound buffers. 37 + * 38 + * QTEE holds an object table for objects it hosts and exposes to the kernel. 39 + * An object ID is an index to the object table in QTEE. 40 + * 41 + * For the direct object invocation message format in the inbound buffer, see 42 + * &struct qcomtee_msg_object_invoke. For the callback request message format 43 + * in the outbound buffer, see &struct qcomtee_msg_callback. For the message 44 + * format for asynchronous messages in the outbound buffer, see 45 + * &struct qcomtee_async_msg_hdr. 46 + */ 47 + 48 + /** 49 + * define QCOMTEE_MSG_OBJECT_NS_BIT - Non-secure bit 50 + * 51 + * Object ID is a globally unique 32-bit number. IDs referencing objects 52 + * in the kernel should have %QCOMTEE_MSG_OBJECT_NS_BIT set. 53 + */ 54 + #define QCOMTEE_MSG_OBJECT_NS_BIT BIT(31) 55 + 56 + /* Static object IDs recognized by QTEE. */ 57 + #define QCOMTEE_MSG_OBJECT_NULL (0U) 58 + #define QCOMTEE_MSG_OBJECT_ROOT (1U) 59 + 60 + /* Definitions from QTEE as part of the transport protocol. */ 61 + 62 + /* qcomtee_msg_arg is an argument as recognized by QTEE. */ 63 + union qcomtee_msg_arg { 64 + struct { 65 + u32 offset; 66 + u32 size; 67 + } b; 68 + u32 o; 69 + }; 70 + 71 + /* BI and BO payloads in QTEE messages should be at 64-bit boundaries. */ 72 + #define qcomtee_msg_offset_align(o) ALIGN((o), sizeof(u64)) 73 + 74 + /* Operations for objects are 32-bit. Transport uses the upper 16 bits. */ 75 + #define QCOMTEE_MSG_OBJECT_OP_MASK GENMASK(15, 0) 76 + 77 + /* Reserved Operation IDs sent to QTEE: */ 78 + /* QCOMTEE_MSG_OBJECT_OP_RELEASE - Reduces the refcount and releases the object. 79 + * QCOMTEE_MSG_OBJECT_OP_RETAIN - Increases the refcount. 80 + * 81 + * These operation IDs are valid for all objects. 82 + */ 83 + 84 + #define QCOMTEE_MSG_OBJECT_OP_RELEASE (QCOMTEE_MSG_OBJECT_OP_MASK - 0) 85 + #define QCOMTEE_MSG_OBJECT_OP_RETAIN (QCOMTEE_MSG_OBJECT_OP_MASK - 1) 86 + 87 + /* Subset of operations supported by QTEE root object. */ 88 + 89 + #define QCOMTEE_ROOT_OP_REG_WITH_CREDENTIALS 5 90 + #define QCOMTEE_ROOT_OP_NOTIFY_DOMAIN_CHANGE 4 91 + #define QCOMTEE_ROOT_OP_ADCI_ACCEPT 8 92 + #define QCOMTEE_ROOT_OP_ADCI_SHUTDOWN 9 93 + 94 + /* Subset of operations supported by client_env object. */ 95 + 96 + #define QCOMTEE_CLIENT_ENV_OPEN 0 97 + 98 + /* List of available QTEE service UIDs and subset of operations. */ 99 + 100 + #define QCOMTEE_FEATURE_VER_UID 2033 101 + #define QCOMTEE_FEATURE_VER_OP_GET 0 102 + /* Get QTEE version number. */ 103 + #define QCOMTEE_FEATURE_VER_OP_GET_QTEE_ID 10 104 + #define QTEE_VERSION_GET_MAJOR(x) (((x) >> 22) & 0xffU) 105 + #define QTEE_VERSION_GET_MINOR(x) (((x) >> 12) & 0xffU) 106 + #define QTEE_VERSION_GET_PATCH(x) ((x) >> 0 & 0xfffU) 107 + 108 + /* Response types as returned from qcomtee_object_invoke_ctx_invoke(). */ 109 + 110 + /* The message contains a callback request. */ 111 + #define QCOMTEE_RESULT_INBOUND_REQ_NEEDED 3 112 + 113 + /** 114 + * struct qcomtee_msg_object_invoke - Direct object invocation message. 115 + * @ctx: object ID hosted in QTEE. 116 + * @op: operation for the object. 117 + * @counts: number of different types of arguments in @args. 118 + * @args: array of arguments. 119 + * 120 + * @counts consists of 4 * 4-bit fields. Bits 0 - 3 represent the number of 121 + * input buffers, bits 4 - 7 represent the number of output buffers, 122 + * bits 8 - 11 represent the number of input objects, and bits 12 - 15 123 + * represent the number of output objects. The remaining bits should be zero. 124 + * 125 + * 15 12 11 8 7 4 3 0 126 + * +----------------+----------------+----------------+----------------+ 127 + * | #OO objects | #IO objects | #OB buffers | #IB buffers | 128 + * +----------------+----------------+----------------+----------------+ 129 + * 130 + * The maximum number of arguments of each type is defined by 131 + * %QCOMTEE_ARGS_PER_TYPE. 132 + */ 133 + struct qcomtee_msg_object_invoke { 134 + u32 cxt; 135 + u32 op; 136 + u32 counts; 137 + union qcomtee_msg_arg args[]; 138 + }; 139 + 140 + /* Bit masks for the four 4-bit nibbles holding the counts. */ 141 + #define QCOMTEE_MASK_IB GENMASK(3, 0) 142 + #define QCOMTEE_MASK_OB GENMASK(7, 4) 143 + #define QCOMTEE_MASK_IO GENMASK(11, 8) 144 + #define QCOMTEE_MASK_OO GENMASK(15, 12) 145 + 146 + /** 147 + * struct qcomtee_msg_callback - Callback request message. 148 + * @result: result of operation @op on the object referenced by @cxt. 149 + * @cxt: object ID hosted in the kernel. 150 + * @op: operation for the object. 151 + * @counts: number of different types of arguments in @args. 152 + * @args: array of arguments. 153 + * 154 + * For details of @counts, see &qcomtee_msg_object_invoke.counts. 155 + */ 156 + struct qcomtee_msg_callback { 157 + u32 result; 158 + u32 cxt; 159 + u32 op; 160 + u32 counts; 161 + union qcomtee_msg_arg args[]; 162 + }; 163 + 164 + /* Offset in the message for the beginning of the buffer argument's contents. */ 165 + #define qcomtee_msg_buffer_args(t, n) \ 166 + qcomtee_msg_offset_align(struct_size_t(t, args, n)) 167 + /* Pointer to the beginning of a buffer argument's content at an offset. */ 168 + #define qcomtee_msg_offset_to_ptr(m, off) ((void *)&((char *)(m))[(off)]) 169 + 170 + /* Some helpers to manage msg.counts. */ 171 + 172 + static inline unsigned int qcomtee_msg_num_ib(u32 counts) 173 + { 174 + return FIELD_GET(QCOMTEE_MASK_IB, counts); 175 + } 176 + 177 + static inline unsigned int qcomtee_msg_num_ob(u32 counts) 178 + { 179 + return FIELD_GET(QCOMTEE_MASK_OB, counts); 180 + } 181 + 182 + static inline unsigned int qcomtee_msg_num_io(u32 counts) 183 + { 184 + return FIELD_GET(QCOMTEE_MASK_IO, counts); 185 + } 186 + 187 + static inline unsigned int qcomtee_msg_num_oo(u32 counts) 188 + { 189 + return FIELD_GET(QCOMTEE_MASK_OO, counts); 190 + } 191 + 192 + static inline unsigned int qcomtee_msg_idx_ib(u32 counts) 193 + { 194 + return 0; 195 + } 196 + 197 + static inline unsigned int qcomtee_msg_idx_ob(u32 counts) 198 + { 199 + return qcomtee_msg_num_ib(counts); 200 + } 201 + 202 + static inline unsigned int qcomtee_msg_idx_io(u32 counts) 203 + { 204 + return qcomtee_msg_idx_ob(counts) + qcomtee_msg_num_ob(counts); 205 + } 206 + 207 + static inline unsigned int qcomtee_msg_idx_oo(u32 counts) 208 + { 209 + return qcomtee_msg_idx_io(counts) + qcomtee_msg_num_io(counts); 210 + } 211 + 212 + #define qcomtee_msg_for_each(i, first, num) \ 213 + for ((i) = (first); (i) < (first) + (num); (i)++) 214 + 215 + #define qcomtee_msg_for_each_input_buffer(i, m) \ 216 + qcomtee_msg_for_each(i, qcomtee_msg_idx_ib((m)->counts), \ 217 + qcomtee_msg_num_ib((m)->counts)) 218 + 219 + #define qcomtee_msg_for_each_output_buffer(i, m) \ 220 + qcomtee_msg_for_each(i, qcomtee_msg_idx_ob((m)->counts), \ 221 + qcomtee_msg_num_ob((m)->counts)) 222 + 223 + #define qcomtee_msg_for_each_input_object(i, m) \ 224 + qcomtee_msg_for_each(i, qcomtee_msg_idx_io((m)->counts), \ 225 + qcomtee_msg_num_io((m)->counts)) 226 + 227 + #define qcomtee_msg_for_each_output_object(i, m) \ 228 + qcomtee_msg_for_each(i, qcomtee_msg_idx_oo((m)->counts), \ 229 + qcomtee_msg_num_oo((m)->counts)) 230 + 231 + /* Sum of arguments in a message. */ 232 + #define qcomtee_msg_args(m) \ 233 + (qcomtee_msg_idx_oo((m)->counts) + qcomtee_msg_num_oo((m)->counts)) 234 + 235 + static inline void qcomtee_msg_init(struct qcomtee_msg_object_invoke *msg, 236 + u32 cxt, u32 op, int in_buffer, 237 + int out_buffer, int in_object, 238 + int out_object) 239 + { 240 + u32 counts = 0; 241 + 242 + counts |= (in_buffer & 0xfU); 243 + counts |= ((out_buffer - in_buffer) & 0xfU) << 4; 244 + counts |= ((in_object - out_buffer) & 0xfU) << 8; 245 + counts |= ((out_object - in_object) & 0xfU) << 12; 246 + 247 + msg->cxt = cxt; 248 + msg->op = op; 249 + msg->counts = counts; 250 + } 251 + 252 + /* Generic error codes. */ 253 + #define QCOMTEE_MSG_OK 0 /* non-specific success code. */ 254 + #define QCOMTEE_MSG_ERROR 1 /* non-specific error. */ 255 + #define QCOMTEE_MSG_ERROR_INVALID 2 /* unsupported/unrecognized request. */ 256 + #define QCOMTEE_MSG_ERROR_SIZE_IN 3 /* supplied buffer/string too large. */ 257 + #define QCOMTEE_MSG_ERROR_SIZE_OUT 4 /* supplied output buffer too small. */ 258 + #define QCOMTEE_MSG_ERROR_USERBASE 10 /* start of user-defined error range. */ 259 + 260 + /* Transport layer error codes. */ 261 + #define QCOMTEE_MSG_ERROR_DEFUNCT -90 /* object no longer exists. */ 262 + #define QCOMTEE_MSG_ERROR_ABORT -91 /* calling thread must exit. */ 263 + #define QCOMTEE_MSG_ERROR_BADOBJ -92 /* invalid object context. */ 264 + #define QCOMTEE_MSG_ERROR_NOSLOTS -93 /* caller's object table full. */ 265 + #define QCOMTEE_MSG_ERROR_MAXARGS -94 /* too many args. */ 266 + #define QCOMTEE_MSG_ERROR_MAXDATA -95 /* buffers too large. */ 267 + #define QCOMTEE_MSG_ERROR_UNAVAIL -96 /* the request could not be processed. */ 268 + #define QCOMTEE_MSG_ERROR_KMEM -97 /* kernel out of memory. */ 269 + #define QCOMTEE_MSG_ERROR_REMOTE -98 /* local method sent to remote object. */ 270 + #define QCOMTEE_MSG_ERROR_BUSY -99 /* Object is busy. */ 271 + #define QCOMTEE_MSG_ERROR_TIMEOUT -103 /* Call Back Object invocation timed out. */ 272 + 273 + static inline void qcomtee_msg_set_result(struct qcomtee_msg_callback *cb_msg, 274 + int err) 275 + { 276 + if (!err) { 277 + cb_msg->result = QCOMTEE_MSG_OK; 278 + } else if (err < 0) { 279 + /* If err < 0, then it is a transport error. */ 280 + switch (err) { 281 + case -ENOMEM: 282 + cb_msg->result = QCOMTEE_MSG_ERROR_KMEM; 283 + break; 284 + case -ENODEV: 285 + cb_msg->result = QCOMTEE_MSG_ERROR_DEFUNCT; 286 + break; 287 + case -ENOSPC: 288 + case -EBUSY: 289 + cb_msg->result = QCOMTEE_MSG_ERROR_BUSY; 290 + break; 291 + case -EBADF: 292 + case -EINVAL: 293 + cb_msg->result = QCOMTEE_MSG_ERROR_UNAVAIL; 294 + break; 295 + default: 296 + cb_msg->result = QCOMTEE_MSG_ERROR; 297 + } 298 + } else { 299 + /* If err > 0, then it is user defined error, pass it as is. */ 300 + cb_msg->result = err; 301 + } 302 + } 303 + 304 + #endif /* QCOMTEE_MSG_H */
+316
drivers/tee/qcomtee/qcomtee_object.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4 + */ 5 + 6 + #ifndef QCOMTEE_OBJECT_H 7 + #define QCOMTEE_OBJECT_H 8 + 9 + #include <linux/completion.h> 10 + #include <linux/kref.h> 11 + #include <linux/slab.h> 12 + #include <linux/workqueue.h> 13 + 14 + struct qcomtee_object; 15 + 16 + /** 17 + * DOC: Overview 18 + * 19 + * qcomtee_object provides object refcounting, ID allocation for objects hosted 20 + * in the kernel, and necessary message marshaling for Qualcomm TEE (QTEE). 21 + * 22 + * To invoke an object in QTEE, the user calls qcomtee_object_do_invoke() 23 + * while passing an instance of &struct qcomtee_object and the requested 24 + * operation + arguments. 25 + * 26 + * After boot, QTEE provides a static object %ROOT_QCOMTEE_OBJECT (type of 27 + * %QCOMTEE_OBJECT_TYPE_ROOT). The root object is invoked to pass the user's 28 + * credentials and obtain other instances of &struct qcomtee_object (type of 29 + * %QCOMTEE_OBJECT_TYPE_TEE) that represent services and TAs in QTEE; 30 + * see &enum qcomtee_object_type. 31 + * 32 + * The objects received from QTEE are refcounted. So the owner of these objects 33 + * can issue qcomtee_object_get() to increase the refcount and pass objects 34 + * to other clients, or issue qcomtee_object_put() to decrease the refcount 35 + * and release the resources in QTEE. 36 + * 37 + * The kernel can host services accessible to QTEE. A driver should embed 38 + * an instance of &struct qcomtee_object in the struct it wants to export to 39 + * QTEE (this is called a callback object). It issues qcomtee_object_user_init() 40 + * to set the dispatch() operation for the callback object and set its type 41 + * to %QCOMTEE_OBJECT_TYPE_CB. 42 + * 43 + * core.c holds an object table for callback objects. An object ID is assigned 44 + * to each callback object, which is an index to the object table. QTEE uses 45 + * these IDs to reference or invoke callback objects. 46 + * 47 + * If QTEE invokes a callback object in the kernel, the dispatch() operation is 48 + * called in the context of the thread that originally called 49 + * qcomtee_object_do_invoke(). 50 + */ 51 + 52 + /** 53 + * enum qcomtee_object_type - Object types. 54 + * @QCOMTEE_OBJECT_TYPE_TEE: object hosted on QTEE. 55 + * @QCOMTEE_OBJECT_TYPE_CB: object hosted on kernel. 56 + * @QCOMTEE_OBJECT_TYPE_ROOT: 'primordial' object. 57 + * @QCOMTEE_OBJECT_TYPE_NULL: NULL object. 58 + * 59 + * The primordial object is used for bootstrapping the IPC connection between 60 + * the kernel and QTEE. It is invoked by the kernel when it wants to get a 61 + * 'client env'. 62 + */ 63 + enum qcomtee_object_type { 64 + QCOMTEE_OBJECT_TYPE_TEE, 65 + QCOMTEE_OBJECT_TYPE_CB, 66 + QCOMTEE_OBJECT_TYPE_ROOT, 67 + QCOMTEE_OBJECT_TYPE_NULL, 68 + }; 69 + 70 + /** 71 + * enum qcomtee_arg_type - Type of QTEE argument. 72 + * @QCOMTEE_ARG_TYPE_INV: invalid type. 73 + * @QCOMTEE_ARG_TYPE_OB: output buffer (OB). 74 + * @QCOMTEE_ARG_TYPE_OO: output object (OO). 75 + * @QCOMTEE_ARG_TYPE_IB: input buffer (IB). 76 + * @QCOMTEE_ARG_TYPE_IO: input object (IO). 77 + * 78 + * Use the invalid type to specify the end of the argument array. 79 + */ 80 + enum qcomtee_arg_type { 81 + QCOMTEE_ARG_TYPE_INV = 0, 82 + QCOMTEE_ARG_TYPE_OB, 83 + QCOMTEE_ARG_TYPE_OO, 84 + QCOMTEE_ARG_TYPE_IB, 85 + QCOMTEE_ARG_TYPE_IO, 86 + QCOMTEE_ARG_TYPE_NR, 87 + }; 88 + 89 + /** 90 + * define QCOMTEE_ARGS_PER_TYPE - Maximum arguments of a specific type. 91 + * 92 + * The QTEE transport protocol limits the maximum number of arguments of 93 + * a specific type (i.e., IB, OB, IO, and OO). 94 + */ 95 + #define QCOMTEE_ARGS_PER_TYPE 16 96 + 97 + /* Maximum arguments that can fit in a QTEE message, ignoring the type. */ 98 + #define QCOMTEE_ARGS_MAX (QCOMTEE_ARGS_PER_TYPE * (QCOMTEE_ARG_TYPE_NR - 1)) 99 + 100 + struct qcomtee_buffer { 101 + union { 102 + void *addr; 103 + void __user *uaddr; 104 + }; 105 + size_t size; 106 + }; 107 + 108 + /** 109 + * struct qcomtee_arg - Argument for QTEE object invocation. 110 + * @type: type of argument as &enum qcomtee_arg_type. 111 + * @flags: extra flags. 112 + * @b: address and size if the type of argument is a buffer. 113 + * @o: object instance if the type of argument is an object. 114 + * 115 + * &qcomtee_arg.flags only accepts %QCOMTEE_ARG_FLAGS_UADDR for now, which 116 + * states that &qcomtee_arg.b contains a userspace address in uaddr. 117 + */ 118 + struct qcomtee_arg { 119 + enum qcomtee_arg_type type; 120 + /* 'b.uaddr' holds a __user address. */ 121 + #define QCOMTEE_ARG_FLAGS_UADDR BIT(0) 122 + unsigned int flags; 123 + union { 124 + struct qcomtee_buffer b; 125 + struct qcomtee_object *o; 126 + }; 127 + }; 128 + 129 + static inline int qcomtee_args_len(struct qcomtee_arg *args) 130 + { 131 + int i = 0; 132 + 133 + while (args[i].type != QCOMTEE_ARG_TYPE_INV) 134 + i++; 135 + return i; 136 + } 137 + 138 + /* Context is busy (callback is in progress). */ 139 + #define QCOMTEE_OIC_FLAG_BUSY BIT(1) 140 + /* Context needs to notify the current object. */ 141 + #define QCOMTEE_OIC_FLAG_NOTIFY BIT(2) 142 + /* Context has shared state with QTEE. */ 143 + #define QCOMTEE_OIC_FLAG_SHARED BIT(3) 144 + 145 + /** 146 + * struct qcomtee_object_invoke_ctx - QTEE context for object invocation. 147 + * @ctx: TEE context for this invocation. 148 + * @flags: flags for the invocation context. 149 + * @errno: error code for the invocation. 150 + * @object: current object invoked in this callback context. 151 + * @u: array of arguments for the current invocation (+1 for ending arg). 152 + * @in_msg: inbound buffer shared with QTEE. 153 + * @out_msg: outbound buffer shared with QTEE. 154 + * @in_shm: TEE shm allocated for inbound buffer. 155 + * @out_shm: TEE shm allocated for outbound buffer. 156 + * @data: extra data attached to this context. 157 + */ 158 + struct qcomtee_object_invoke_ctx { 159 + struct tee_context *ctx; 160 + unsigned long flags; 161 + int errno; 162 + 163 + struct qcomtee_object *object; 164 + struct qcomtee_arg u[QCOMTEE_ARGS_MAX + 1]; 165 + 166 + struct qcomtee_buffer in_msg; 167 + struct qcomtee_buffer out_msg; 168 + struct tee_shm *in_shm; 169 + struct tee_shm *out_shm; 170 + 171 + void *data; 172 + }; 173 + 174 + static inline struct qcomtee_object_invoke_ctx * 175 + qcomtee_object_invoke_ctx_alloc(struct tee_context *ctx) 176 + { 177 + struct qcomtee_object_invoke_ctx *oic; 178 + 179 + oic = kzalloc(sizeof(*oic), GFP_KERNEL); 180 + if (oic) 181 + oic->ctx = ctx; 182 + return oic; 183 + } 184 + 185 + /** 186 + * qcomtee_object_do_invoke() - Submit an invocation for an object. 187 + * @oic: context to use for the current invocation. 188 + * @object: object being invoked. 189 + * @op: requested operation on the object. 190 + * @u: array of arguments for the current invocation. 191 + * @result: result returned from QTEE. 192 + * 193 + * The caller is responsible for keeping track of the refcount for each object, 194 + * including @object. On return, the caller loses ownership of all input 195 + * objects of type %QCOMTEE_OBJECT_TYPE_CB. 196 + * 197 + * @object can be of %QCOMTEE_OBJECT_TYPE_ROOT or %QCOMTEE_OBJECT_TYPE_TEE. 198 + * 199 + * Return: On success, returns 0; on failure, returns < 0. 200 + */ 201 + int qcomtee_object_do_invoke(struct qcomtee_object_invoke_ctx *oic, 202 + struct qcomtee_object *object, u32 op, 203 + struct qcomtee_arg *u, int *result); 204 + 205 + /** 206 + * struct qcomtee_object_operations - Callback object operations. 207 + * @release: release the object if QTEE is not using it. 208 + * @dispatch: dispatch the operation requested by QTEE. 209 + * @notify: report the status of any pending response submitted by @dispatch. 210 + */ 211 + struct qcomtee_object_operations { 212 + void (*release)(struct qcomtee_object *object); 213 + int (*dispatch)(struct qcomtee_object_invoke_ctx *oic, 214 + struct qcomtee_object *object, u32 op, 215 + struct qcomtee_arg *args); 216 + void (*notify)(struct qcomtee_object_invoke_ctx *oic, 217 + struct qcomtee_object *object, int err); 218 + }; 219 + 220 + /** 221 + * struct qcomtee_object - QTEE or kernel object. 222 + * @name: object name. 223 + * @refcount: reference counter. 224 + * @object_type: object type as &enum qcomtee_object_type. 225 + * @info: extra information for the object. 226 + * @ops: callback operations for objects of type %QCOMTEE_OBJECT_TYPE_CB. 227 + * @work: work for async operations on the object. 228 + * 229 + * @work is used for releasing objects of %QCOMTEE_OBJECT_TYPE_TEE type. 230 + */ 231 + struct qcomtee_object { 232 + const char *name; 233 + struct kref refcount; 234 + 235 + enum qcomtee_object_type object_type; 236 + struct object_info { 237 + unsigned long qtee_id; 238 + /* TEE context for QTEE object async requests. */ 239 + struct tee_context *qcomtee_async_ctx; 240 + } info; 241 + 242 + struct qcomtee_object_operations *ops; 243 + struct work_struct work; 244 + }; 245 + 246 + /* Static instances of qcomtee_object objects. */ 247 + #define NULL_QCOMTEE_OBJECT ((struct qcomtee_object *)(0)) 248 + extern struct qcomtee_object qcomtee_object_root; 249 + #define ROOT_QCOMTEE_OBJECT (&qcomtee_object_root) 250 + 251 + static inline enum qcomtee_object_type 252 + typeof_qcomtee_object(struct qcomtee_object *object) 253 + { 254 + if (object == NULL_QCOMTEE_OBJECT) 255 + return QCOMTEE_OBJECT_TYPE_NULL; 256 + return object->object_type; 257 + } 258 + 259 + static inline const char *qcomtee_object_name(struct qcomtee_object *object) 260 + { 261 + if (object == NULL_QCOMTEE_OBJECT) 262 + return "null"; 263 + 264 + if (!object->name) 265 + return "no-name"; 266 + return object->name; 267 + } 268 + 269 + /** 270 + * qcomtee_object_user_init() - Initialize an object for the user. 271 + * @object: object to initialize. 272 + * @ot: type of object as &enum qcomtee_object_type. 273 + * @ops: instance of callbacks. 274 + * @fmt: name assigned to the object. 275 + * 276 + * Return: On success, returns 0; on failure, returns < 0. 277 + */ 278 + int qcomtee_object_user_init(struct qcomtee_object *object, 279 + enum qcomtee_object_type ot, 280 + struct qcomtee_object_operations *ops, 281 + const char *fmt, ...) __printf(4, 5); 282 + 283 + /* Object release is RCU protected. */ 284 + int qcomtee_object_get(struct qcomtee_object *object); 285 + void qcomtee_object_put(struct qcomtee_object *object); 286 + 287 + #define qcomtee_arg_for_each(i, args) \ 288 + for (i = 0; args[i].type != QCOMTEE_ARG_TYPE_INV; i++) 289 + 290 + /* Next argument of type @type after index @i. */ 291 + int qcomtee_next_arg_type(struct qcomtee_arg *u, int i, 292 + enum qcomtee_arg_type type); 293 + 294 + /* Iterate over argument of given type. */ 295 + #define qcomtee_arg_for_each_type(i, args, at) \ 296 + for (i = qcomtee_next_arg_type(args, 0, at); \ 297 + args[i].type != QCOMTEE_ARG_TYPE_INV; \ 298 + i = qcomtee_next_arg_type(args, i + 1, at)) 299 + 300 + #define qcomtee_arg_for_each_input_buffer(i, args) \ 301 + qcomtee_arg_for_each_type(i, args, QCOMTEE_ARG_TYPE_IB) 302 + #define qcomtee_arg_for_each_output_buffer(i, args) \ 303 + qcomtee_arg_for_each_type(i, args, QCOMTEE_ARG_TYPE_OB) 304 + #define qcomtee_arg_for_each_input_object(i, args) \ 305 + qcomtee_arg_for_each_type(i, args, QCOMTEE_ARG_TYPE_IO) 306 + #define qcomtee_arg_for_each_output_object(i, args) \ 307 + qcomtee_arg_for_each_type(i, args, QCOMTEE_ARG_TYPE_OO) 308 + 309 + struct qcomtee_object * 310 + qcomtee_object_get_client_env(struct qcomtee_object_invoke_ctx *oic); 311 + 312 + struct qcomtee_object * 313 + qcomtee_object_get_service(struct qcomtee_object_invoke_ctx *oic, 314 + struct qcomtee_object *client_env, u32 uid); 315 + 316 + #endif /* QCOMTEE_OBJECT_H */
+153
drivers/tee/qcomtee/shm.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4 + */ 5 + 6 + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 7 + 8 + #include <linux/firmware/qcom/qcom_tzmem.h> 9 + #include <linux/mm.h> 10 + 11 + #include "qcomtee.h" 12 + 13 + /** 14 + * define MAX_OUTBOUND_BUFFER_SIZE - Maximum size of outbound buffers. 15 + * 16 + * The size of outbound buffer depends on QTEE callback requests. 17 + */ 18 + #define MAX_OUTBOUND_BUFFER_SIZE SZ_4K 19 + 20 + /** 21 + * define MAX_INBOUND_BUFFER_SIZE - Maximum size of the inbound buffer. 22 + * 23 + * The size of the inbound buffer depends on the user's requests, 24 + * specifically the number of IB and OB arguments. If an invocation 25 + * requires a size larger than %MAX_INBOUND_BUFFER_SIZE, the user should 26 + * consider using another form of shared memory with QTEE. 27 + */ 28 + #define MAX_INBOUND_BUFFER_SIZE SZ_4M 29 + 30 + /** 31 + * qcomtee_msg_buffers_alloc() - Allocate inbound and outbound buffers. 32 + * @oic: context to use for the current invocation. 33 + * @u: array of arguments for the current invocation. 34 + * 35 + * It calculates the size of inbound and outbound buffers based on the 36 + * arguments in @u. It allocates the buffers from the teedev pool. 37 + * 38 + * Return: On success, returns 0. On error, returns < 0. 39 + */ 40 + int qcomtee_msg_buffers_alloc(struct qcomtee_object_invoke_ctx *oic, 41 + struct qcomtee_arg *u) 42 + { 43 + struct tee_context *ctx = oic->ctx; 44 + struct tee_shm *shm; 45 + size_t size; 46 + int i; 47 + 48 + /* Start offset in a message for buffer arguments. */ 49 + size = qcomtee_msg_buffer_args(struct qcomtee_msg_object_invoke, 50 + qcomtee_args_len(u)); 51 + if (size > MAX_INBOUND_BUFFER_SIZE) 52 + return -EINVAL; 53 + 54 + /* Add size of IB arguments. */ 55 + qcomtee_arg_for_each_input_buffer(i, u) { 56 + size = size_add(size, qcomtee_msg_offset_align(u[i].b.size)); 57 + if (size > MAX_INBOUND_BUFFER_SIZE) 58 + return -EINVAL; 59 + } 60 + 61 + /* Add size of OB arguments. */ 62 + qcomtee_arg_for_each_output_buffer(i, u) { 63 + size = size_add(size, qcomtee_msg_offset_align(u[i].b.size)); 64 + if (size > MAX_INBOUND_BUFFER_SIZE) 65 + return -EINVAL; 66 + } 67 + 68 + shm = tee_shm_alloc_priv_buf(ctx, size); 69 + if (IS_ERR(shm)) 70 + return PTR_ERR(shm); 71 + 72 + /* Allocate inbound buffer. */ 73 + oic->in_shm = shm; 74 + shm = tee_shm_alloc_priv_buf(ctx, MAX_OUTBOUND_BUFFER_SIZE); 75 + if (IS_ERR(shm)) { 76 + tee_shm_free(oic->in_shm); 77 + 78 + return PTR_ERR(shm); 79 + } 80 + /* Allocate outbound buffer. */ 81 + oic->out_shm = shm; 82 + 83 + oic->in_msg.addr = tee_shm_get_va(oic->in_shm, 0); 84 + oic->in_msg.size = tee_shm_get_size(oic->in_shm); 85 + oic->out_msg.addr = tee_shm_get_va(oic->out_shm, 0); 86 + oic->out_msg.size = tee_shm_get_size(oic->out_shm); 87 + /* QTEE assume unused buffers are zeroed. */ 88 + memzero_explicit(oic->in_msg.addr, oic->in_msg.size); 89 + memzero_explicit(oic->out_msg.addr, oic->out_msg.size); 90 + 91 + return 0; 92 + } 93 + 94 + void qcomtee_msg_buffers_free(struct qcomtee_object_invoke_ctx *oic) 95 + { 96 + tee_shm_free(oic->in_shm); 97 + tee_shm_free(oic->out_shm); 98 + } 99 + 100 + /* Dynamic shared memory pool based on tee_dyn_shm_alloc_helper(). */ 101 + 102 + static int qcomtee_shm_register(struct tee_context *ctx, struct tee_shm *shm, 103 + struct page **pages, size_t num_pages, 104 + unsigned long start) 105 + { 106 + return qcom_tzmem_shm_bridge_create(shm->paddr, shm->size, 107 + &shm->sec_world_id); 108 + } 109 + 110 + static int qcomtee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm) 111 + { 112 + qcom_tzmem_shm_bridge_delete(shm->sec_world_id); 113 + 114 + return 0; 115 + } 116 + 117 + static int pool_op_alloc(struct tee_shm_pool *pool, struct tee_shm *shm, 118 + size_t size, size_t align) 119 + { 120 + if (!(shm->flags & TEE_SHM_PRIV)) 121 + return -ENOMEM; 122 + 123 + return tee_dyn_shm_alloc_helper(shm, size, align, qcomtee_shm_register); 124 + } 125 + 126 + static void pool_op_free(struct tee_shm_pool *pool, struct tee_shm *shm) 127 + { 128 + tee_dyn_shm_free_helper(shm, qcomtee_shm_unregister); 129 + } 130 + 131 + static void pool_op_destroy_pool(struct tee_shm_pool *pool) 132 + { 133 + kfree(pool); 134 + } 135 + 136 + static const struct tee_shm_pool_ops pool_ops = { 137 + .alloc = pool_op_alloc, 138 + .free = pool_op_free, 139 + .destroy_pool = pool_op_destroy_pool, 140 + }; 141 + 142 + struct tee_shm_pool *qcomtee_shm_pool_alloc(void) 143 + { 144 + struct tee_shm_pool *pool; 145 + 146 + pool = kzalloc(sizeof(*pool), GFP_KERNEL); 147 + if (!pool) 148 + return ERR_PTR(-ENOMEM); 149 + 150 + pool->ops = &pool_ops; 151 + 152 + return pool; 153 + }
+692
drivers/tee/qcomtee/user_obj.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4 + */ 5 + 6 + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 7 + 8 + #include <linux/slab.h> 9 + #include <linux/uaccess.h> 10 + 11 + #include "qcomtee.h" 12 + 13 + /** 14 + * DOC: User Objects aka Supplicants 15 + * 16 + * Any userspace process with access to the TEE device file can behave as a 17 + * supplicant by creating a user object. Any TEE parameter of type OBJREF with 18 + * %QCOMTEE_OBJREF_FLAG_USER flag set is considered a user object. 19 + * 20 + * A supplicant uses qcomtee_user_object_select() (i.e. TEE_IOC_SUPPL_RECV) to 21 + * receive a QTEE user object request and qcomtee_user_object_submit() 22 + * (i.e. TEE_IOC_SUPPL_SEND) to submit a response. QTEE expects to receive the 23 + * response, including OB and OO in a specific order in the message; parameters 24 + * submitted with qcomtee_user_object_submit() should maintain this order. 25 + */ 26 + 27 + /** 28 + * struct qcomtee_user_object - User object. 29 + * @object: &struct qcomtee_object representing the user object. 30 + * @ctx: context for which the user object is defined. 31 + * @object_id: object ID in @ctx. 32 + * @notify: notify on release. 33 + * 34 + * Any object managed in userspace is represented by this struct. 35 + * If @notify is set, a notification message is sent back to userspace 36 + * upon release. 37 + */ 38 + struct qcomtee_user_object { 39 + struct qcomtee_object object; 40 + struct tee_context *ctx; 41 + u64 object_id; 42 + bool notify; 43 + }; 44 + 45 + #define to_qcomtee_user_object(o) \ 46 + container_of((o), struct qcomtee_user_object, object) 47 + 48 + static struct qcomtee_object_operations qcomtee_user_object_ops; 49 + 50 + /* Is it a user object? */ 51 + int is_qcomtee_user_object(struct qcomtee_object *object) 52 + { 53 + return object != NULL_QCOMTEE_OBJECT && 54 + typeof_qcomtee_object(object) == QCOMTEE_OBJECT_TYPE_CB && 55 + object->ops == &qcomtee_user_object_ops; 56 + } 57 + 58 + /* Set the user object's 'notify on release' flag. */ 59 + void qcomtee_user_object_set_notify(struct qcomtee_object *object, bool notify) 60 + { 61 + if (is_qcomtee_user_object(object)) 62 + to_qcomtee_user_object(object)->notify = notify; 63 + } 64 + 65 + /* Supplicant Requests: */ 66 + 67 + /** 68 + * enum qcomtee_req_state - Current state of request. 69 + * @QCOMTEE_REQ_QUEUED: Request is waiting for supplicant. 70 + * @QCOMTEE_REQ_PROCESSING: Request has been picked by the supplicant. 71 + * @QCOMTEE_REQ_PROCESSED: Response has been submitted for the request. 72 + */ 73 + enum qcomtee_req_state { 74 + QCOMTEE_REQ_QUEUED = 1, 75 + QCOMTEE_REQ_PROCESSING, 76 + QCOMTEE_REQ_PROCESSED, 77 + }; 78 + 79 + /* User requests sent to supplicants. */ 80 + struct qcomtee_ureq { 81 + enum qcomtee_req_state state; 82 + 83 + /* User Request: */ 84 + int req_id; 85 + u64 object_id; 86 + u32 op; 87 + struct qcomtee_arg *args; 88 + int errno; 89 + 90 + struct list_head node; 91 + struct completion c; /* Completion for whoever wait. */ 92 + }; 93 + 94 + /* 95 + * Placeholder for a PROCESSING request in qcomtee_context.reqs_idr. 96 + * 97 + * If the thread that calls qcomtee_object_invoke() dies and the supplicant 98 + * is processing the request, replace the entry in qcomtee_context.reqs_idr 99 + * with empty_ureq. This ensures that (1) the req_id remains busy and is not 100 + * reused, and (2) the supplicant fails to submit the response and performs 101 + * the necessary rollback. 102 + */ 103 + static struct qcomtee_ureq empty_ureq = { .state = QCOMTEE_REQ_PROCESSING }; 104 + 105 + /* Enqueue a user request for a context and assign a request ID. */ 106 + static int ureq_enqueue(struct qcomtee_context_data *ctxdata, 107 + struct qcomtee_ureq *ureq) 108 + { 109 + int ret; 110 + 111 + guard(mutex)(&ctxdata->reqs_lock); 112 + /* Supplicant is dying. */ 113 + if (ctxdata->released) 114 + return -ENODEV; 115 + 116 + /* Allocate an ID and queue the request. */ 117 + ret = idr_alloc(&ctxdata->reqs_idr, ureq, 0, 0, GFP_KERNEL); 118 + if (ret < 0) 119 + return ret; 120 + 121 + ureq->req_id = ret; 122 + ureq->state = QCOMTEE_REQ_QUEUED; 123 + list_add_tail(&ureq->node, &ctxdata->reqs_list); 124 + 125 + return 0; 126 + } 127 + 128 + /** 129 + * ureq_dequeue() - Dequeue a user request from a context. 130 + * @ctxdata: context data for a context to dequeue the request. 131 + * @req_id: ID of the request to be dequeued. 132 + * 133 + * It dequeues a user request and releases its request ID. 134 + * 135 + * Context: The caller should hold &qcomtee_context_data->reqs_lock. 136 + * Return: Returns the user request associated with this ID; otherwise, NULL. 137 + */ 138 + static struct qcomtee_ureq *ureq_dequeue(struct qcomtee_context_data *ctxdata, 139 + int req_id) 140 + { 141 + struct qcomtee_ureq *ureq; 142 + 143 + ureq = idr_remove(&ctxdata->reqs_idr, req_id); 144 + if (ureq == &empty_ureq || !ureq) 145 + return NULL; 146 + 147 + list_del(&ureq->node); 148 + 149 + return ureq; 150 + } 151 + 152 + /** 153 + * ureq_select() - Select the next request in a context. 154 + * @ctxdata: context data for a context to pop a request. 155 + * @ubuf_size: size of the available buffer for UBUF parameters. 156 + * @num_params: number of entries for the TEE parameter array. 157 + * 158 + * It checks if @num_params is large enough to fit the next request arguments. 159 + * It checks if @ubuf_size is large enough to fit IB buffer arguments. 160 + * 161 + * Context: The caller should hold &qcomtee_context_data->reqs_lock. 162 + * Return: On success, returns a request; 163 + * on failure, returns NULL and ERR_PTR. 164 + */ 165 + static struct qcomtee_ureq *ureq_select(struct qcomtee_context_data *ctxdata, 166 + size_t ubuf_size, int num_params) 167 + { 168 + struct qcomtee_ureq *req, *ureq = NULL; 169 + struct qcomtee_arg *u; 170 + int i; 171 + 172 + /* Find the a queued request. */ 173 + list_for_each_entry(req, &ctxdata->reqs_list, node) { 174 + if (req->state == QCOMTEE_REQ_QUEUED) { 175 + ureq = req; 176 + break; 177 + } 178 + } 179 + 180 + if (!ureq) 181 + return NULL; 182 + 183 + u = ureq->args; 184 + /* (1) Is there enough TEE parameters? */ 185 + if (num_params < qcomtee_args_len(u)) 186 + return ERR_PTR(-EINVAL); 187 + /* (2) Is there enough space to pass input buffers? */ 188 + qcomtee_arg_for_each_input_buffer(i, u) { 189 + ubuf_size = size_sub(ubuf_size, u[i].b.size); 190 + if (ubuf_size == SIZE_MAX) 191 + return ERR_PTR(-EINVAL); 192 + 193 + ubuf_size = round_down(ubuf_size, 8); 194 + } 195 + 196 + return ureq; 197 + } 198 + 199 + /* Gets called when the user closes the device. */ 200 + void qcomtee_requests_destroy(struct qcomtee_context_data *ctxdata) 201 + { 202 + struct qcomtee_ureq *req, *ureq; 203 + 204 + guard(mutex)(&ctxdata->reqs_lock); 205 + /* So ureq_enqueue() refuses new requests from QTEE. */ 206 + ctxdata->released = true; 207 + /* ureqs in reqs_list are in QUEUED or PROCESSING (!= empty_ureq) state. */ 208 + list_for_each_entry_safe(ureq, req, &ctxdata->reqs_list, node) { 209 + ureq_dequeue(ctxdata, ureq->req_id); 210 + 211 + if (ureq->op != QCOMTEE_MSG_OBJECT_OP_RELEASE) { 212 + ureq->state = QCOMTEE_REQ_PROCESSED; 213 + ureq->errno = -ENODEV; 214 + 215 + complete(&ureq->c); 216 + } else { 217 + kfree(ureq); 218 + } 219 + } 220 + } 221 + 222 + /* User Object API. */ 223 + 224 + /* User object dispatcher. */ 225 + static int qcomtee_user_object_dispatch(struct qcomtee_object_invoke_ctx *oic, 226 + struct qcomtee_object *object, u32 op, 227 + struct qcomtee_arg *args) 228 + { 229 + struct qcomtee_user_object *uo = to_qcomtee_user_object(object); 230 + struct qcomtee_context_data *ctxdata = uo->ctx->data; 231 + struct qcomtee_ureq *ureq __free(kfree) = NULL; 232 + int errno; 233 + 234 + ureq = kzalloc(sizeof(*ureq), GFP_KERNEL); 235 + if (!ureq) 236 + return -ENOMEM; 237 + 238 + init_completion(&ureq->c); 239 + ureq->object_id = uo->object_id; 240 + ureq->op = op; 241 + ureq->args = args; 242 + 243 + /* Queue the request. */ 244 + if (ureq_enqueue(ctxdata, ureq)) 245 + return -ENODEV; 246 + /* Wakeup supplicant to process it. */ 247 + complete(&ctxdata->req_c); 248 + 249 + /* 250 + * Wait for the supplicant to process the request. Wait as KILLABLE 251 + * in case the supplicant and invoke thread are both running from the 252 + * same process, the supplicant crashes, or the shutdown sequence 253 + * starts with supplicant dies first; otherwise, it stuck indefinitely. 254 + * 255 + * If the supplicant processes long-running requests, also use 256 + * TASK_FREEZABLE to allow the device to safely suspend if needed. 257 + */ 258 + if (!wait_for_completion_state(&ureq->c, 259 + TASK_KILLABLE | TASK_FREEZABLE)) { 260 + errno = ureq->errno; 261 + if (!errno) 262 + oic->data = no_free_ptr(ureq); 263 + } else { 264 + enum qcomtee_req_state prev_state; 265 + 266 + errno = -ENODEV; 267 + 268 + scoped_guard(mutex, &ctxdata->reqs_lock) { 269 + prev_state = ureq->state; 270 + /* Replace with empty_ureq to keep req_id reserved. */ 271 + if (prev_state == QCOMTEE_REQ_PROCESSING) { 272 + list_del(&ureq->node); 273 + idr_replace(&ctxdata->reqs_idr, 274 + &empty_ureq, ureq->req_id); 275 + 276 + /* Remove as supplicant has never seen this request. */ 277 + } else if (prev_state == QCOMTEE_REQ_QUEUED) { 278 + ureq_dequeue(ctxdata, ureq->req_id); 279 + } 280 + } 281 + 282 + /* Supplicant did some work, do not discard it. */ 283 + if (prev_state == QCOMTEE_REQ_PROCESSED) { 284 + errno = ureq->errno; 285 + if (!errno) 286 + oic->data = no_free_ptr(ureq); 287 + } 288 + } 289 + 290 + return errno; 291 + } 292 + 293 + /* Gets called after submitting the dispatcher response. */ 294 + static void qcomtee_user_object_notify(struct qcomtee_object_invoke_ctx *oic, 295 + struct qcomtee_object *unused_object, 296 + int err) 297 + { 298 + struct qcomtee_ureq *ureq = oic->data; 299 + struct qcomtee_arg *u = ureq->args; 300 + int i; 301 + 302 + /* 303 + * If err, there was a transport issue, and QTEE did not receive the 304 + * response for the dispatcher. Release the callback object created for 305 + * QTEE, in addition to the copies of objects kept for the drivers. 306 + */ 307 + qcomtee_arg_for_each_output_object(i, u) { 308 + if (err && 309 + (typeof_qcomtee_object(u[i].o) == QCOMTEE_OBJECT_TYPE_CB)) 310 + qcomtee_object_put(u[i].o); 311 + qcomtee_object_put(u[i].o); 312 + } 313 + 314 + kfree(ureq); 315 + } 316 + 317 + static void qcomtee_user_object_release(struct qcomtee_object *object) 318 + { 319 + struct qcomtee_user_object *uo = to_qcomtee_user_object(object); 320 + struct qcomtee_context_data *ctxdata = uo->ctx->data; 321 + struct qcomtee_ureq *ureq; 322 + 323 + /* RELEASE does not require any argument. */ 324 + static struct qcomtee_arg args[] = { { .type = QCOMTEE_ARG_TYPE_INV } }; 325 + 326 + if (!uo->notify) 327 + goto out_no_notify; 328 + 329 + ureq = kzalloc(sizeof(*ureq), GFP_KERNEL); 330 + if (!ureq) 331 + goto out_no_notify; 332 + 333 + /* QUEUE a release request: */ 334 + ureq->object_id = uo->object_id; 335 + ureq->op = QCOMTEE_MSG_OBJECT_OP_RELEASE; 336 + ureq->args = args; 337 + if (ureq_enqueue(ctxdata, ureq)) { 338 + kfree(ureq); 339 + /* Ignore the notification if it cannot be queued. */ 340 + goto out_no_notify; 341 + } 342 + 343 + complete(&ctxdata->req_c); 344 + 345 + out_no_notify: 346 + teedev_ctx_put(uo->ctx); 347 + kfree(uo); 348 + } 349 + 350 + static struct qcomtee_object_operations qcomtee_user_object_ops = { 351 + .release = qcomtee_user_object_release, 352 + .notify = qcomtee_user_object_notify, 353 + .dispatch = qcomtee_user_object_dispatch, 354 + }; 355 + 356 + /** 357 + * qcomtee_user_param_to_object() - OBJREF parameter to &struct qcomtee_object. 358 + * @object: object returned. 359 + * @param: TEE parameter. 360 + * @ctx: context in which the conversion should happen. 361 + * 362 + * @param is an OBJREF with %QCOMTEE_OBJREF_FLAG_USER flags. 363 + * 364 + * Return: On success, returns 0; on failure, returns < 0. 365 + */ 366 + int qcomtee_user_param_to_object(struct qcomtee_object **object, 367 + struct tee_param *param, 368 + struct tee_context *ctx) 369 + { 370 + struct qcomtee_user_object *user_object __free(kfree) = NULL; 371 + int err; 372 + 373 + user_object = kzalloc(sizeof(*user_object), GFP_KERNEL); 374 + if (!user_object) 375 + return -ENOMEM; 376 + 377 + user_object->ctx = ctx; 378 + user_object->object_id = param->u.objref.id; 379 + /* By default, always notify userspace upon release. */ 380 + user_object->notify = true; 381 + err = qcomtee_object_user_init(&user_object->object, 382 + QCOMTEE_OBJECT_TYPE_CB, 383 + &qcomtee_user_object_ops, "uo-%llu", 384 + param->u.objref.id); 385 + if (err) 386 + return err; 387 + /* Matching teedev_ctx_put() is in qcomtee_user_object_release(). */ 388 + teedev_ctx_get(ctx); 389 + 390 + *object = &no_free_ptr(user_object)->object; 391 + 392 + return 0; 393 + } 394 + 395 + /* Reverse what qcomtee_user_param_to_object() does. */ 396 + int qcomtee_user_param_from_object(struct tee_param *param, 397 + struct qcomtee_object *object, 398 + struct tee_context *ctx) 399 + { 400 + struct qcomtee_user_object *uo; 401 + 402 + uo = to_qcomtee_user_object(object); 403 + /* Ensure the object is in the same context as the caller. */ 404 + if (uo->ctx != ctx) 405 + return -EINVAL; 406 + 407 + param->u.objref.id = uo->object_id; 408 + param->u.objref.flags = QCOMTEE_OBJREF_FLAG_USER; 409 + 410 + /* User objects are valid in userspace; do not keep a copy. */ 411 + qcomtee_object_put(object); 412 + 413 + return 0; 414 + } 415 + 416 + /** 417 + * qcomtee_cb_params_from_args() - Convert QTEE arguments to TEE parameters. 418 + * @params: TEE parameters. 419 + * @u: QTEE arguments. 420 + * @num_params: number of elements in the parameter array. 421 + * @ubuf_addr: user buffer for arguments of type %QCOMTEE_ARG_TYPE_IB. 422 + * @ubuf_size: size of the user buffer. 423 + * @ctx: context in which the conversion should happen. 424 + * 425 + * It expects @params to have enough entries for @u. Entries in @params are of 426 + * %TEE_IOCTL_PARAM_ATTR_TYPE_NONE. 427 + * 428 + * Return: On success, returns the number of input parameters; 429 + * on failure, returns < 0. 430 + */ 431 + static int qcomtee_cb_params_from_args(struct tee_param *params, 432 + struct qcomtee_arg *u, int num_params, 433 + void __user *ubuf_addr, size_t ubuf_size, 434 + struct tee_context *ctx) 435 + { 436 + int i, np; 437 + void __user *uaddr; 438 + 439 + qcomtee_arg_for_each(i, u) { 440 + switch (u[i].type) { 441 + case QCOMTEE_ARG_TYPE_IB: 442 + params[i].attr = TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INPUT; 443 + 444 + /* Underflow already checked in ureq_select(). */ 445 + ubuf_size = round_down(ubuf_size - u[i].b.size, 8); 446 + uaddr = (void __user *)(ubuf_addr + ubuf_size); 447 + 448 + params[i].u.ubuf.uaddr = uaddr; 449 + params[i].u.ubuf.size = u[i].b.size; 450 + if (copy_to_user(params[i].u.ubuf.uaddr, u[i].b.addr, 451 + u[i].b.size)) 452 + goto out_failed; 453 + 454 + break; 455 + case QCOMTEE_ARG_TYPE_OB: 456 + params[i].attr = TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_OUTPUT; 457 + /* Let the user knows the maximum size QTEE expects. */ 458 + params[i].u.ubuf.size = u[i].b.size; 459 + 460 + break; 461 + case QCOMTEE_ARG_TYPE_IO: 462 + params[i].attr = TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INPUT; 463 + if (qcomtee_objref_from_arg(&params[i], &u[i], ctx)) 464 + goto out_failed; 465 + 466 + break; 467 + case QCOMTEE_ARG_TYPE_OO: 468 + params[i].attr = 469 + TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_OUTPUT; 470 + 471 + break; 472 + default: /* Never get here! */ 473 + goto out_failed; 474 + } 475 + } 476 + 477 + return i; 478 + 479 + out_failed: 480 + /* Undo qcomtee_objref_from_arg(). */ 481 + for (np = i; np >= 0; np--) { 482 + if (params[np].attr == TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INPUT) 483 + qcomtee_context_del_qtee_object(&params[np], ctx); 484 + } 485 + 486 + /* Release any IO objects not processed. */ 487 + for (; u[i].type; i++) { 488 + if (u[i].type == QCOMTEE_ARG_TYPE_IO) 489 + qcomtee_object_put(u[i].o); 490 + } 491 + 492 + return -EINVAL; 493 + } 494 + 495 + /** 496 + * qcomtee_cb_params_to_args() - Convert TEE parameters to QTEE arguments. 497 + * @u: QTEE arguments. 498 + * @params: TEE parameters. 499 + * @num_params: number of elements in the parameter array. 500 + * @ctx: context in which the conversion should happen. 501 + * 502 + * Return: On success, returns 0; on failure, returns < 0. 503 + */ 504 + static int qcomtee_cb_params_to_args(struct qcomtee_arg *u, 505 + struct tee_param *params, int num_params, 506 + struct tee_context *ctx) 507 + { 508 + int i; 509 + 510 + qcomtee_arg_for_each(i, u) { 511 + switch (u[i].type) { 512 + case QCOMTEE_ARG_TYPE_IB: 513 + if (params[i].attr != 514 + TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INPUT) 515 + goto out_failed; 516 + 517 + break; 518 + case QCOMTEE_ARG_TYPE_OB: 519 + if (params[i].attr != 520 + TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_OUTPUT) 521 + goto out_failed; 522 + 523 + /* Client can not send more data than requested. */ 524 + if (params[i].u.ubuf.size > u[i].b.size) 525 + goto out_failed; 526 + 527 + if (copy_from_user(u[i].b.addr, params[i].u.ubuf.uaddr, 528 + params[i].u.ubuf.size)) 529 + goto out_failed; 530 + 531 + u[i].b.size = params[i].u.ubuf.size; 532 + 533 + break; 534 + case QCOMTEE_ARG_TYPE_IO: 535 + if (params[i].attr != 536 + TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INPUT) 537 + goto out_failed; 538 + 539 + break; 540 + case QCOMTEE_ARG_TYPE_OO: 541 + if (params[i].attr != 542 + TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_OUTPUT) 543 + goto out_failed; 544 + 545 + if (qcomtee_objref_to_arg(&u[i], &params[i], ctx)) 546 + goto out_failed; 547 + 548 + break; 549 + default: /* Never get here! */ 550 + goto out_failed; 551 + } 552 + } 553 + 554 + return 0; 555 + 556 + out_failed: 557 + /* Undo qcomtee_objref_to_arg(). */ 558 + for (i--; i >= 0; i--) { 559 + if (u[i].type != QCOMTEE_ARG_TYPE_OO) 560 + continue; 561 + 562 + qcomtee_user_object_set_notify(u[i].o, false); 563 + if (typeof_qcomtee_object(u[i].o) == QCOMTEE_OBJECT_TYPE_CB) 564 + qcomtee_object_put(u[i].o); 565 + 566 + qcomtee_object_put(u[i].o); 567 + } 568 + 569 + return -EINVAL; 570 + } 571 + 572 + /** 573 + * qcomtee_user_object_select() - Select a request for a user object. 574 + * @ctx: context to look for a user object. 575 + * @params: parameters for @op. 576 + * @num_params: number of elements in the parameter array. 577 + * @uaddr: user buffer for output UBUF parameters. 578 + * @size: size of user buffer @uaddr. 579 + * @data: information for the selected request. 580 + * 581 + * @params is filled along with @data for the selected request. 582 + * 583 + * Return: On success, returns 0; on failure, returns < 0. 584 + */ 585 + int qcomtee_user_object_select(struct tee_context *ctx, 586 + struct tee_param *params, int num_params, 587 + void __user *uaddr, size_t size, 588 + struct qcomtee_user_object_request_data *data) 589 + { 590 + struct qcomtee_context_data *ctxdata = ctx->data; 591 + struct qcomtee_ureq *ureq; 592 + int ret; 593 + 594 + /* 595 + * Hold the reqs_lock not only for ureq_select() and updating the ureq 596 + * state to PROCESSING but for the entire duration of ureq access. 597 + * This prevents qcomtee_user_object_dispatch() from freeing 598 + * ureq while it is still in use, if client dies. 599 + */ 600 + 601 + while (1) { 602 + scoped_guard(mutex, &ctxdata->reqs_lock) { 603 + ureq = ureq_select(ctxdata, size, num_params); 604 + if (!ureq) 605 + goto wait_for_request; 606 + 607 + if (IS_ERR(ureq)) 608 + return PTR_ERR(ureq); 609 + 610 + /* Processing the request 'QUEUED -> PROCESSING'. */ 611 + ureq->state = QCOMTEE_REQ_PROCESSING; 612 + /* ''Prepare user request:'' */ 613 + data->id = ureq->req_id; 614 + data->object_id = ureq->object_id; 615 + data->op = ureq->op; 616 + ret = qcomtee_cb_params_from_args(params, ureq->args, 617 + num_params, uaddr, 618 + size, ctx); 619 + if (ret >= 0) 620 + goto done_request; 621 + 622 + /* Something is wrong with the request: */ 623 + ureq_dequeue(ctxdata, data->id); 624 + /* Send error to QTEE. */ 625 + ureq->state = QCOMTEE_REQ_PROCESSED; 626 + ureq->errno = ret; 627 + 628 + complete(&ureq->c); 629 + } 630 + 631 + continue; 632 + wait_for_request: 633 + /* Wait for a new QUEUED request. */ 634 + if (wait_for_completion_interruptible(&ctxdata->req_c)) 635 + return -ERESTARTSYS; 636 + } 637 + 638 + done_request: 639 + /* No one is waiting for the response. */ 640 + if (data->op == QCOMTEE_MSG_OBJECT_OP_RELEASE) { 641 + scoped_guard(mutex, &ctxdata->reqs_lock) 642 + ureq_dequeue(ctxdata, data->id); 643 + kfree(ureq); 644 + } 645 + 646 + data->np = ret; 647 + 648 + return 0; 649 + } 650 + 651 + /** 652 + * qcomtee_user_object_submit() - Submit a response for a user object. 653 + * @ctx: context to look for a user object. 654 + * @params: returned parameters. 655 + * @num_params: number of elements in the parameter array. 656 + * @req_id: request ID for the response. 657 + * @errno: result of user object invocation. 658 + * 659 + * Return: On success, returns 0; on failure, returns < 0. 660 + */ 661 + int qcomtee_user_object_submit(struct tee_context *ctx, 662 + struct tee_param *params, int num_params, 663 + int req_id, int errno) 664 + { 665 + struct qcomtee_context_data *ctxdata = ctx->data; 666 + struct qcomtee_ureq *ureq; 667 + 668 + /* See comments for reqs_lock in qcomtee_user_object_select(). */ 669 + guard(mutex)(&ctxdata->reqs_lock); 670 + 671 + ureq = ureq_dequeue(ctxdata, req_id); 672 + if (!ureq) 673 + return -EINVAL; 674 + 675 + ureq->state = QCOMTEE_REQ_PROCESSED; 676 + 677 + if (!errno) 678 + ureq->errno = qcomtee_cb_params_to_args(ureq->args, params, 679 + num_params, ctx); 680 + else 681 + ureq->errno = errno; 682 + /* Return errno if qcomtee_cb_params_to_args() failed; otherwise 0. */ 683 + if (!errno && ureq->errno) 684 + errno = ureq->errno; 685 + else 686 + errno = 0; 687 + 688 + /* Send result to QTEE. */ 689 + complete(&ureq->c); 690 + 691 + return errno; 692 + }
+1
include/uapi/linux/tee.h
··· 59 59 #define TEE_IMPL_ID_OPTEE 1 60 60 #define TEE_IMPL_ID_AMDTEE 2 61 61 #define TEE_IMPL_ID_TSTEE 3 62 + #define TEE_IMPL_ID_QTEE 4 62 63 63 64 /* 64 65 * OP-TEE specific capabilities