Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: MIT
0002 /*
0003  * Copyright 2019 Advanced Micro Devices, Inc.
0004  */
0005 
0006 #include <linux/errno.h>
0007 #include <linux/io.h>
0008 #include <linux/module.h>
0009 #include <linux/slab.h>
0010 #include <linux/string.h>
0011 #include <linux/device.h>
0012 #include <linux/tee_drv.h>
0013 #include <linux/types.h>
0014 #include <linux/mm.h>
0015 #include <linux/uaccess.h>
0016 #include <linux/firmware.h>
0017 #include "amdtee_private.h"
0018 #include "../tee_private.h"
0019 #include <linux/psp-tee.h>
0020 
0021 static struct amdtee_driver_data *drv_data;
0022 static DEFINE_MUTEX(session_list_mutex);
0023 
0024 static void amdtee_get_version(struct tee_device *teedev,
0025                    struct tee_ioctl_version_data *vers)
0026 {
0027     struct tee_ioctl_version_data v = {
0028         .impl_id = TEE_IMPL_ID_AMDTEE,
0029         .impl_caps = 0,
0030         .gen_caps = TEE_GEN_CAP_GP,
0031     };
0032     *vers = v;
0033 }
0034 
0035 static int amdtee_open(struct tee_context *ctx)
0036 {
0037     struct amdtee_context_data *ctxdata;
0038 
0039     ctxdata = kzalloc(sizeof(*ctxdata), GFP_KERNEL);
0040     if (!ctxdata)
0041         return -ENOMEM;
0042 
0043     INIT_LIST_HEAD(&ctxdata->sess_list);
0044     INIT_LIST_HEAD(&ctxdata->shm_list);
0045     mutex_init(&ctxdata->shm_mutex);
0046 
0047     ctx->data = ctxdata;
0048     return 0;
0049 }
0050 
0051 static void release_session(struct amdtee_session *sess)
0052 {
0053     int i;
0054 
0055     /* Close any open session */
0056     for (i = 0; i < TEE_NUM_SESSIONS; ++i) {
0057         /* Check if session entry 'i' is valid */
0058         if (!test_bit(i, sess->sess_mask))
0059             continue;
0060 
0061         handle_close_session(sess->ta_handle, sess->session_info[i]);
0062         handle_unload_ta(sess->ta_handle);
0063     }
0064 
0065     kfree(sess);
0066 }
0067 
0068 static void amdtee_release(struct tee_context *ctx)
0069 {
0070     struct amdtee_context_data *ctxdata = ctx->data;
0071 
0072     if (!ctxdata)
0073         return;
0074 
0075     while (true) {
0076         struct amdtee_session *sess;
0077 
0078         sess = list_first_entry_or_null(&ctxdata->sess_list,
0079                         struct amdtee_session,
0080                         list_node);
0081 
0082         if (!sess)
0083             break;
0084 
0085         list_del(&sess->list_node);
0086         release_session(sess);
0087     }
0088     mutex_destroy(&ctxdata->shm_mutex);
0089     kfree(ctxdata);
0090 
0091     ctx->data = NULL;
0092 }
0093 
0094 /**
0095  * alloc_session() - Allocate a session structure
0096  * @ctxdata:    TEE Context data structure
0097  * @session:    Session ID for which 'struct amdtee_session' structure is to be
0098  *              allocated.
0099  *
0100  * Scans the TEE context's session list to check if TA is already loaded in to
0101  * TEE. If yes, returns the 'session' structure for that TA. Else allocates,
0102  * initializes a new 'session' structure and adds it to context's session list.
0103  *
0104  * The caller must hold a mutex.
0105  *
0106  * Returns:
0107  * 'struct amdtee_session *' on success and NULL on failure.
0108  */
0109 static struct amdtee_session *alloc_session(struct amdtee_context_data *ctxdata,
0110                         u32 session)
0111 {
0112     struct amdtee_session *sess;
0113     u32 ta_handle = get_ta_handle(session);
0114 
0115     /* Scan session list to check if TA is already loaded in to TEE */
0116     list_for_each_entry(sess, &ctxdata->sess_list, list_node)
0117         if (sess->ta_handle == ta_handle) {
0118             kref_get(&sess->refcount);
0119             return sess;
0120         }
0121 
0122     /* Allocate a new session and add to list */
0123     sess = kzalloc(sizeof(*sess), GFP_KERNEL);
0124     if (sess) {
0125         sess->ta_handle = ta_handle;
0126         kref_init(&sess->refcount);
0127         spin_lock_init(&sess->lock);
0128         list_add(&sess->list_node, &ctxdata->sess_list);
0129     }
0130 
0131     return sess;
0132 }
0133 
0134 /* Requires mutex to be held */
0135 static struct amdtee_session *find_session(struct amdtee_context_data *ctxdata,
0136                        u32 session)
0137 {
0138     u32 ta_handle = get_ta_handle(session);
0139     u32 index = get_session_index(session);
0140     struct amdtee_session *sess;
0141 
0142     if (index >= TEE_NUM_SESSIONS)
0143         return NULL;
0144 
0145     list_for_each_entry(sess, &ctxdata->sess_list, list_node)
0146         if (ta_handle == sess->ta_handle &&
0147             test_bit(index, sess->sess_mask))
0148             return sess;
0149 
0150     return NULL;
0151 }
0152 
0153 u32 get_buffer_id(struct tee_shm *shm)
0154 {
0155     struct amdtee_context_data *ctxdata = shm->ctx->data;
0156     struct amdtee_shm_data *shmdata;
0157     u32 buf_id = 0;
0158 
0159     mutex_lock(&ctxdata->shm_mutex);
0160     list_for_each_entry(shmdata, &ctxdata->shm_list, shm_node)
0161         if (shmdata->kaddr == shm->kaddr) {
0162             buf_id = shmdata->buf_id;
0163             break;
0164         }
0165     mutex_unlock(&ctxdata->shm_mutex);
0166 
0167     return buf_id;
0168 }
0169 
0170 static DEFINE_MUTEX(drv_mutex);
0171 static int copy_ta_binary(struct tee_context *ctx, void *ptr, void **ta,
0172               size_t *ta_size)
0173 {
0174     const struct firmware *fw;
0175     char fw_name[TA_PATH_MAX];
0176     struct {
0177         u32 lo;
0178         u16 mid;
0179         u16 hi_ver;
0180         u8 seq_n[8];
0181     } *uuid = ptr;
0182     int n, rc = 0;
0183 
0184     n = snprintf(fw_name, TA_PATH_MAX,
0185              "%s/%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x.bin",
0186              TA_LOAD_PATH, uuid->lo, uuid->mid, uuid->hi_ver,
0187              uuid->seq_n[0], uuid->seq_n[1],
0188              uuid->seq_n[2], uuid->seq_n[3],
0189              uuid->seq_n[4], uuid->seq_n[5],
0190              uuid->seq_n[6], uuid->seq_n[7]);
0191     if (n < 0 || n >= TA_PATH_MAX) {
0192         pr_err("failed to get firmware name\n");
0193         return -EINVAL;
0194     }
0195 
0196     mutex_lock(&drv_mutex);
0197     n = request_firmware(&fw, fw_name, &ctx->teedev->dev);
0198     if (n) {
0199         pr_err("failed to load firmware %s\n", fw_name);
0200         rc = -ENOMEM;
0201         goto unlock;
0202     }
0203 
0204     *ta_size = roundup(fw->size, PAGE_SIZE);
0205     *ta = (void *)__get_free_pages(GFP_KERNEL, get_order(*ta_size));
0206     if (!*ta) {
0207         pr_err("%s: get_free_pages failed\n", __func__);
0208         rc = -ENOMEM;
0209         goto rel_fw;
0210     }
0211 
0212     memcpy(*ta, fw->data, fw->size);
0213 rel_fw:
0214     release_firmware(fw);
0215 unlock:
0216     mutex_unlock(&drv_mutex);
0217     return rc;
0218 }
0219 
0220 static void destroy_session(struct kref *ref)
0221 {
0222     struct amdtee_session *sess = container_of(ref, struct amdtee_session,
0223                            refcount);
0224 
0225     mutex_lock(&session_list_mutex);
0226     list_del(&sess->list_node);
0227     mutex_unlock(&session_list_mutex);
0228     kfree(sess);
0229 }
0230 
0231 int amdtee_open_session(struct tee_context *ctx,
0232             struct tee_ioctl_open_session_arg *arg,
0233             struct tee_param *param)
0234 {
0235     struct amdtee_context_data *ctxdata = ctx->data;
0236     struct amdtee_session *sess = NULL;
0237     u32 session_info, ta_handle;
0238     size_t ta_size;
0239     int rc, i;
0240     void *ta;
0241 
0242     if (arg->clnt_login != TEE_IOCTL_LOGIN_PUBLIC) {
0243         pr_err("unsupported client login method\n");
0244         return -EINVAL;
0245     }
0246 
0247     rc = copy_ta_binary(ctx, &arg->uuid[0], &ta, &ta_size);
0248     if (rc) {
0249         pr_err("failed to copy TA binary\n");
0250         return rc;
0251     }
0252 
0253     /* Load the TA binary into TEE environment */
0254     handle_load_ta(ta, ta_size, arg);
0255     if (arg->ret != TEEC_SUCCESS)
0256         goto out;
0257 
0258     ta_handle = get_ta_handle(arg->session);
0259 
0260     mutex_lock(&session_list_mutex);
0261     sess = alloc_session(ctxdata, arg->session);
0262     mutex_unlock(&session_list_mutex);
0263 
0264     if (!sess) {
0265         handle_unload_ta(ta_handle);
0266         rc = -ENOMEM;
0267         goto out;
0268     }
0269 
0270     /* Find an empty session index for the given TA */
0271     spin_lock(&sess->lock);
0272     i = find_first_zero_bit(sess->sess_mask, TEE_NUM_SESSIONS);
0273     if (i < TEE_NUM_SESSIONS)
0274         set_bit(i, sess->sess_mask);
0275     spin_unlock(&sess->lock);
0276 
0277     if (i >= TEE_NUM_SESSIONS) {
0278         pr_err("reached maximum session count %d\n", TEE_NUM_SESSIONS);
0279         handle_unload_ta(ta_handle);
0280         kref_put(&sess->refcount, destroy_session);
0281         rc = -ENOMEM;
0282         goto out;
0283     }
0284 
0285     /* Open session with loaded TA */
0286     handle_open_session(arg, &session_info, param);
0287     if (arg->ret != TEEC_SUCCESS) {
0288         pr_err("open_session failed %d\n", arg->ret);
0289         spin_lock(&sess->lock);
0290         clear_bit(i, sess->sess_mask);
0291         spin_unlock(&sess->lock);
0292         handle_unload_ta(ta_handle);
0293         kref_put(&sess->refcount, destroy_session);
0294         goto out;
0295     }
0296 
0297     sess->session_info[i] = session_info;
0298     set_session_id(ta_handle, i, &arg->session);
0299 out:
0300     free_pages((u64)ta, get_order(ta_size));
0301     return rc;
0302 }
0303 
0304 int amdtee_close_session(struct tee_context *ctx, u32 session)
0305 {
0306     struct amdtee_context_data *ctxdata = ctx->data;
0307     u32 i, ta_handle, session_info;
0308     struct amdtee_session *sess;
0309 
0310     pr_debug("%s: sid = 0x%x\n", __func__, session);
0311 
0312     /*
0313      * Check that the session is valid and clear the session
0314      * usage bit
0315      */
0316     mutex_lock(&session_list_mutex);
0317     sess = find_session(ctxdata, session);
0318     if (sess) {
0319         ta_handle = get_ta_handle(session);
0320         i = get_session_index(session);
0321         session_info = sess->session_info[i];
0322         spin_lock(&sess->lock);
0323         clear_bit(i, sess->sess_mask);
0324         spin_unlock(&sess->lock);
0325     }
0326     mutex_unlock(&session_list_mutex);
0327 
0328     if (!sess)
0329         return -EINVAL;
0330 
0331     /* Close the session */
0332     handle_close_session(ta_handle, session_info);
0333     handle_unload_ta(ta_handle);
0334 
0335     kref_put(&sess->refcount, destroy_session);
0336 
0337     return 0;
0338 }
0339 
0340 int amdtee_map_shmem(struct tee_shm *shm)
0341 {
0342     struct amdtee_context_data *ctxdata;
0343     struct amdtee_shm_data *shmnode;
0344     struct shmem_desc shmem;
0345     int rc, count;
0346     u32 buf_id;
0347 
0348     if (!shm)
0349         return -EINVAL;
0350 
0351     shmnode = kmalloc(sizeof(*shmnode), GFP_KERNEL);
0352     if (!shmnode)
0353         return -ENOMEM;
0354 
0355     count = 1;
0356     shmem.kaddr = shm->kaddr;
0357     shmem.size = shm->size;
0358 
0359     /*
0360      * Send a MAP command to TEE and get the corresponding
0361      * buffer Id
0362      */
0363     rc = handle_map_shmem(count, &shmem, &buf_id);
0364     if (rc) {
0365         pr_err("map_shmem failed: ret = %d\n", rc);
0366         kfree(shmnode);
0367         return rc;
0368     }
0369 
0370     shmnode->kaddr = shm->kaddr;
0371     shmnode->buf_id = buf_id;
0372     ctxdata = shm->ctx->data;
0373     mutex_lock(&ctxdata->shm_mutex);
0374     list_add(&shmnode->shm_node, &ctxdata->shm_list);
0375     mutex_unlock(&ctxdata->shm_mutex);
0376 
0377     pr_debug("buf_id :[%x] kaddr[%p]\n", shmnode->buf_id, shmnode->kaddr);
0378 
0379     return 0;
0380 }
0381 
0382 void amdtee_unmap_shmem(struct tee_shm *shm)
0383 {
0384     struct amdtee_context_data *ctxdata;
0385     struct amdtee_shm_data *shmnode;
0386     u32 buf_id;
0387 
0388     if (!shm)
0389         return;
0390 
0391     buf_id = get_buffer_id(shm);
0392     /* Unmap the shared memory from TEE */
0393     handle_unmap_shmem(buf_id);
0394 
0395     ctxdata = shm->ctx->data;
0396     mutex_lock(&ctxdata->shm_mutex);
0397     list_for_each_entry(shmnode, &ctxdata->shm_list, shm_node)
0398         if (buf_id == shmnode->buf_id) {
0399             list_del(&shmnode->shm_node);
0400             kfree(shmnode);
0401             break;
0402         }
0403     mutex_unlock(&ctxdata->shm_mutex);
0404 }
0405 
0406 int amdtee_invoke_func(struct tee_context *ctx,
0407                struct tee_ioctl_invoke_arg *arg,
0408                struct tee_param *param)
0409 {
0410     struct amdtee_context_data *ctxdata = ctx->data;
0411     struct amdtee_session *sess;
0412     u32 i, session_info;
0413 
0414     /* Check that the session is valid */
0415     mutex_lock(&session_list_mutex);
0416     sess = find_session(ctxdata, arg->session);
0417     if (sess) {
0418         i = get_session_index(arg->session);
0419         session_info = sess->session_info[i];
0420     }
0421     mutex_unlock(&session_list_mutex);
0422 
0423     if (!sess)
0424         return -EINVAL;
0425 
0426     handle_invoke_cmd(arg, session_info, param);
0427 
0428     return 0;
0429 }
0430 
0431 int amdtee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session)
0432 {
0433     return -EINVAL;
0434 }
0435 
0436 static const struct tee_driver_ops amdtee_ops = {
0437     .get_version = amdtee_get_version,
0438     .open = amdtee_open,
0439     .release = amdtee_release,
0440     .open_session = amdtee_open_session,
0441     .close_session = amdtee_close_session,
0442     .invoke_func = amdtee_invoke_func,
0443     .cancel_req = amdtee_cancel_req,
0444 };
0445 
0446 static const struct tee_desc amdtee_desc = {
0447     .name = DRIVER_NAME "-clnt",
0448     .ops = &amdtee_ops,
0449     .owner = THIS_MODULE,
0450 };
0451 
0452 static int __init amdtee_driver_init(void)
0453 {
0454     struct tee_device *teedev;
0455     struct tee_shm_pool *pool;
0456     struct amdtee *amdtee;
0457     int rc;
0458 
0459     rc = psp_check_tee_status();
0460     if (rc) {
0461         pr_err("amd-tee driver: tee not present\n");
0462         return rc;
0463     }
0464 
0465     drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL);
0466     if (!drv_data)
0467         return -ENOMEM;
0468 
0469     amdtee = kzalloc(sizeof(*amdtee), GFP_KERNEL);
0470     if (!amdtee) {
0471         rc = -ENOMEM;
0472         goto err_kfree_drv_data;
0473     }
0474 
0475     pool = amdtee_config_shm();
0476     if (IS_ERR(pool)) {
0477         pr_err("shared pool configuration error\n");
0478         rc = PTR_ERR(pool);
0479         goto err_kfree_amdtee;
0480     }
0481 
0482     teedev = tee_device_alloc(&amdtee_desc, NULL, pool, amdtee);
0483     if (IS_ERR(teedev)) {
0484         rc = PTR_ERR(teedev);
0485         goto err_free_pool;
0486     }
0487     amdtee->teedev = teedev;
0488 
0489     rc = tee_device_register(amdtee->teedev);
0490     if (rc)
0491         goto err_device_unregister;
0492 
0493     amdtee->pool = pool;
0494 
0495     drv_data->amdtee = amdtee;
0496 
0497     pr_info("amd-tee driver initialization successful\n");
0498     return 0;
0499 
0500 err_device_unregister:
0501     tee_device_unregister(amdtee->teedev);
0502 
0503 err_free_pool:
0504     tee_shm_pool_free(pool);
0505 
0506 err_kfree_amdtee:
0507     kfree(amdtee);
0508 
0509 err_kfree_drv_data:
0510     kfree(drv_data);
0511     drv_data = NULL;
0512 
0513     pr_err("amd-tee driver initialization failed\n");
0514     return rc;
0515 }
0516 module_init(amdtee_driver_init);
0517 
0518 static void __exit amdtee_driver_exit(void)
0519 {
0520     struct amdtee *amdtee;
0521 
0522     if (!drv_data || !drv_data->amdtee)
0523         return;
0524 
0525     amdtee = drv_data->amdtee;
0526 
0527     tee_device_unregister(amdtee->teedev);
0528     tee_shm_pool_free(amdtee->pool);
0529 }
0530 module_exit(amdtee_driver_exit);
0531 
0532 MODULE_AUTHOR(DRIVER_AUTHOR);
0533 MODULE_DESCRIPTION("AMD-TEE driver");
0534 MODULE_VERSION("1.0");
0535 MODULE_LICENSE("Dual MIT/GPL");