0001
0002
0003
0004
0005
0006 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0007
0008 #include <linux/delay.h>
0009 #include <linux/i2c.h>
0010 #include <linux/slab.h>
0011 #include <linux/tee_drv.h>
0012 #include "optee_private.h"
0013 #include "optee_rpc_cmd.h"
0014
0015 static void handle_rpc_func_cmd_get_time(struct optee_msg_arg *arg)
0016 {
0017 struct timespec64 ts;
0018
0019 if (arg->num_params != 1)
0020 goto bad;
0021 if ((arg->params[0].attr & OPTEE_MSG_ATTR_TYPE_MASK) !=
0022 OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT)
0023 goto bad;
0024
0025 ktime_get_real_ts64(&ts);
0026 arg->params[0].u.value.a = ts.tv_sec;
0027 arg->params[0].u.value.b = ts.tv_nsec;
0028
0029 arg->ret = TEEC_SUCCESS;
0030 return;
0031 bad:
0032 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
0033 }
0034
0035 #if IS_REACHABLE(CONFIG_I2C)
0036 static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
0037 struct optee_msg_arg *arg)
0038 {
0039 struct optee *optee = tee_get_drvdata(ctx->teedev);
0040 struct tee_param *params;
0041 struct i2c_adapter *adapter;
0042 struct i2c_msg msg = { };
0043 size_t i;
0044 int ret = -EOPNOTSUPP;
0045 u8 attr[] = {
0046 TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT,
0047 TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT,
0048 TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT,
0049 TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT,
0050 };
0051
0052 if (arg->num_params != ARRAY_SIZE(attr)) {
0053 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
0054 return;
0055 }
0056
0057 params = kmalloc_array(arg->num_params, sizeof(struct tee_param),
0058 GFP_KERNEL);
0059 if (!params) {
0060 arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
0061 return;
0062 }
0063
0064 if (optee->ops->from_msg_param(optee, params, arg->num_params,
0065 arg->params))
0066 goto bad;
0067
0068 for (i = 0; i < arg->num_params; i++) {
0069 if (params[i].attr != attr[i])
0070 goto bad;
0071 }
0072
0073 adapter = i2c_get_adapter(params[0].u.value.b);
0074 if (!adapter)
0075 goto bad;
0076
0077 if (params[1].u.value.a & OPTEE_RPC_I2C_FLAGS_TEN_BIT) {
0078 if (!i2c_check_functionality(adapter,
0079 I2C_FUNC_10BIT_ADDR)) {
0080 i2c_put_adapter(adapter);
0081 goto bad;
0082 }
0083
0084 msg.flags = I2C_M_TEN;
0085 }
0086
0087 msg.addr = params[0].u.value.c;
0088 msg.buf = params[2].u.memref.shm->kaddr;
0089 msg.len = params[2].u.memref.size;
0090
0091 switch (params[0].u.value.a) {
0092 case OPTEE_RPC_I2C_TRANSFER_RD:
0093 msg.flags |= I2C_M_RD;
0094 break;
0095 case OPTEE_RPC_I2C_TRANSFER_WR:
0096 break;
0097 default:
0098 i2c_put_adapter(adapter);
0099 goto bad;
0100 }
0101
0102 ret = i2c_transfer(adapter, &msg, 1);
0103
0104 if (ret < 0) {
0105 arg->ret = TEEC_ERROR_COMMUNICATION;
0106 } else {
0107 params[3].u.value.a = msg.len;
0108 if (optee->ops->to_msg_param(optee, arg->params,
0109 arg->num_params, params))
0110 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
0111 else
0112 arg->ret = TEEC_SUCCESS;
0113 }
0114
0115 i2c_put_adapter(adapter);
0116 kfree(params);
0117 return;
0118 bad:
0119 kfree(params);
0120 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
0121 }
0122 #else
0123 static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
0124 struct optee_msg_arg *arg)
0125 {
0126 arg->ret = TEEC_ERROR_NOT_SUPPORTED;
0127 }
0128 #endif
0129
0130 static void handle_rpc_func_cmd_wq(struct optee *optee,
0131 struct optee_msg_arg *arg)
0132 {
0133 if (arg->num_params != 1)
0134 goto bad;
0135
0136 if ((arg->params[0].attr & OPTEE_MSG_ATTR_TYPE_MASK) !=
0137 OPTEE_MSG_ATTR_TYPE_VALUE_INPUT)
0138 goto bad;
0139
0140 switch (arg->params[0].u.value.a) {
0141 case OPTEE_RPC_NOTIFICATION_WAIT:
0142 if (optee_notif_wait(optee, arg->params[0].u.value.b))
0143 goto bad;
0144 break;
0145 case OPTEE_RPC_NOTIFICATION_SEND:
0146 if (optee_notif_send(optee, arg->params[0].u.value.b))
0147 goto bad;
0148 break;
0149 default:
0150 goto bad;
0151 }
0152
0153 arg->ret = TEEC_SUCCESS;
0154 return;
0155 bad:
0156 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
0157 }
0158
0159 static void handle_rpc_func_cmd_wait(struct optee_msg_arg *arg)
0160 {
0161 u32 msec_to_wait;
0162
0163 if (arg->num_params != 1)
0164 goto bad;
0165
0166 if ((arg->params[0].attr & OPTEE_MSG_ATTR_TYPE_MASK) !=
0167 OPTEE_MSG_ATTR_TYPE_VALUE_INPUT)
0168 goto bad;
0169
0170 msec_to_wait = arg->params[0].u.value.a;
0171
0172
0173 msleep_interruptible(msec_to_wait);
0174
0175 arg->ret = TEEC_SUCCESS;
0176 return;
0177 bad:
0178 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
0179 }
0180
0181 static void handle_rpc_supp_cmd(struct tee_context *ctx, struct optee *optee,
0182 struct optee_msg_arg *arg)
0183 {
0184 struct tee_param *params;
0185
0186 arg->ret_origin = TEEC_ORIGIN_COMMS;
0187
0188 params = kmalloc_array(arg->num_params, sizeof(struct tee_param),
0189 GFP_KERNEL);
0190 if (!params) {
0191 arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
0192 return;
0193 }
0194
0195 if (optee->ops->from_msg_param(optee, params, arg->num_params,
0196 arg->params)) {
0197 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
0198 goto out;
0199 }
0200
0201 arg->ret = optee_supp_thrd_req(ctx, arg->cmd, arg->num_params, params);
0202
0203 if (optee->ops->to_msg_param(optee, arg->params, arg->num_params,
0204 params))
0205 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
0206 out:
0207 kfree(params);
0208 }
0209
0210 struct tee_shm *optee_rpc_cmd_alloc_suppl(struct tee_context *ctx, size_t sz)
0211 {
0212 u32 ret;
0213 struct tee_param param;
0214 struct optee *optee = tee_get_drvdata(ctx->teedev);
0215 struct tee_shm *shm;
0216
0217 param.attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT;
0218 param.u.value.a = OPTEE_RPC_SHM_TYPE_APPL;
0219 param.u.value.b = sz;
0220 param.u.value.c = 0;
0221
0222 ret = optee_supp_thrd_req(ctx, OPTEE_RPC_CMD_SHM_ALLOC, 1, ¶m);
0223 if (ret)
0224 return ERR_PTR(-ENOMEM);
0225
0226 mutex_lock(&optee->supp.mutex);
0227
0228 shm = tee_shm_get_from_id(optee->supp.ctx, param.u.value.c);
0229 mutex_unlock(&optee->supp.mutex);
0230 return shm;
0231 }
0232
0233 void optee_rpc_cmd_free_suppl(struct tee_context *ctx, struct tee_shm *shm)
0234 {
0235 struct tee_param param;
0236
0237 param.attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT;
0238 param.u.value.a = OPTEE_RPC_SHM_TYPE_APPL;
0239 param.u.value.b = tee_shm_get_id(shm);
0240 param.u.value.c = 0;
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253 tee_shm_put(shm);
0254
0255 optee_supp_thrd_req(ctx, OPTEE_RPC_CMD_SHM_FREE, 1, ¶m);
0256 }
0257
0258 void optee_rpc_cmd(struct tee_context *ctx, struct optee *optee,
0259 struct optee_msg_arg *arg)
0260 {
0261 switch (arg->cmd) {
0262 case OPTEE_RPC_CMD_GET_TIME:
0263 handle_rpc_func_cmd_get_time(arg);
0264 break;
0265 case OPTEE_RPC_CMD_NOTIFICATION:
0266 handle_rpc_func_cmd_wq(optee, arg);
0267 break;
0268 case OPTEE_RPC_CMD_SUSPEND:
0269 handle_rpc_func_cmd_wait(arg);
0270 break;
0271 case OPTEE_RPC_CMD_I2C_TRANSFER:
0272 handle_rpc_func_cmd_i2c_transfer(ctx, arg);
0273 break;
0274 default:
0275 handle_rpc_supp_cmd(ctx, optee, arg);
0276 }
0277 }
0278
0279