1/* 2 * Copyright (c) 2015, Linaro Limited 3 * Copyright (c) 2017, EPAM Systems 4 * 5 * This software is licensed under the terms of the GNU General Public 6 * License version 2, as published by the Free Software Foundation, and 7 * may be copied, distributed, and modified under those terms. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 */ 15#include <linux/device.h> 16#include <linux/dma-buf.h> 17#include <linux/genalloc.h> 18#include <linux/slab.h> 19#include <linux/tee_drv.h> 20#include "optee_private.h" 21#include "optee_smc.h" 22#include "shm_pool.h" 23 24static int pool_op_alloc(struct tee_shm_pool_mgr *poolm, 25 struct tee_shm *shm, size_t size) 26{ 27 unsigned int order = get_order(size); 28 struct page *page; 29 30 page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order); 31 if (!page) 32 return -ENOMEM; 33 34 shm->kaddr = page_address(page); 35 shm->paddr = page_to_phys(page); 36 shm->size = PAGE_SIZE << order; 37 38 return 0; 39} 40 41static void pool_op_free(struct tee_shm_pool_mgr *poolm, 42 struct tee_shm *shm) 43{ 44 free_pages((unsigned long)shm->kaddr, get_order(shm->size)); 45 shm->kaddr = NULL; 46} 47 48static void pool_op_destroy_poolmgr(struct tee_shm_pool_mgr *poolm) 49{ 50 kfree(poolm); 51} 52 53static const struct tee_shm_pool_mgr_ops pool_ops = { 54 .alloc = pool_op_alloc, 55 .free = pool_op_free, 56 .destroy_poolmgr = pool_op_destroy_poolmgr, 57}; 58 59/** 60 * optee_shm_pool_alloc_pages() - create page-based allocator pool 61 * 62 * This pool is used when OP-TEE supports dymanic SHM. In this case 63 * command buffers and such are allocated from kernel's own memory. 64 */ 65struct tee_shm_pool_mgr *optee_shm_pool_alloc_pages(void) 66{ 67 struct tee_shm_pool_mgr *mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); 68 69 if (!mgr) 70 return ERR_PTR(-ENOMEM); 71 72 mgr->ops = &pool_ops; 73 74 return mgr; 75} 76