2 * Copyright (c) 2014, STMicroelectronics International N.V.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation.
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.
13 #include <linux/kernel.h>
15 #include <linux/mutex.h>
16 #include <linux/miscdevice.h>
17 #include <linux/uaccess.h>
18 #include <linux/anon_inodes.h>
19 #include <linux/semaphore.h>
21 #include <linux/sched.h>
22 #include <linux/device.h>
26 #include "tee_supp_com.h"
28 #define TEE_RPC_BUFFER 0x00000001
29 #define TEE_RPC_VALUE 0x00000002
31 enum teec_rpc_result tee_supp_cmd(struct tee *tee,
32 uint32_t id, void *data, size_t datalen)
34 struct tee_rpc *rpc = tee->rpc;
35 enum teec_rpc_result res = TEEC_RPC_FAIL;
37 struct task_struct *task = current;
39 dev_dbg(tee->dev, "> tgid:[%d] id:[0x%08x]\n", task->tgid, id);
41 if (atomic_read(&rpc->used) == 0) {
42 dev_err(tee->dev, "%s: ERROR Supplicant application NOT ready\n"
48 case TEE_RPC_ICMD_ALLOCATE:
50 struct tee_rpc_alloc *alloc;
51 struct tee_shm *shmint;
53 alloc = (struct tee_rpc_alloc *)data;
55 memset(alloc, 0, sizeof(struct tee_rpc_alloc));
56 shmint = tee_shm_alloc_from_rpc(tee, size);
57 if (IS_ERR_OR_NULL(shmint))
61 alloc->data = (void *)shmint->paddr;
67 case TEE_RPC_ICMD_FREE:
69 struct tee_rpc_free *free;
71 free = (struct tee_rpc_free *)data;
72 tee_shm_free_from_rpc(free->shm);
76 case TEE_RPC_ICMD_INVOKE:
78 if (sizeof(rpc->commToUser) < datalen)
82 * Other threads blocks here until we've copied our
83 * answer from the supplicant
85 mutex_lock(&rpc->thrd_mutex);
87 mutex_lock(&rpc->outsync);
88 memcpy(&rpc->commToUser, data, datalen);
89 mutex_unlock(&rpc->outsync);
92 "Supplicant Cmd: %x. Give hand to supplicant\n",
97 down(&rpc->datafromuser);
100 "Supplicant Cmd: %x. Give hand to fw\n",
101 rpc->commToUser.cmd);
103 mutex_lock(&rpc->insync);
104 memcpy(data, &rpc->commFromUser, datalen);
105 mutex_unlock(&rpc->insync);
107 mutex_unlock(&rpc->thrd_mutex);
119 dev_dbg(tee->dev, "< res: [%d]\n", res);
123 EXPORT_SYMBOL(tee_supp_cmd);
125 ssize_t tee_supp_read(struct file *filp, char __user *buffer,
126 size_t length, loff_t *offset)
128 struct tee_context *ctx = (struct tee_context *)(filp->private_data);
131 struct task_struct *task = current;
140 dev_dbg(tee->dev, "> ctx %p\n", ctx);
144 if (atomic_read(&rpc->used) == 0) {
145 dev_err(tee->dev, "%s: ERROR Supplicant application NOT ready\n"
151 if (down_interruptible(&rpc->datatouser))
154 dev_dbg(tee->dev, "> tgid:[%d]\n", task->tgid);
156 mutex_lock(&rpc->outsync);
159 sizeof(rpc->commToUser) - sizeof(rpc->commToUser.cmds) +
160 sizeof(rpc->commToUser.cmds[0]) * rpc->commToUser.nbr_bf;
164 if (copy_to_user(buffer, &rpc->commToUser, ret)) {
166 "[%s] error, copy_to_user failed!\n", __func__);
171 mutex_unlock(&rpc->outsync);
174 dev_dbg(tee->dev, "< [%d]\n", ret);
178 ssize_t tee_supp_write(struct file *filp, const char __user *buffer,
179 size_t length, loff_t *offset)
181 struct tee_context *ctx = (struct tee_context *)(filp->private_data);
184 struct task_struct *task = current;
189 BUG_ON(!ctx->tee->rpc);
192 dev_dbg(tee->dev, "> tgid:[%d]\n", task->tgid);
194 if (atomic_read(&rpc->used) == 0) {
195 dev_err(tee->dev, "%s: ERROR Supplicant application NOT ready\n"
200 if (length > 0 && length < sizeof(rpc->commFromUser)) {
203 mutex_lock(&rpc->insync);
205 if (copy_from_user(&rpc->commFromUser, buffer, length)) {
207 "%s: ERROR, tee_session copy_from_user failed\n",
209 mutex_unlock(&rpc->insync);
214 /* Translate virtual address of caller into physical address */
215 for (i = 0; i < rpc->commFromUser.nbr_bf; i++) {
216 if (rpc->commFromUser.cmds[i].type == TEE_RPC_BUFFER
217 && rpc->commFromUser.cmds[i].buffer) {
218 struct vm_area_struct *vma =
219 find_vma(current->mm,
221 commFromUser.cmds[i].buffer);
223 struct tee_shm *shm =
224 vma->vm_private_data;
227 "%d gid2pa(0x%p => %x)\n", i,
228 rpc->commFromUser.cmds[i].
230 (unsigned int)shm->paddr);
231 rpc->commFromUser.cmds[i].buffer =
235 " gid2pa(0x%p => NULL\n)",
236 rpc->commFromUser.cmds[i].
241 mutex_unlock(&rpc->insync);
242 up(&rpc->datafromuser);
247 dev_dbg(tee->dev, "< [%d]\n", ret);
251 int tee_supp_init(struct tee *tee)
253 struct tee_rpc *rpc =
254 devm_kzalloc(tee->dev, sizeof(struct tee_rpc), GFP_KERNEL);
256 dev_err(tee->dev, "%s: can't allocate tee_rpc structure\n",
261 rpc->datafromuser = (struct semaphore)
262 __SEMAPHORE_INITIALIZER(rpc->datafromuser, 0);
263 rpc->datatouser = (struct semaphore)
264 __SEMAPHORE_INITIALIZER(rpc->datatouser, 0);
265 mutex_init(&rpc->thrd_mutex);
266 mutex_init(&rpc->outsync);
267 mutex_init(&rpc->insync);
268 atomic_set(&rpc->used, 0);
273 void tee_supp_deinit(struct tee *tee)
275 devm_kfree(tee->dev, tee->rpc);