1// SPDX-License-Identifier: MIT 2/* 3 * Copyright 2019 Advanced Micro Devices, Inc. 4 */ 5 6#include <linux/slab.h> 7#include <linux/tee_drv.h> 8#include <linux/psp-sev.h> 9#include "amdtee_private.h" 10 11static int pool_op_alloc(struct tee_shm_pool_mgr *poolm, struct tee_shm *shm, 12 size_t size) 13{ 14 unsigned int order = get_order(size); 15 unsigned long va; 16 int rc; 17 18 va = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order); 19 if (!va) 20 return -ENOMEM; 21 22 shm->kaddr = (void *)va; 23 shm->paddr = __psp_pa((void *)va); 24 shm->size = PAGE_SIZE << order; 25 26 /* Map the allocated memory in to TEE */ 27 rc = amdtee_map_shmem(shm); 28 if (rc) { 29 free_pages(va, order); 30 shm->kaddr = NULL; 31 return rc; 32 } 33 34 return 0; 35} 36 37static void pool_op_free(struct tee_shm_pool_mgr *poolm, struct tee_shm *shm) 38{ 39 /* Unmap the shared memory from TEE */ 40 amdtee_unmap_shmem(shm); 41 free_pages((unsigned long)shm->kaddr, get_order(shm->size)); 42 shm->kaddr = NULL; 43} 44 45static void pool_op_destroy_poolmgr(struct tee_shm_pool_mgr *poolm) 46{ 47 kfree(poolm); 48} 49 50static const struct tee_shm_pool_mgr_ops pool_ops = { 51 .alloc = pool_op_alloc, 52 .free = pool_op_free, 53 .destroy_poolmgr = pool_op_destroy_poolmgr, 54}; 55 56static struct tee_shm_pool_mgr *pool_mem_mgr_alloc(void) 57{ 58 struct tee_shm_pool_mgr *mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); 59 60 if (!mgr) 61 return ERR_PTR(-ENOMEM); 62 63 mgr->ops = &pool_ops; 64 65 return mgr; 66} 67 68struct tee_shm_pool *amdtee_config_shm(void) 69{ 70 struct tee_shm_pool_mgr *priv_mgr; 71 struct tee_shm_pool_mgr *dmabuf_mgr; 72 void *rc; 73 74 rc = pool_mem_mgr_alloc(); 75 if (IS_ERR(rc)) 76 return rc; 77 priv_mgr = rc; 78 79 rc = pool_mem_mgr_alloc(); 80 if (IS_ERR(rc)) { 81 tee_shm_pool_mgr_destroy(priv_mgr); 82 return rc; 83 } 84 dmabuf_mgr = rc; 85 86 rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr); 87 if (IS_ERR(rc)) { 88 tee_shm_pool_mgr_destroy(priv_mgr); 89 tee_shm_pool_mgr_destroy(dmabuf_mgr); 90 } 91 92 return rc; 93} 94