hc
2024-05-10 37f49e37ab4cb5d0bc4c60eb5c6d4dd57db767bb
kernel/drivers/tee/optee/rpc.c
....@@ -1,21 +1,13 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2015-2016, Linaro Limited
3
- *
4
- * This software is licensed under the terms of the GNU General Public
5
- * License version 2, as published by the Free Software Foundation, and
6
- * may be copied, distributed, and modified under those terms.
7
- *
8
- * This program is distributed in the hope that it will be useful,
9
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
- * GNU General Public License for more details.
12
- *
134 */
145
156 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
167
178 #include <linux/delay.h>
189 #include <linux/device.h>
10
+#include <linux/i2c.h>
1911 #include <linux/slab.h>
2012 #include <linux/tee_drv.h>
2113 #include "optee_private.h"
....@@ -57,6 +49,98 @@
5749 bad:
5850 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
5951 }
52
+
53
+#if IS_REACHABLE(CONFIG_I2C)
54
+static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
55
+ struct optee_msg_arg *arg)
56
+{
57
+ struct tee_param *params;
58
+ struct i2c_adapter *adapter;
59
+ struct i2c_msg msg = { };
60
+ size_t i;
61
+ int ret = -EOPNOTSUPP;
62
+ u8 attr[] = {
63
+ TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT,
64
+ TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT,
65
+ TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT,
66
+ TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT,
67
+ };
68
+
69
+ if (arg->num_params != ARRAY_SIZE(attr)) {
70
+ arg->ret = TEEC_ERROR_BAD_PARAMETERS;
71
+ return;
72
+ }
73
+
74
+ params = kmalloc_array(arg->num_params, sizeof(struct tee_param),
75
+ GFP_KERNEL);
76
+ if (!params) {
77
+ arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
78
+ return;
79
+ }
80
+
81
+ if (optee_from_msg_param(params, arg->num_params, arg->params))
82
+ goto bad;
83
+
84
+ for (i = 0; i < arg->num_params; i++) {
85
+ if (params[i].attr != attr[i])
86
+ goto bad;
87
+ }
88
+
89
+ adapter = i2c_get_adapter(params[0].u.value.b);
90
+ if (!adapter)
91
+ goto bad;
92
+
93
+ if (params[1].u.value.a & OPTEE_MSG_RPC_CMD_I2C_FLAGS_TEN_BIT) {
94
+ if (!i2c_check_functionality(adapter,
95
+ I2C_FUNC_10BIT_ADDR)) {
96
+ i2c_put_adapter(adapter);
97
+ goto bad;
98
+ }
99
+
100
+ msg.flags = I2C_M_TEN;
101
+ }
102
+
103
+ msg.addr = params[0].u.value.c;
104
+ msg.buf = params[2].u.memref.shm->kaddr;
105
+ msg.len = params[2].u.memref.size;
106
+
107
+ switch (params[0].u.value.a) {
108
+ case OPTEE_MSG_RPC_CMD_I2C_TRANSFER_RD:
109
+ msg.flags |= I2C_M_RD;
110
+ break;
111
+ case OPTEE_MSG_RPC_CMD_I2C_TRANSFER_WR:
112
+ break;
113
+ default:
114
+ i2c_put_adapter(adapter);
115
+ goto bad;
116
+ }
117
+
118
+ ret = i2c_transfer(adapter, &msg, 1);
119
+
120
+ if (ret < 0) {
121
+ arg->ret = TEEC_ERROR_COMMUNICATION;
122
+ } else {
123
+ params[3].u.value.a = msg.len;
124
+ if (optee_to_msg_param(arg->params, arg->num_params, params))
125
+ arg->ret = TEEC_ERROR_BAD_PARAMETERS;
126
+ else
127
+ arg->ret = TEEC_SUCCESS;
128
+ }
129
+
130
+ i2c_put_adapter(adapter);
131
+ kfree(params);
132
+ return;
133
+bad:
134
+ kfree(params);
135
+ arg->ret = TEEC_ERROR_BAD_PARAMETERS;
136
+}
137
+#else
138
+static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx,
139
+ struct optee_msg_arg *arg)
140
+{
141
+ arg->ret = TEEC_ERROR_NOT_SUPPORTED;
142
+}
143
+#endif
60144
61145 static struct wq_entry *wq_entry_get(struct optee_wait_queue *wq, u32 key)
62146 {
....@@ -200,6 +284,7 @@
200284 }
201285
202286 static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
287
+ struct optee *optee,
203288 struct optee_msg_arg *arg,
204289 struct optee_call_ctx *call_ctx)
205290 {
....@@ -229,7 +314,8 @@
229314 shm = cmd_alloc_suppl(ctx, sz);
230315 break;
231316 case OPTEE_MSG_RPC_SHM_TYPE_KERNEL:
232
- shm = tee_shm_alloc(ctx, sz, TEE_SHM_MAPPED);
317
+ shm = tee_shm_alloc(optee->ctx, sz,
318
+ TEE_SHM_MAPPED | TEE_SHM_PRIV);
233319 break;
234320 default:
235321 arg->ret = TEEC_ERROR_BAD_PARAMETERS;
....@@ -386,10 +472,13 @@
386472 break;
387473 case OPTEE_MSG_RPC_CMD_SHM_ALLOC:
388474 free_pages_list(call_ctx);
389
- handle_rpc_func_cmd_shm_alloc(ctx, arg, call_ctx);
475
+ handle_rpc_func_cmd_shm_alloc(ctx, optee, arg, call_ctx);
390476 break;
391477 case OPTEE_MSG_RPC_CMD_SHM_FREE:
392478 handle_rpc_func_cmd_shm_free(ctx, arg);
479
+ break;
480
+ case OPTEE_MSG_RPC_CMD_I2C_TRANSFER:
481
+ handle_rpc_func_cmd_i2c_transfer(ctx, arg);
393482 break;
394483 default:
395484 handle_rpc_supp_cmd(ctx, arg);
....@@ -414,7 +503,8 @@
414503
415504 switch (OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0)) {
416505 case OPTEE_SMC_RPC_FUNC_ALLOC:
417
- shm = tee_shm_alloc(ctx, param->a1, TEE_SHM_MAPPED);
506
+ shm = tee_shm_alloc(optee->ctx, param->a1,
507
+ TEE_SHM_MAPPED | TEE_SHM_PRIV);
418508 if (!IS_ERR(shm) && !tee_shm_get_pa(shm, 0, &pa)) {
419509 reg_pair_from_64(&param->a1, &param->a2, pa);
420510 reg_pair_from_64(&param->a4, &param->a5,