Merge tag 'powerpc-6.6-6' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
[platform/kernel/linux-starfive.git] / drivers / tee / amdtee / core.c
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright 2019 Advanced Micro Devices, Inc.
4  */
5
6 #include <linux/errno.h>
7 #include <linux/io.h>
8 #include <linux/module.h>
9 #include <linux/slab.h>
10 #include <linux/string.h>
11 #include <linux/device.h>
12 #include <linux/tee_drv.h>
13 #include <linux/types.h>
14 #include <linux/mm.h>
15 #include <linux/uaccess.h>
16 #include <linux/firmware.h>
17 #include "amdtee_private.h"
18 #include "../tee_private.h"
19 #include <linux/psp-tee.h>
20
21 static struct amdtee_driver_data *drv_data;
22 static DEFINE_MUTEX(session_list_mutex);
23
24 static void amdtee_get_version(struct tee_device *teedev,
25                                struct tee_ioctl_version_data *vers)
26 {
27         struct tee_ioctl_version_data v = {
28                 .impl_id = TEE_IMPL_ID_AMDTEE,
29                 .impl_caps = 0,
30                 .gen_caps = TEE_GEN_CAP_GP,
31         };
32         *vers = v;
33 }
34
35 static int amdtee_open(struct tee_context *ctx)
36 {
37         struct amdtee_context_data *ctxdata;
38
39         ctxdata = kzalloc(sizeof(*ctxdata), GFP_KERNEL);
40         if (!ctxdata)
41                 return -ENOMEM;
42
43         INIT_LIST_HEAD(&ctxdata->sess_list);
44         INIT_LIST_HEAD(&ctxdata->shm_list);
45         mutex_init(&ctxdata->shm_mutex);
46
47         ctx->data = ctxdata;
48         return 0;
49 }
50
51 static void release_session(struct amdtee_session *sess)
52 {
53         int i;
54
55         /* Close any open session */
56         for (i = 0; i < TEE_NUM_SESSIONS; ++i) {
57                 /* Check if session entry 'i' is valid */
58                 if (!test_bit(i, sess->sess_mask))
59                         continue;
60
61                 handle_close_session(sess->ta_handle, sess->session_info[i]);
62                 handle_unload_ta(sess->ta_handle);
63         }
64
65         kfree(sess);
66 }
67
68 static void amdtee_release(struct tee_context *ctx)
69 {
70         struct amdtee_context_data *ctxdata = ctx->data;
71
72         if (!ctxdata)
73                 return;
74
75         while (true) {
76                 struct amdtee_session *sess;
77
78                 sess = list_first_entry_or_null(&ctxdata->sess_list,
79                                                 struct amdtee_session,
80                                                 list_node);
81
82                 if (!sess)
83                         break;
84
85                 list_del(&sess->list_node);
86                 release_session(sess);
87         }
88         mutex_destroy(&ctxdata->shm_mutex);
89         kfree(ctxdata);
90
91         ctx->data = NULL;
92 }
93
94 /**
95  * alloc_session() - Allocate a session structure
96  * @ctxdata:    TEE Context data structure
97  * @session:    Session ID for which 'struct amdtee_session' structure is to be
98  *              allocated.
99  *
100  * Scans the TEE context's session list to check if TA is already loaded in to
101  * TEE. If yes, returns the 'session' structure for that TA. Else allocates,
102  * initializes a new 'session' structure and adds it to context's session list.
103  *
104  * The caller must hold a mutex.
105  *
106  * Returns:
107  * 'struct amdtee_session *' on success and NULL on failure.
108  */
109 static struct amdtee_session *alloc_session(struct amdtee_context_data *ctxdata,
110                                             u32 session)
111 {
112         struct amdtee_session *sess;
113         u32 ta_handle = get_ta_handle(session);
114
115         /* Scan session list to check if TA is already loaded in to TEE */
116         list_for_each_entry(sess, &ctxdata->sess_list, list_node)
117                 if (sess->ta_handle == ta_handle) {
118                         kref_get(&sess->refcount);
119                         return sess;
120                 }
121
122         /* Allocate a new session and add to list */
123         sess = kzalloc(sizeof(*sess), GFP_KERNEL);
124         if (sess) {
125                 sess->ta_handle = ta_handle;
126                 kref_init(&sess->refcount);
127                 spin_lock_init(&sess->lock);
128                 list_add(&sess->list_node, &ctxdata->sess_list);
129         }
130
131         return sess;
132 }
133
134 /* Requires mutex to be held */
135 static struct amdtee_session *find_session(struct amdtee_context_data *ctxdata,
136                                            u32 session)
137 {
138         u32 ta_handle = get_ta_handle(session);
139         u32 index = get_session_index(session);
140         struct amdtee_session *sess;
141
142         if (index >= TEE_NUM_SESSIONS)
143                 return NULL;
144
145         list_for_each_entry(sess, &ctxdata->sess_list, list_node)
146                 if (ta_handle == sess->ta_handle &&
147                     test_bit(index, sess->sess_mask))
148                         return sess;
149
150         return NULL;
151 }
152
153 u32 get_buffer_id(struct tee_shm *shm)
154 {
155         struct amdtee_context_data *ctxdata = shm->ctx->data;
156         struct amdtee_shm_data *shmdata;
157         u32 buf_id = 0;
158
159         mutex_lock(&ctxdata->shm_mutex);
160         list_for_each_entry(shmdata, &ctxdata->shm_list, shm_node)
161                 if (shmdata->kaddr == shm->kaddr) {
162                         buf_id = shmdata->buf_id;
163                         break;
164                 }
165         mutex_unlock(&ctxdata->shm_mutex);
166
167         return buf_id;
168 }
169
170 static DEFINE_MUTEX(drv_mutex);
171 static int copy_ta_binary(struct tee_context *ctx, void *ptr, void **ta,
172                           size_t *ta_size)
173 {
174         const struct firmware *fw;
175         char fw_name[TA_PATH_MAX];
176         struct {
177                 u32 lo;
178                 u16 mid;
179                 u16 hi_ver;
180                 u8 seq_n[8];
181         } *uuid = ptr;
182         int n, rc = 0;
183
184         n = snprintf(fw_name, TA_PATH_MAX,
185                      "%s/%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x.bin",
186                      TA_LOAD_PATH, uuid->lo, uuid->mid, uuid->hi_ver,
187                      uuid->seq_n[0], uuid->seq_n[1],
188                      uuid->seq_n[2], uuid->seq_n[3],
189                      uuid->seq_n[4], uuid->seq_n[5],
190                      uuid->seq_n[6], uuid->seq_n[7]);
191         if (n < 0 || n >= TA_PATH_MAX) {
192                 pr_err("failed to get firmware name\n");
193                 return -EINVAL;
194         }
195
196         mutex_lock(&drv_mutex);
197         n = request_firmware(&fw, fw_name, &ctx->teedev->dev);
198         if (n) {
199                 pr_err("failed to load firmware %s\n", fw_name);
200                 rc = -ENOMEM;
201                 goto unlock;
202         }
203
204         *ta_size = roundup(fw->size, PAGE_SIZE);
205         *ta = (void *)__get_free_pages(GFP_KERNEL, get_order(*ta_size));
206         if (!*ta) {
207                 pr_err("%s: get_free_pages failed\n", __func__);
208                 rc = -ENOMEM;
209                 goto rel_fw;
210         }
211
212         memcpy(*ta, fw->data, fw->size);
213 rel_fw:
214         release_firmware(fw);
215 unlock:
216         mutex_unlock(&drv_mutex);
217         return rc;
218 }
219
220 /* mutex must be held by caller */
221 static void destroy_session(struct kref *ref)
222 {
223         struct amdtee_session *sess = container_of(ref, struct amdtee_session,
224                                                    refcount);
225
226         list_del(&sess->list_node);
227         mutex_unlock(&session_list_mutex);
228         kfree(sess);
229 }
230
231 int amdtee_open_session(struct tee_context *ctx,
232                         struct tee_ioctl_open_session_arg *arg,
233                         struct tee_param *param)
234 {
235         struct amdtee_context_data *ctxdata = ctx->data;
236         struct amdtee_session *sess = NULL;
237         u32 session_info, ta_handle;
238         size_t ta_size;
239         int rc, i;
240         void *ta;
241
242         if (arg->clnt_login != TEE_IOCTL_LOGIN_PUBLIC) {
243                 pr_err("unsupported client login method\n");
244                 return -EINVAL;
245         }
246
247         rc = copy_ta_binary(ctx, &arg->uuid[0], &ta, &ta_size);
248         if (rc) {
249                 pr_err("failed to copy TA binary\n");
250                 return rc;
251         }
252
253         /* Load the TA binary into TEE environment */
254         handle_load_ta(ta, ta_size, arg);
255         if (arg->ret != TEEC_SUCCESS)
256                 goto out;
257
258         ta_handle = get_ta_handle(arg->session);
259
260         mutex_lock(&session_list_mutex);
261         sess = alloc_session(ctxdata, arg->session);
262         mutex_unlock(&session_list_mutex);
263
264         if (!sess) {
265                 handle_unload_ta(ta_handle);
266                 rc = -ENOMEM;
267                 goto out;
268         }
269
270         /* Open session with loaded TA */
271         handle_open_session(arg, &session_info, param);
272         if (arg->ret != TEEC_SUCCESS) {
273                 pr_err("open_session failed %d\n", arg->ret);
274                 handle_unload_ta(ta_handle);
275                 kref_put_mutex(&sess->refcount, destroy_session,
276                                &session_list_mutex);
277                 goto out;
278         }
279
280         /* Find an empty session index for the given TA */
281         spin_lock(&sess->lock);
282         i = find_first_zero_bit(sess->sess_mask, TEE_NUM_SESSIONS);
283         if (i < TEE_NUM_SESSIONS) {
284                 sess->session_info[i] = session_info;
285                 set_session_id(ta_handle, i, &arg->session);
286                 set_bit(i, sess->sess_mask);
287         }
288         spin_unlock(&sess->lock);
289
290         if (i >= TEE_NUM_SESSIONS) {
291                 pr_err("reached maximum session count %d\n", TEE_NUM_SESSIONS);
292                 handle_close_session(ta_handle, session_info);
293                 handle_unload_ta(ta_handle);
294                 kref_put_mutex(&sess->refcount, destroy_session,
295                                &session_list_mutex);
296                 rc = -ENOMEM;
297                 goto out;
298         }
299
300 out:
301         free_pages((u64)ta, get_order(ta_size));
302         return rc;
303 }
304
305 int amdtee_close_session(struct tee_context *ctx, u32 session)
306 {
307         struct amdtee_context_data *ctxdata = ctx->data;
308         u32 i, ta_handle, session_info;
309         struct amdtee_session *sess;
310
311         pr_debug("%s: sid = 0x%x\n", __func__, session);
312
313         /*
314          * Check that the session is valid and clear the session
315          * usage bit
316          */
317         mutex_lock(&session_list_mutex);
318         sess = find_session(ctxdata, session);
319         if (sess) {
320                 ta_handle = get_ta_handle(session);
321                 i = get_session_index(session);
322                 session_info = sess->session_info[i];
323                 spin_lock(&sess->lock);
324                 clear_bit(i, sess->sess_mask);
325                 spin_unlock(&sess->lock);
326         }
327         mutex_unlock(&session_list_mutex);
328
329         if (!sess)
330                 return -EINVAL;
331
332         /* Close the session */
333         handle_close_session(ta_handle, session_info);
334         handle_unload_ta(ta_handle);
335
336         kref_put_mutex(&sess->refcount, destroy_session, &session_list_mutex);
337
338         return 0;
339 }
340
341 int amdtee_map_shmem(struct tee_shm *shm)
342 {
343         struct amdtee_context_data *ctxdata;
344         struct amdtee_shm_data *shmnode;
345         struct shmem_desc shmem;
346         int rc, count;
347         u32 buf_id;
348
349         if (!shm)
350                 return -EINVAL;
351
352         shmnode = kmalloc(sizeof(*shmnode), GFP_KERNEL);
353         if (!shmnode)
354                 return -ENOMEM;
355
356         count = 1;
357         shmem.kaddr = shm->kaddr;
358         shmem.size = shm->size;
359
360         /*
361          * Send a MAP command to TEE and get the corresponding
362          * buffer Id
363          */
364         rc = handle_map_shmem(count, &shmem, &buf_id);
365         if (rc) {
366                 pr_err("map_shmem failed: ret = %d\n", rc);
367                 kfree(shmnode);
368                 return rc;
369         }
370
371         shmnode->kaddr = shm->kaddr;
372         shmnode->buf_id = buf_id;
373         ctxdata = shm->ctx->data;
374         mutex_lock(&ctxdata->shm_mutex);
375         list_add(&shmnode->shm_node, &ctxdata->shm_list);
376         mutex_unlock(&ctxdata->shm_mutex);
377
378         pr_debug("buf_id :[%x] kaddr[%p]\n", shmnode->buf_id, shmnode->kaddr);
379
380         return 0;
381 }
382
383 void amdtee_unmap_shmem(struct tee_shm *shm)
384 {
385         struct amdtee_context_data *ctxdata;
386         struct amdtee_shm_data *shmnode;
387         u32 buf_id;
388
389         if (!shm)
390                 return;
391
392         buf_id = get_buffer_id(shm);
393         /* Unmap the shared memory from TEE */
394         handle_unmap_shmem(buf_id);
395
396         ctxdata = shm->ctx->data;
397         mutex_lock(&ctxdata->shm_mutex);
398         list_for_each_entry(shmnode, &ctxdata->shm_list, shm_node)
399                 if (buf_id == shmnode->buf_id) {
400                         list_del(&shmnode->shm_node);
401                         kfree(shmnode);
402                         break;
403                 }
404         mutex_unlock(&ctxdata->shm_mutex);
405 }
406
407 int amdtee_invoke_func(struct tee_context *ctx,
408                        struct tee_ioctl_invoke_arg *arg,
409                        struct tee_param *param)
410 {
411         struct amdtee_context_data *ctxdata = ctx->data;
412         struct amdtee_session *sess;
413         u32 i, session_info;
414
415         /* Check that the session is valid */
416         mutex_lock(&session_list_mutex);
417         sess = find_session(ctxdata, arg->session);
418         if (sess) {
419                 i = get_session_index(arg->session);
420                 session_info = sess->session_info[i];
421         }
422         mutex_unlock(&session_list_mutex);
423
424         if (!sess)
425                 return -EINVAL;
426
427         handle_invoke_cmd(arg, session_info, param);
428
429         return 0;
430 }
431
432 int amdtee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session)
433 {
434         return -EINVAL;
435 }
436
437 static const struct tee_driver_ops amdtee_ops = {
438         .get_version = amdtee_get_version,
439         .open = amdtee_open,
440         .release = amdtee_release,
441         .open_session = amdtee_open_session,
442         .close_session = amdtee_close_session,
443         .invoke_func = amdtee_invoke_func,
444         .cancel_req = amdtee_cancel_req,
445 };
446
447 static const struct tee_desc amdtee_desc = {
448         .name = DRIVER_NAME "-clnt",
449         .ops = &amdtee_ops,
450         .owner = THIS_MODULE,
451 };
452
453 static int __init amdtee_driver_init(void)
454 {
455         struct tee_device *teedev;
456         struct tee_shm_pool *pool;
457         struct amdtee *amdtee;
458         int rc;
459
460         rc = psp_check_tee_status();
461         if (rc) {
462                 pr_err("amd-tee driver: tee not present\n");
463                 return rc;
464         }
465
466         drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL);
467         if (!drv_data)
468                 return -ENOMEM;
469
470         amdtee = kzalloc(sizeof(*amdtee), GFP_KERNEL);
471         if (!amdtee) {
472                 rc = -ENOMEM;
473                 goto err_kfree_drv_data;
474         }
475
476         pool = amdtee_config_shm();
477         if (IS_ERR(pool)) {
478                 pr_err("shared pool configuration error\n");
479                 rc = PTR_ERR(pool);
480                 goto err_kfree_amdtee;
481         }
482
483         teedev = tee_device_alloc(&amdtee_desc, NULL, pool, amdtee);
484         if (IS_ERR(teedev)) {
485                 rc = PTR_ERR(teedev);
486                 goto err_free_pool;
487         }
488         amdtee->teedev = teedev;
489
490         rc = tee_device_register(amdtee->teedev);
491         if (rc)
492                 goto err_device_unregister;
493
494         amdtee->pool = pool;
495
496         drv_data->amdtee = amdtee;
497
498         pr_info("amd-tee driver initialization successful\n");
499         return 0;
500
501 err_device_unregister:
502         tee_device_unregister(amdtee->teedev);
503
504 err_free_pool:
505         tee_shm_pool_free(pool);
506
507 err_kfree_amdtee:
508         kfree(amdtee);
509
510 err_kfree_drv_data:
511         kfree(drv_data);
512         drv_data = NULL;
513
514         pr_err("amd-tee driver initialization failed\n");
515         return rc;
516 }
517 module_init(amdtee_driver_init);
518
519 static void __exit amdtee_driver_exit(void)
520 {
521         struct amdtee *amdtee;
522
523         if (!drv_data || !drv_data->amdtee)
524                 return;
525
526         amdtee = drv_data->amdtee;
527
528         tee_device_unregister(amdtee->teedev);
529         tee_shm_pool_free(amdtee->pool);
530 }
531 module_exit(amdtee_driver_exit);
532
533 MODULE_AUTHOR(DRIVER_AUTHOR);
534 MODULE_DESCRIPTION("AMD-TEE driver");
535 MODULE_VERSION("1.0");
536 MODULE_LICENSE("Dual MIT/GPL");