Merge tag 'arm-drivers-5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
[linux-2.6-microblaze.git] / drivers / tee / optee / smc_abi.c
index c517d31..67b7f7d 100644 (file)
  * 6. Driver initialization.
  */
 
-#define OPTEE_SHM_NUM_PRIV_PAGES       CONFIG_OPTEE_SHM_NUM_PRIV_PAGES
+/*
+ * A typical OP-TEE private shm allocation is 224 bytes (argument struct
+ * with 6 parameters, needed for open session). So with an alignment of 512
+ * we'll waste a bit more than 50%. However, it's only expected that we'll
+ * have a handful of these structs allocated at a time. Most memory will
+ * be allocated aligned to the page size, So all in all this should scale
+ * up and down quite well.
+ */
+#define OPTEE_MIN_STATIC_POOL_ALIGN    9 /* 512 bytes aligned */
 
 /*
  * 1. Convert between struct tee_param and struct optee_msg_param
@@ -220,7 +228,7 @@ static int optee_to_msg_param(struct optee *optee,
                case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
                case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
                case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
-                       if (tee_shm_is_registered(p->u.memref.shm))
+                       if (tee_shm_is_dynamic(p->u.memref.shm))
                                rc = to_msg_param_reg_mem(mp, p);
                        else
                                rc = to_msg_param_tmp_mem(mp, p);
@@ -522,38 +530,38 @@ static int optee_shm_unregister_supp(struct tee_context *ctx,
  * The main function is optee_shm_pool_alloc_pages().
  */
 
-static int pool_op_alloc(struct tee_shm_pool_mgr *poolm,
-                        struct tee_shm *shm, size_t size)
+static int pool_op_alloc(struct tee_shm_pool *pool,
+                        struct tee_shm *shm, size_t size, size_t align)
 {
        /*
         * Shared memory private to the OP-TEE driver doesn't need
         * to be registered with OP-TEE.
         */
        if (shm->flags & TEE_SHM_PRIV)
-               return optee_pool_op_alloc_helper(poolm, shm, size, NULL);
+               return optee_pool_op_alloc_helper(pool, shm, size, align, NULL);
 
-       return optee_pool_op_alloc_helper(poolm, shm, size, optee_shm_register);
+       return optee_pool_op_alloc_helper(pool, shm, size, align,
+                                         optee_shm_register);
 }
 
-static void pool_op_free(struct tee_shm_pool_mgr *poolm,
+static void pool_op_free(struct tee_shm_pool *pool,
                         struct tee_shm *shm)
 {
        if (!(shm->flags & TEE_SHM_PRIV))
-               optee_shm_unregister(shm->ctx, shm);
-
-       free_pages((unsigned long)shm->kaddr, get_order(shm->size));
-       shm->kaddr = NULL;
+               optee_pool_op_free_helper(pool, shm, optee_shm_unregister);
+       else
+               optee_pool_op_free_helper(pool, shm, NULL);
 }
 
-static void pool_op_destroy_poolmgr(struct tee_shm_pool_mgr *poolm)
+static void pool_op_destroy_pool(struct tee_shm_pool *pool)
 {
-       kfree(poolm);
+       kfree(pool);
 }
 
-static const struct tee_shm_pool_mgr_ops pool_ops = {
+static const struct tee_shm_pool_ops pool_ops = {
        .alloc = pool_op_alloc,
        .free = pool_op_free,
-       .destroy_poolmgr = pool_op_destroy_poolmgr,
+       .destroy_pool = pool_op_destroy_pool,
 };
 
 /**
@@ -562,16 +570,16 @@ static const struct tee_shm_pool_mgr_ops pool_ops = {
  * This pool is used when OP-TEE supports dymanic SHM. In this case
  * command buffers and such are allocated from kernel's own memory.
  */
-static struct tee_shm_pool_mgr *optee_shm_pool_alloc_pages(void)
+static struct tee_shm_pool *optee_shm_pool_alloc_pages(void)
 {
-       struct tee_shm_pool_mgr *mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
+       struct tee_shm_pool *pool = kzalloc(sizeof(*pool), GFP_KERNEL);
 
-       if (!mgr)
+       if (!pool)
                return ERR_PTR(-ENOMEM);
 
-       mgr->ops = &pool_ops;
+       pool->ops = &pool_ops;
 
-       return mgr;
+       return pool;
 }
 
 /*
@@ -642,8 +650,7 @@ static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
                shm = optee_rpc_cmd_alloc_suppl(ctx, sz);
                break;
        case OPTEE_RPC_SHM_TYPE_KERNEL:
-               shm = tee_shm_alloc(optee->ctx, sz,
-                                   TEE_SHM_MAPPED | TEE_SHM_PRIV);
+               shm = tee_shm_alloc_priv_buf(optee->ctx, sz);
                break;
        default:
                arg->ret = TEEC_ERROR_BAD_PARAMETERS;
@@ -662,7 +669,7 @@ static void handle_rpc_func_cmd_shm_alloc(struct tee_context *ctx,
 
        sz = tee_shm_get_size(shm);
 
-       if (tee_shm_is_registered(shm)) {
+       if (tee_shm_is_dynamic(shm)) {
                struct page **pages;
                u64 *pages_list;
                size_t page_num;
@@ -768,8 +775,7 @@ static void optee_handle_rpc(struct tee_context *ctx,
 
        switch (OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0)) {
        case OPTEE_SMC_RPC_FUNC_ALLOC:
-               shm = tee_shm_alloc(optee->ctx, param->a1,
-                                   TEE_SHM_MAPPED | TEE_SHM_PRIV);
+               shm = tee_shm_alloc_priv_buf(optee->ctx, param->a1);
                if (!IS_ERR(shm) && !tee_shm_get_pa(shm, 0, &pa)) {
                        reg_pair_from_64(&param->a1, &param->a2, pa);
                        reg_pair_from_64(&param->a4, &param->a5,
@@ -1143,33 +1149,6 @@ static bool optee_msg_exchange_capabilities(optee_invoke_fn *invoke_fn,
        return true;
 }
 
-static struct tee_shm_pool *optee_config_dyn_shm(void)
-{
-       struct tee_shm_pool_mgr *priv_mgr;
-       struct tee_shm_pool_mgr *dmabuf_mgr;
-       void *rc;
-
-       rc = optee_shm_pool_alloc_pages();
-       if (IS_ERR(rc))
-               return rc;
-       priv_mgr = rc;
-
-       rc = optee_shm_pool_alloc_pages();
-       if (IS_ERR(rc)) {
-               tee_shm_pool_mgr_destroy(priv_mgr);
-               return rc;
-       }
-       dmabuf_mgr = rc;
-
-       rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr);
-       if (IS_ERR(rc)) {
-               tee_shm_pool_mgr_destroy(priv_mgr);
-               tee_shm_pool_mgr_destroy(dmabuf_mgr);
-       }
-
-       return rc;
-}
-
 static struct tee_shm_pool *
 optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm)
 {
@@ -1183,10 +1162,7 @@ optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm)
        phys_addr_t begin;
        phys_addr_t end;
        void *va;
-       struct tee_shm_pool_mgr *priv_mgr;
-       struct tee_shm_pool_mgr *dmabuf_mgr;
        void *rc;
-       const int sz = OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE;
 
        invoke_fn(OPTEE_SMC_GET_SHM_CONFIG, 0, 0, 0, 0, 0, 0, 0, &res.smccc);
        if (res.result.status != OPTEE_SMC_RETURN_OK) {
@@ -1204,11 +1180,6 @@ optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm)
        paddr = begin;
        size = end - begin;
 
-       if (size < 2 * OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE) {
-               pr_err("too small shared memory area\n");
-               return ERR_PTR(-EINVAL);
-       }
-
        va = memremap(paddr, size, MEMREMAP_WB);
        if (!va) {
                pr_err("shared memory ioremap failed\n");
@@ -1216,35 +1187,13 @@ optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm)
        }
        vaddr = (unsigned long)va;
 
-       rc = tee_shm_pool_mgr_alloc_res_mem(vaddr, paddr, sz,
-                                           3 /* 8 bytes aligned */);
+       rc = tee_shm_pool_alloc_res_mem(vaddr, paddr, size,
+                                       OPTEE_MIN_STATIC_POOL_ALIGN);
        if (IS_ERR(rc))
-               goto err_memunmap;
-       priv_mgr = rc;
-
-       vaddr += sz;
-       paddr += sz;
-       size -= sz;
-
-       rc = tee_shm_pool_mgr_alloc_res_mem(vaddr, paddr, size, PAGE_SHIFT);
-       if (IS_ERR(rc))
-               goto err_free_priv_mgr;
-       dmabuf_mgr = rc;
-
-       rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr);
-       if (IS_ERR(rc))
-               goto err_free_dmabuf_mgr;
-
-       *memremaped_shm = va;
-
-       return rc;
+               memunmap(va);
+       else
+               *memremaped_shm = va;
 
-err_free_dmabuf_mgr:
-       tee_shm_pool_mgr_destroy(dmabuf_mgr);
-err_free_priv_mgr:
-       tee_shm_pool_mgr_destroy(priv_mgr);
-err_memunmap:
-       memunmap(va);
        return rc;
 }
 
@@ -1366,7 +1315,7 @@ static int optee_probe(struct platform_device *pdev)
         * Try to use dynamic shared memory if possible
         */
        if (sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
-               pool = optee_config_dyn_shm();
+               pool = optee_shm_pool_alloc_pages();
 
        /*
         * If dynamic shared memory is not available or failed - try static one