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 void pool_op_gen_destroy_poolmgr(struct tee_shm_pool_mgr
*poolm
)
49 gen_pool_destroy(poolm
->private_data
);
53 static const struct tee_shm_pool_mgr_ops pool_ops_generic
= {
54 .alloc
= pool_op_gen_alloc
,
55 .free
= pool_op_gen_free
,
56 .destroy_poolmgr
= pool_op_gen_destroy_poolmgr
,
60 * tee_shm_pool_alloc_res_mem() - Create a shared memory pool from reserved
62 * @priv_info: Information for driver private shared memory pool
63 * @dmabuf_info: Information for dma-buf shared memory pool
65 * Start and end of pools will must be page aligned.
67 * Allocation with the flag TEE_SHM_DMA_BUF set will use the range supplied
68 * in @dmabuf, others will use the range provided by @priv.
70 * @returns pointer to a 'struct tee_shm_pool' or an ERR_PTR on failure.
73 tee_shm_pool_alloc_res_mem(struct tee_shm_pool_mem_info
*priv_info
,
74 struct tee_shm_pool_mem_info
*dmabuf_info
)
76 struct tee_shm_pool_mgr
*priv_mgr
;
77 struct tee_shm_pool_mgr
*dmabuf_mgr
;
81 * Create the pool for driver private shared memory
83 rc
= tee_shm_pool_mgr_alloc_res_mem(priv_info
->vaddr
, priv_info
->paddr
,
85 3 /* 8 byte aligned */);
91 * Create the pool for dma_buf shared memory
93 rc
= tee_shm_pool_mgr_alloc_res_mem(dmabuf_info
->vaddr
,
95 dmabuf_info
->size
, PAGE_SHIFT
);
97 goto err_free_priv_mgr
;
100 rc
= tee_shm_pool_alloc(priv_mgr
, dmabuf_mgr
);
102 goto err_free_dmabuf_mgr
;
107 tee_shm_pool_mgr_destroy(dmabuf_mgr
);
109 tee_shm_pool_mgr_destroy(priv_mgr
);
113 EXPORT_SYMBOL_GPL(tee_shm_pool_alloc_res_mem
);
115 struct tee_shm_pool_mgr
*tee_shm_pool_mgr_alloc_res_mem(unsigned long vaddr
,
120 const size_t page_mask
= PAGE_SIZE
- 1;
121 struct tee_shm_pool_mgr
*mgr
;
124 /* Start and end must be page aligned */
125 if (vaddr
& page_mask
|| paddr
& page_mask
|| size
& page_mask
)
126 return ERR_PTR(-EINVAL
);
128 mgr
= kzalloc(sizeof(*mgr
), GFP_KERNEL
);
130 return ERR_PTR(-ENOMEM
);
132 mgr
->private_data
= gen_pool_create(min_alloc_order
, -1);
133 if (!mgr
->private_data
) {
138 gen_pool_set_algo(mgr
->private_data
, gen_pool_best_fit
, NULL
);
139 rc
= gen_pool_add_virt(mgr
->private_data
, vaddr
, paddr
, size
, -1);
141 gen_pool_destroy(mgr
->private_data
);
145 mgr
->ops
= &pool_ops_generic
;
153 EXPORT_SYMBOL_GPL(tee_shm_pool_mgr_alloc_res_mem
);
155 static bool check_mgr_ops(struct tee_shm_pool_mgr
*mgr
)
157 return mgr
&& mgr
->ops
&& mgr
->ops
->alloc
&& mgr
->ops
->free
&&
158 mgr
->ops
->destroy_poolmgr
;
161 struct tee_shm_pool
*tee_shm_pool_alloc(struct tee_shm_pool_mgr
*priv_mgr
,
162 struct tee_shm_pool_mgr
*dmabuf_mgr
)
164 struct tee_shm_pool
*pool
;
166 if (!check_mgr_ops(priv_mgr
) || !check_mgr_ops(dmabuf_mgr
))
167 return ERR_PTR(-EINVAL
);
169 pool
= kzalloc(sizeof(*pool
), GFP_KERNEL
);
171 return ERR_PTR(-ENOMEM
);
173 pool
->private_mgr
= priv_mgr
;
174 pool
->dma_buf_mgr
= dmabuf_mgr
;
178 EXPORT_SYMBOL_GPL(tee_shm_pool_alloc
);
181 * tee_shm_pool_free() - Free a shared memory pool
182 * @pool: The shared memory pool to free
184 * There must be no remaining shared memory allocated from this pool when
185 * this function is called.
187 void tee_shm_pool_free(struct tee_shm_pool
*pool
)
189 if (pool
->private_mgr
)
190 tee_shm_pool_mgr_destroy(pool
->private_mgr
);
191 if (pool
->dma_buf_mgr
)
192 tee_shm_pool_mgr_destroy(pool
->dma_buf_mgr
);
195 EXPORT_SYMBOL_GPL(tee_shm_pool_free
);