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