2323static void tee_shm_release (struct tee_shm * shm )
2424{
2525 struct tee_device * teedev = shm -> teedev ;
26- struct tee_shm_pool_mgr * poolm ;
2726
2827 mutex_lock (& teedev -> mutex );
2928 idr_remove (& teedev -> idr , shm -> id );
3029 if (shm -> ctx )
3130 list_del (& shm -> link );
3231 mutex_unlock (& teedev -> mutex );
3332
34- if (shm -> flags & TEE_SHM_DMA_BUF )
35- poolm = teedev -> pool -> dma_buf_mgr ;
36- else
37- poolm = teedev -> pool -> private_mgr ;
33+ if (shm -> flags & TEE_SHM_POOL ) {
34+ struct tee_shm_pool_mgr * poolm ;
35+
36+ if (shm -> flags & TEE_SHM_DMA_BUF )
37+ poolm = teedev -> pool -> dma_buf_mgr ;
38+ else
39+ poolm = teedev -> pool -> private_mgr ;
40+
41+ poolm -> ops -> free (poolm , shm );
42+ } else if (shm -> flags & TEE_SHM_REGISTER ) {
43+ size_t n ;
44+ int rc = teedev -> desc -> ops -> shm_unregister (shm -> ctx , shm );
45+
46+ if (rc )
47+ dev_err (teedev -> dev .parent ,
48+ "unregister shm %p failed: %d" , shm , rc );
49+
50+ for (n = 0 ; n < shm -> num_pages ; n ++ )
51+ put_page (shm -> pages [n ]);
52+
53+ kfree (shm -> pages );
54+ }
3855
39- poolm -> ops -> free (poolm , shm );
4056 kfree (shm );
4157
4258 tee_device_put (teedev );
@@ -76,6 +92,10 @@ static int tee_shm_op_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
7692 struct tee_shm * shm = dmabuf -> priv ;
7793 size_t size = vma -> vm_end - vma -> vm_start ;
7894
95+ /* Refuse sharing shared memory provided by application */
96+ if (shm -> flags & TEE_SHM_REGISTER )
97+ return - EINVAL ;
98+
7999 return remap_pfn_range (vma , vma -> vm_start , shm -> paddr >> PAGE_SHIFT ,
80100 size , vma -> vm_page_prot );
81101}
@@ -89,26 +109,20 @@ static const struct dma_buf_ops tee_shm_dma_buf_ops = {
89109 .mmap = tee_shm_op_mmap ,
90110};
91111
92- /**
93- * tee_shm_alloc() - Allocate shared memory
94- * @ctx: Context that allocates the shared memory
95- * @size: Requested size of shared memory
96- * @flags: Flags setting properties for the requested shared memory.
97- *
98- * Memory allocated as global shared memory is automatically freed when the
99- * TEE file pointer is closed. The @flags field uses the bits defined by
100- * TEE_SHM_* in <linux/tee_drv.h>. TEE_SHM_MAPPED must currently always be
101- * set. If TEE_SHM_DMA_BUF global shared memory will be allocated and
102- * associated with a dma-buf handle, else driver private memory.
103- */
104- struct tee_shm * tee_shm_alloc (struct tee_context * ctx , size_t size , u32 flags )
112+ struct tee_shm * __tee_shm_alloc (struct tee_context * ctx ,
113+ struct tee_device * teedev ,
114+ size_t size , u32 flags )
105115{
106- struct tee_device * teedev = ctx -> teedev ;
107116 struct tee_shm_pool_mgr * poolm = NULL ;
108117 struct tee_shm * shm ;
109118 void * ret ;
110119 int rc ;
111120
121+ if (ctx && ctx -> teedev != teedev ) {
122+ dev_err (teedev -> dev .parent , "ctx and teedev mismatch\n" );
123+ return ERR_PTR (- EINVAL );
124+ }
125+
112126 if (!(flags & TEE_SHM_MAPPED )) {
113127 dev_err (teedev -> dev .parent ,
114128 "only mapped allocations supported\n" );
@@ -135,7 +149,7 @@ struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags)
135149 goto err_dev_put ;
136150 }
137151
138- shm -> flags = flags ;
152+ shm -> flags = flags | TEE_SHM_POOL ;
139153 shm -> teedev = teedev ;
140154 shm -> ctx = ctx ;
141155 if (flags & TEE_SHM_DMA_BUF )
@@ -171,9 +185,12 @@ struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags)
171185 goto err_rem ;
172186 }
173187 }
174- mutex_lock (& teedev -> mutex );
175- list_add_tail (& shm -> link , & ctx -> list_shm );
176- mutex_unlock (& teedev -> mutex );
188+
189+ if (ctx ) {
190+ mutex_lock (& teedev -> mutex );
191+ list_add_tail (& shm -> link , & ctx -> list_shm );
192+ mutex_unlock (& teedev -> mutex );
193+ }
177194
178195 return shm ;
179196err_rem :
@@ -188,19 +205,150 @@ struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags)
188205 tee_device_put (teedev );
189206 return ret ;
190207}
208+
209+ /**
210+ * tee_shm_alloc() - Allocate shared memory
211+ * @ctx: Context that allocates the shared memory
212+ * @size: Requested size of shared memory
213+ * @flags: Flags setting properties for the requested shared memory.
214+ *
215+ * Memory allocated as global shared memory is automatically freed when the
216+ * TEE file pointer is closed. The @flags field uses the bits defined by
217+ * TEE_SHM_* in <linux/tee_drv.h>. TEE_SHM_MAPPED must currently always be
218+ * set. If TEE_SHM_DMA_BUF global shared memory will be allocated and
219+ * associated with a dma-buf handle, else driver private memory.
220+ */
221+ struct tee_shm * tee_shm_alloc (struct tee_context * ctx , size_t size , u32 flags )
222+ {
223+ return __tee_shm_alloc (ctx , ctx -> teedev , size , flags );
224+ }
191225EXPORT_SYMBOL_GPL (tee_shm_alloc );
192226
227+ struct tee_shm * tee_shm_priv_alloc (struct tee_device * teedev , size_t size )
228+ {
229+ return __tee_shm_alloc (NULL , teedev , size , TEE_SHM_MAPPED );
230+ }
231+ EXPORT_SYMBOL_GPL (tee_shm_priv_alloc );
232+
233+ struct tee_shm * tee_shm_register (struct tee_context * ctx , unsigned long addr ,
234+ size_t length , u32 flags )
235+ {
236+ struct tee_device * teedev = ctx -> teedev ;
237+ const u32 req_flags = TEE_SHM_DMA_BUF | TEE_SHM_USER_MAPPED ;
238+ struct tee_shm * shm ;
239+ void * ret ;
240+ int rc ;
241+ int num_pages ;
242+ unsigned long start ;
243+
244+ if (flags != req_flags )
245+ return ERR_PTR (- ENOTSUPP );
246+
247+ if (!tee_device_get (teedev ))
248+ return ERR_PTR (- EINVAL );
249+
250+ if (!teedev -> desc -> ops -> shm_register ||
251+ !teedev -> desc -> ops -> shm_unregister ) {
252+ tee_device_put (teedev );
253+ return ERR_PTR (- ENOTSUPP );
254+ }
255+
256+ shm = kzalloc (sizeof (* shm ), GFP_KERNEL );
257+ if (!shm ) {
258+ ret = ERR_PTR (- ENOMEM );
259+ goto err ;
260+ }
261+
262+ shm -> flags = flags | TEE_SHM_REGISTER ;
263+ shm -> teedev = teedev ;
264+ shm -> ctx = ctx ;
265+ shm -> id = -1 ;
266+ start = rounddown (addr , PAGE_SIZE );
267+ shm -> offset = addr - start ;
268+ shm -> size = length ;
269+ num_pages = (roundup (addr + length , PAGE_SIZE ) - start ) / PAGE_SIZE ;
270+ shm -> pages = kcalloc (num_pages , sizeof (* shm -> pages ), GFP_KERNEL );
271+ if (!shm -> pages ) {
272+ ret = ERR_PTR (- ENOMEM );
273+ goto err ;
274+ }
275+
276+ rc = get_user_pages_fast (start , num_pages , 1 , shm -> pages );
277+ if (rc > 0 )
278+ shm -> num_pages = rc ;
279+ if (rc != num_pages ) {
280+ if (rc > 0 )
281+ rc = - ENOMEM ;
282+ ret = ERR_PTR (rc );
283+ goto err ;
284+ }
285+
286+ mutex_lock (& teedev -> mutex );
287+ shm -> id = idr_alloc (& teedev -> idr , shm , 1 , 0 , GFP_KERNEL );
288+ mutex_unlock (& teedev -> mutex );
289+
290+ if (shm -> id < 0 ) {
291+ ret = ERR_PTR (shm -> id );
292+ goto err ;
293+ }
294+
295+ rc = teedev -> desc -> ops -> shm_register (ctx , shm , shm -> pages ,
296+ shm -> num_pages );
297+ if (rc ) {
298+ ret = ERR_PTR (rc );
299+ goto err ;
300+ }
301+
302+ if (flags & TEE_SHM_DMA_BUF ) {
303+ DEFINE_DMA_BUF_EXPORT_INFO (exp_info );
304+
305+ exp_info .ops = & tee_shm_dma_buf_ops ;
306+ exp_info .size = shm -> size ;
307+ exp_info .flags = O_RDWR ;
308+ exp_info .priv = shm ;
309+
310+ shm -> dmabuf = dma_buf_export (& exp_info );
311+ if (IS_ERR (shm -> dmabuf )) {
312+ ret = ERR_CAST (shm -> dmabuf );
313+ teedev -> desc -> ops -> shm_unregister (ctx , shm );
314+ goto err ;
315+ }
316+ }
317+
318+ mutex_lock (& teedev -> mutex );
319+ list_add_tail (& shm -> link , & ctx -> list_shm );
320+ mutex_unlock (& teedev -> mutex );
321+
322+ return shm ;
323+ err :
324+ if (shm ) {
325+ size_t n ;
326+
327+ if (shm -> id >= 0 ) {
328+ mutex_lock (& teedev -> mutex );
329+ idr_remove (& teedev -> idr , shm -> id );
330+ mutex_unlock (& teedev -> mutex );
331+ }
332+ for (n = 0 ; n < shm -> num_pages ; n ++ )
333+ put_page (shm -> pages [n ]);
334+ kfree (shm -> pages );
335+ }
336+ kfree (shm );
337+ tee_device_put (teedev );
338+ return ret ;
339+ }
340+ EXPORT_SYMBOL_GPL (tee_shm_register );
341+
193342/**
194343 * tee_shm_get_fd() - Increase reference count and return file descriptor
195344 * @shm: Shared memory handle
196345 * @returns user space file descriptor to shared memory
197346 */
198347int tee_shm_get_fd (struct tee_shm * shm )
199348{
200- u32 req_flags = TEE_SHM_MAPPED | TEE_SHM_DMA_BUF ;
201349 int fd ;
202350
203- if ((shm -> flags & req_flags ) != req_flags )
351+ if (! (shm -> flags & TEE_SHM_DMA_BUF ) )
204352 return - EINVAL ;
205353
206354 fd = dma_buf_fd (shm -> dmabuf , O_CLOEXEC );
@@ -238,6 +386,8 @@ EXPORT_SYMBOL_GPL(tee_shm_free);
238386 */
239387int tee_shm_va2pa (struct tee_shm * shm , void * va , phys_addr_t * pa )
240388{
389+ if (!(shm -> flags & TEE_SHM_MAPPED ))
390+ return - EINVAL ;
241391 /* Check that we're in the range of the shm */
242392 if ((char * )va < (char * )shm -> kaddr )
243393 return - EINVAL ;
@@ -258,6 +408,8 @@ EXPORT_SYMBOL_GPL(tee_shm_va2pa);
258408 */
259409int tee_shm_pa2va (struct tee_shm * shm , phys_addr_t pa , void * * va )
260410{
411+ if (!(shm -> flags & TEE_SHM_MAPPED ))
412+ return - EINVAL ;
261413 /* Check that we're in the range of the shm */
262414 if (pa < shm -> paddr )
263415 return - EINVAL ;
@@ -284,6 +436,8 @@ EXPORT_SYMBOL_GPL(tee_shm_pa2va);
284436 */
285437void * tee_shm_get_va (struct tee_shm * shm , size_t offs )
286438{
439+ if (!(shm -> flags & TEE_SHM_MAPPED ))
440+ return ERR_PTR (- EINVAL );
287441 if (offs >= shm -> size )
288442 return ERR_PTR (- EINVAL );
289443 return (char * )shm -> kaddr + offs ;
0 commit comments