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.h> 9 #include "amdtee_private.h" 10 11 static int pool_op_alloc(struct tee_shm_pool *pool, struct tee_shm *shm, 12 size_t size, size_t align) 13 { 14 unsigned int order = get_order(size); 15 unsigned long va; 16 int rc; 17 18 /* 19 * Ignore alignment since this is already going to be page aligned 20 * and there's no need for any larger alignment. 21 */ 22 va = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order); 23 if (!va) 24 return -ENOMEM; 25 26 shm->kaddr = (void *)va; 27 shm->paddr = __psp_pa((void *)va); 28 shm->size = PAGE_SIZE << order; 29 30 /* Map the allocated memory in to TEE */ 31 rc = amdtee_map_shmem(shm); 32 if (rc) { 33 free_pages(va, order); 34 shm->kaddr = NULL; 35 return rc; 36 } 37 38 return 0; 39 } 40 41 static void pool_op_free(struct tee_shm_pool *pool, struct tee_shm *shm) 42 { 43 /* Unmap the shared memory from TEE */ 44 amdtee_unmap_shmem(shm); 45 free_pages((unsigned long)shm->kaddr, get_order(shm->size)); 46 shm->kaddr = NULL; 47 } 48 49 static void pool_op_destroy_pool(struct tee_shm_pool *pool) 50 { 51 kfree(pool); 52 } 53 54 static const struct tee_shm_pool_ops pool_ops = { 55 .alloc = pool_op_alloc, 56 .free = pool_op_free, 57 .destroy_pool = pool_op_destroy_pool, 58 }; 59 60 struct tee_shm_pool *amdtee_config_shm(void) 61 { 62 struct tee_shm_pool *pool = kzalloc(sizeof(*pool), GFP_KERNEL); 63 64 if (!pool) 65 return ERR_PTR(-ENOMEM); 66 67 pool->ops = &pool_ops; 68 69 return pool; 70 } 71