2 * Copyright (c) 2015, Linaro Limited
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
14 #include <linux/device.h>
15 #include <linux/dma-buf.h>
16 #include <linux/genalloc.h>
17 #include <linux/slab.h>
18 #include <linux/tee_drv.h>
19 #include "tee_private.h"
21 static int pool_op_gen_alloc(struct tee_shm_pool_mgr
*poolm
,
22 struct tee_shm
*shm
, size_t size
)
25 struct gen_pool
*genpool
= poolm
->private_data
;
26 size_t s
= roundup(size
, 1 << genpool
->min_alloc_order
);
28 va
= gen_pool_alloc(genpool
, s
);
32 memset((void *)va
, 0, s
);
33 shm
->kaddr
= (void *)va
;
34 shm
->paddr
= gen_pool_virt_to_phys(genpool
, va
);
39 static void pool_op_gen_free(struct tee_shm_pool_mgr
*poolm
,
42 gen_pool_free(poolm
->private_data
, (unsigned long)shm
->kaddr
,
47 static const struct tee_shm_pool_mgr_ops pool_ops_generic
= {
48 .alloc
= pool_op_gen_alloc
,
49 .free
= pool_op_gen_free
,
52 static void pool_res_mem_destroy(struct tee_shm_pool
*pool
)
54 gen_pool_destroy(pool
->private_mgr
.private_data
);
55 gen_pool_destroy(pool
->dma_buf_mgr
.private_data
);
58 static int pool_res_mem_mgr_init(struct tee_shm_pool_mgr
*mgr
,
59 struct tee_shm_pool_mem_info
*info
,
62 size_t page_mask
= PAGE_SIZE
- 1;
63 struct gen_pool
*genpool
= NULL
;
67 * Start and end must be page aligned
69 if ((info
->vaddr
& page_mask
) || (info
->paddr
& page_mask
) ||
70 (info
->size
& page_mask
))
73 genpool
= gen_pool_create(min_alloc_order
, -1);
77 gen_pool_set_algo(genpool
, gen_pool_best_fit
, NULL
);
78 rc
= gen_pool_add_virt(genpool
, info
->vaddr
, info
->paddr
, info
->size
,
81 gen_pool_destroy(genpool
);
85 mgr
->private_data
= genpool
;
86 mgr
->ops
= &pool_ops_generic
;
91 * tee_shm_pool_alloc_res_mem() - Create a shared memory pool from reserved
93 * @priv_info: Information for driver private shared memory pool
94 * @dmabuf_info: Information for dma-buf shared memory pool
96 * Start and end of pools will must be page aligned.
98 * Allocation with the flag TEE_SHM_DMA_BUF set will use the range supplied
99 * in @dmabuf, others will use the range provided by @priv.
101 * @returns pointer to a 'struct tee_shm_pool' or an ERR_PTR on failure.
103 struct tee_shm_pool
*
104 tee_shm_pool_alloc_res_mem(struct tee_shm_pool_mem_info
*priv_info
,
105 struct tee_shm_pool_mem_info
*dmabuf_info
)
107 struct tee_shm_pool
*pool
= NULL
;
110 pool
= kzalloc(sizeof(*pool
), GFP_KERNEL
);
117 * Create the pool for driver private shared memory
119 ret
= pool_res_mem_mgr_init(&pool
->private_mgr
, priv_info
,
120 3 /* 8 byte aligned */);
125 * Create the pool for dma_buf shared memory
127 ret
= pool_res_mem_mgr_init(&pool
->dma_buf_mgr
, dmabuf_info
,
132 pool
->destroy
= pool_res_mem_destroy
;
136 pr_err("%s: can't allocate memory for res_mem shared memory pool\n", __func__
);
137 if (pool
&& pool
->private_mgr
.private_data
)
138 gen_pool_destroy(pool
->private_mgr
.private_data
);
142 EXPORT_SYMBOL_GPL(tee_shm_pool_alloc_res_mem
);
145 * tee_shm_pool_free() - Free a shared memory pool
146 * @pool: The shared memory pool to free
148 * There must be no remaining shared memory allocated from this pool when
149 * this function is called.
151 void tee_shm_pool_free(struct tee_shm_pool
*pool
)
156 EXPORT_SYMBOL_GPL(tee_shm_pool_free
);