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)
81 mutex_lock(&rpc->outsync);
83 memcpy(&rpc->commToUser, data, datalen);
85 mutex_unlock(&rpc->outsync);
88 "Supplicant Cmd: %x. Give hand to supplicant\n",
93 down(&rpc->datafromuser);
96 "Supplicant Cmd: %x. Give hand to fw\n",
99 mutex_lock(&rpc->insync);
101 memcpy(data, &rpc->commFromUser, datalen);
103 mutex_unlock(&rpc->insync);
115 dev_dbg(tee->dev, "< res: [%d]\n", res);
119 EXPORT_SYMBOL(tee_supp_cmd);
121 ssize_t tee_supp_read(struct file *filp, char __user *buffer,
122 size_t length, loff_t *offset)
124 struct tee_context *ctx = (struct tee_context *)(filp->private_data);
127 struct task_struct *task = current;
136 dev_dbg(tee->dev, "> ctx %p\n", ctx);
140 if (atomic_read(&rpc->used) == 0) {
141 dev_err(tee->dev, "%s: ERROR Supplicant application NOT ready\n"
147 if (down_interruptible(&rpc->datatouser))
150 dev_dbg(tee->dev, "> tgid:[%d]\n", task->tgid);
152 mutex_lock(&rpc->outsync);
155 sizeof(rpc->commToUser) - sizeof(rpc->commToUser.cmds) +
156 sizeof(rpc->commToUser.cmds[0]) * rpc->commToUser.nbr_bf;
160 if (copy_to_user(buffer, &rpc->commToUser, ret)) {
162 "[%s] error, copy_to_user failed!\n", __func__);
167 mutex_unlock(&rpc->outsync);
170 dev_dbg(tee->dev, "< [%d]\n", ret);
174 ssize_t tee_supp_write(struct file *filp, const char __user *buffer,
175 size_t length, loff_t *offset)
177 struct tee_context *ctx = (struct tee_context *)(filp->private_data);
180 struct task_struct *task = current;
185 BUG_ON(!ctx->tee->rpc);
188 dev_dbg(tee->dev, "> tgid:[%d]\n", task->tgid);
190 if (atomic_read(&rpc->used) == 0) {
191 dev_err(tee->dev, "%s: ERROR Supplicant application NOT ready\n"
196 if (length > 0 && length < sizeof(rpc->commFromUser)) {
199 mutex_lock(&rpc->insync);
201 if (copy_from_user(&rpc->commFromUser, buffer, length)) {
203 "%s: ERROR, tee_session copy_from_user failed\n",
205 mutex_unlock(&rpc->insync);
210 /* Translate virtual address of caller into physical address */
211 for (i = 0; i < rpc->commFromUser.nbr_bf; i++) {
212 if (rpc->commFromUser.cmds[i].type == TEE_RPC_BUFFER
213 && rpc->commFromUser.cmds[i].buffer) {
214 struct vm_area_struct *vma =
215 find_vma(current->mm,
217 commFromUser.cmds[i].buffer);
219 struct tee_shm *shm =
220 vma->vm_private_data;
223 "%d gid2pa(0x%p => %x)\n", i,
224 rpc->commFromUser.cmds[i].
226 (unsigned int)shm->paddr);
227 rpc->commFromUser.cmds[i].buffer =
231 " gid2pa(0x%p => NULL\n)",
232 rpc->commFromUser.cmds[i].
237 mutex_unlock(&rpc->insync);
238 up(&rpc->datafromuser);
243 dev_dbg(tee->dev, "< [%d]\n", ret);
247 int tee_supp_init(struct tee *tee)
249 struct tee_rpc *rpc =
250 devm_kzalloc(tee->dev, sizeof(struct tee_rpc), GFP_KERNEL);
252 dev_err(tee->dev, "%s: can't allocate tee_rpc structure\n",
257 rpc->datafromuser = (struct semaphore)
258 __SEMAPHORE_INITIALIZER(rpc->datafromuser, 0);
259 rpc->datatouser = (struct semaphore)
260 __SEMAPHORE_INITIALIZER(rpc->datatouser, 0);
261 mutex_init(&rpc->outsync);
262 mutex_init(&rpc->insync);
263 atomic_set(&rpc->used, 0);
268 void tee_supp_deinit(struct tee *tee)
270 devm_kfree(tee->dev, tee->rpc);