18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: MIT 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright 2019 Advanced Micro Devices, Inc. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#include <linux/slab.h> 78c2ecf20Sopenharmony_ci#include <linux/tee_drv.h> 88c2ecf20Sopenharmony_ci#include <linux/psp-sev.h> 98c2ecf20Sopenharmony_ci#include "amdtee_private.h" 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_cistatic int pool_op_alloc(struct tee_shm_pool_mgr *poolm, struct tee_shm *shm, 128c2ecf20Sopenharmony_ci size_t size) 138c2ecf20Sopenharmony_ci{ 148c2ecf20Sopenharmony_ci unsigned int order = get_order(size); 158c2ecf20Sopenharmony_ci unsigned long va; 168c2ecf20Sopenharmony_ci int rc; 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci va = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order); 198c2ecf20Sopenharmony_ci if (!va) 208c2ecf20Sopenharmony_ci return -ENOMEM; 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci shm->kaddr = (void *)va; 238c2ecf20Sopenharmony_ci shm->paddr = __psp_pa((void *)va); 248c2ecf20Sopenharmony_ci shm->size = PAGE_SIZE << order; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci /* Map the allocated memory in to TEE */ 278c2ecf20Sopenharmony_ci rc = amdtee_map_shmem(shm); 288c2ecf20Sopenharmony_ci if (rc) { 298c2ecf20Sopenharmony_ci free_pages(va, order); 308c2ecf20Sopenharmony_ci shm->kaddr = NULL; 318c2ecf20Sopenharmony_ci return rc; 328c2ecf20Sopenharmony_ci } 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci return 0; 358c2ecf20Sopenharmony_ci} 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_cistatic void pool_op_free(struct tee_shm_pool_mgr *poolm, struct tee_shm *shm) 388c2ecf20Sopenharmony_ci{ 398c2ecf20Sopenharmony_ci /* Unmap the shared memory from TEE */ 408c2ecf20Sopenharmony_ci amdtee_unmap_shmem(shm); 418c2ecf20Sopenharmony_ci free_pages((unsigned long)shm->kaddr, get_order(shm->size)); 428c2ecf20Sopenharmony_ci shm->kaddr = NULL; 438c2ecf20Sopenharmony_ci} 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_cistatic void pool_op_destroy_poolmgr(struct tee_shm_pool_mgr *poolm) 468c2ecf20Sopenharmony_ci{ 478c2ecf20Sopenharmony_ci kfree(poolm); 488c2ecf20Sopenharmony_ci} 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_cistatic const struct tee_shm_pool_mgr_ops pool_ops = { 518c2ecf20Sopenharmony_ci .alloc = pool_op_alloc, 528c2ecf20Sopenharmony_ci .free = pool_op_free, 538c2ecf20Sopenharmony_ci .destroy_poolmgr = pool_op_destroy_poolmgr, 548c2ecf20Sopenharmony_ci}; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cistatic struct tee_shm_pool_mgr *pool_mem_mgr_alloc(void) 578c2ecf20Sopenharmony_ci{ 588c2ecf20Sopenharmony_ci struct tee_shm_pool_mgr *mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci if (!mgr) 618c2ecf20Sopenharmony_ci return ERR_PTR(-ENOMEM); 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci mgr->ops = &pool_ops; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci return mgr; 668c2ecf20Sopenharmony_ci} 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_cistruct tee_shm_pool *amdtee_config_shm(void) 698c2ecf20Sopenharmony_ci{ 708c2ecf20Sopenharmony_ci struct tee_shm_pool_mgr *priv_mgr; 718c2ecf20Sopenharmony_ci struct tee_shm_pool_mgr *dmabuf_mgr; 728c2ecf20Sopenharmony_ci void *rc; 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci rc = pool_mem_mgr_alloc(); 758c2ecf20Sopenharmony_ci if (IS_ERR(rc)) 768c2ecf20Sopenharmony_ci return rc; 778c2ecf20Sopenharmony_ci priv_mgr = rc; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci rc = pool_mem_mgr_alloc(); 808c2ecf20Sopenharmony_ci if (IS_ERR(rc)) { 818c2ecf20Sopenharmony_ci tee_shm_pool_mgr_destroy(priv_mgr); 828c2ecf20Sopenharmony_ci return rc; 838c2ecf20Sopenharmony_ci } 848c2ecf20Sopenharmony_ci dmabuf_mgr = rc; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr); 878c2ecf20Sopenharmony_ci if (IS_ERR(rc)) { 888c2ecf20Sopenharmony_ci tee_shm_pool_mgr_destroy(priv_mgr); 898c2ecf20Sopenharmony_ci tee_shm_pool_mgr_destroy(dmabuf_mgr); 908c2ecf20Sopenharmony_ci } 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci return rc; 938c2ecf20Sopenharmony_ci} 94