// SPDX-License-Identifier: MIT /* * Copyright 2019 Advanced Micro Devices, Inc. */ #include #include #include #include "amdtee_private.h" static int pool_op_alloc(struct tee_shm_pool_mgr *poolm, struct tee_shm *shm, size_t size) { unsigned int order = get_order(size); unsigned long va; int rc; va = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order); if (!va) return -ENOMEM; shm->kaddr = (void *)va; shm->paddr = __psp_pa((void *)va); shm->size = PAGE_SIZE << order; /* Map the allocated memory in to TEE */ rc = amdtee_map_shmem(shm); if (rc) { free_pages(va, order); shm->kaddr = NULL; return rc; } return 0; } static void pool_op_free(struct tee_shm_pool_mgr *poolm, struct tee_shm *shm) { /* Unmap the shared memory from TEE */ amdtee_unmap_shmem(shm); free_pages((unsigned long)shm->kaddr, get_order(shm->size)); shm->kaddr = NULL; } static void pool_op_destroy_poolmgr(struct tee_shm_pool_mgr *poolm) { kfree(poolm); } static const struct tee_shm_pool_mgr_ops pool_ops = { .alloc = pool_op_alloc, .free = pool_op_free, .destroy_poolmgr = pool_op_destroy_poolmgr, }; static struct tee_shm_pool_mgr *pool_mem_mgr_alloc(void) { struct tee_shm_pool_mgr *mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); if (!mgr) return ERR_PTR(-ENOMEM); mgr->ops = &pool_ops; return mgr; } struct tee_shm_pool *amdtee_config_shm(void) { struct tee_shm_pool_mgr *priv_mgr; struct tee_shm_pool_mgr *dmabuf_mgr; void *rc; rc = pool_mem_mgr_alloc(); if (IS_ERR(rc)) return rc; priv_mgr = rc; rc = pool_mem_mgr_alloc(); 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; }