Lines Matching refs:shm
15 static void release_registered_pages(struct tee_shm *shm) in release_registered_pages() argument
17 if (shm->pages) { in release_registered_pages()
18 if (shm->flags & TEE_SHM_USER_MAPPED) { in release_registered_pages()
19 unpin_user_pages(shm->pages, shm->num_pages); in release_registered_pages()
23 for (n = 0; n < shm->num_pages; n++) in release_registered_pages()
24 put_page(shm->pages[n]); in release_registered_pages()
27 kfree(shm->pages); in release_registered_pages()
31 static void tee_shm_release(struct tee_device *teedev, struct tee_shm *shm) in tee_shm_release() argument
33 if (shm->flags & TEE_SHM_POOL) { in tee_shm_release()
36 if (shm->flags & TEE_SHM_DMA_BUF) in tee_shm_release()
41 poolm->ops->free(poolm, shm); in tee_shm_release()
42 } else if (shm->flags & TEE_SHM_REGISTER) { in tee_shm_release()
43 int rc = teedev->desc->ops->shm_unregister(shm->ctx, shm); in tee_shm_release()
47 "unregister shm %p failed: %d", shm, rc); in tee_shm_release()
49 release_registered_pages(shm); in tee_shm_release()
52 teedev_ctx_put(shm->ctx); in tee_shm_release()
54 kfree(shm); in tee_shm_release()
63 struct tee_shm *shm; in tee_shm_alloc() local
87 shm = kzalloc(sizeof(*shm), GFP_KERNEL); in tee_shm_alloc()
88 if (!shm) { in tee_shm_alloc()
93 refcount_set(&shm->refcount, 1); in tee_shm_alloc()
94 shm->flags = flags | TEE_SHM_POOL; in tee_shm_alloc()
95 shm->ctx = ctx; in tee_shm_alloc()
101 rc = poolm->ops->alloc(poolm, shm, size); in tee_shm_alloc()
109 shm->id = idr_alloc(&teedev->idr, shm, 1, 0, GFP_KERNEL); in tee_shm_alloc()
111 if (shm->id < 0) { in tee_shm_alloc()
112 ret = ERR_PTR(shm->id); in tee_shm_alloc()
119 return shm; in tee_shm_alloc()
121 poolm->ops->free(poolm, shm); in tee_shm_alloc()
123 kfree(shm); in tee_shm_alloc()
154 struct tee_shm *shm; in tee_shm_register() local
174 shm = kzalloc(sizeof(*shm), GFP_KERNEL); in tee_shm_register()
175 if (!shm) { in tee_shm_register()
180 refcount_set(&shm->refcount, 1); in tee_shm_register()
181 shm->flags = flags | TEE_SHM_REGISTER; in tee_shm_register()
182 shm->ctx = ctx; in tee_shm_register()
183 shm->id = -1; in tee_shm_register()
186 shm->offset = addr - start; in tee_shm_register()
187 shm->size = length; in tee_shm_register()
189 shm->pages = kcalloc(num_pages, sizeof(*shm->pages), GFP_KERNEL); in tee_shm_register()
190 if (!shm->pages) { in tee_shm_register()
197 shm->pages); in tee_shm_register()
213 rc = get_kernel_pages(kiov, num_pages, 0, shm->pages); in tee_shm_register()
217 shm->num_pages = rc; in tee_shm_register()
226 shm->id = idr_alloc(&teedev->idr, shm, 1, 0, GFP_KERNEL); in tee_shm_register()
229 if (shm->id < 0) { in tee_shm_register()
230 ret = ERR_PTR(shm->id); in tee_shm_register()
234 rc = teedev->desc->ops->shm_register(ctx, shm, shm->pages, in tee_shm_register()
235 shm->num_pages, start); in tee_shm_register()
241 return shm; in tee_shm_register()
243 if (shm) { in tee_shm_register()
244 if (shm->id >= 0) { in tee_shm_register()
246 idr_remove(&teedev->idr, shm->id); in tee_shm_register()
249 release_registered_pages(shm); in tee_shm_register()
251 kfree(shm); in tee_shm_register()
266 struct tee_shm *shm = filp->private_data; in tee_shm_fop_mmap() local
270 if (shm->flags & TEE_SHM_USER_MAPPED) in tee_shm_fop_mmap()
274 if (vma->vm_pgoff + vma_pages(vma) > shm->size >> PAGE_SHIFT) in tee_shm_fop_mmap()
277 return remap_pfn_range(vma, vma->vm_start, shm->paddr >> PAGE_SHIFT, in tee_shm_fop_mmap()
292 int tee_shm_get_fd(struct tee_shm *shm) in tee_shm_get_fd() argument
296 if (!(shm->flags & TEE_SHM_DMA_BUF)) in tee_shm_get_fd()
300 refcount_inc(&shm->refcount); in tee_shm_get_fd()
301 fd = anon_inode_getfd("tee_shm", &tee_shm_fops, shm, O_RDWR); in tee_shm_get_fd()
303 tee_shm_put(shm); in tee_shm_get_fd()
311 void tee_shm_free(struct tee_shm *shm) in tee_shm_free() argument
313 tee_shm_put(shm); in tee_shm_free()
324 int tee_shm_va2pa(struct tee_shm *shm, void *va, phys_addr_t *pa) in tee_shm_va2pa() argument
326 if (!(shm->flags & TEE_SHM_MAPPED)) in tee_shm_va2pa()
329 if ((char *)va < (char *)shm->kaddr) in tee_shm_va2pa()
331 if ((char *)va >= ((char *)shm->kaddr + shm->size)) in tee_shm_va2pa()
335 shm, (unsigned long)va - (unsigned long)shm->kaddr, pa); in tee_shm_va2pa()
346 int tee_shm_pa2va(struct tee_shm *shm, phys_addr_t pa, void **va) in tee_shm_pa2va() argument
348 if (!(shm->flags & TEE_SHM_MAPPED)) in tee_shm_pa2va()
351 if (pa < shm->paddr) in tee_shm_pa2va()
353 if (pa >= (shm->paddr + shm->size)) in tee_shm_pa2va()
357 void *v = tee_shm_get_va(shm, pa - shm->paddr); in tee_shm_pa2va()
374 void *tee_shm_get_va(struct tee_shm *shm, size_t offs) in tee_shm_get_va() argument
376 if (!(shm->flags & TEE_SHM_MAPPED)) in tee_shm_get_va()
378 if (offs >= shm->size) in tee_shm_get_va()
380 return (char *)shm->kaddr + offs; in tee_shm_get_va()
392 int tee_shm_get_pa(struct tee_shm *shm, size_t offs, phys_addr_t *pa) in tee_shm_get_pa() argument
394 if (offs >= shm->size) in tee_shm_get_pa()
397 *pa = shm->paddr + offs; in tee_shm_get_pa()
412 struct tee_shm *shm; in tee_shm_get_from_id() local
419 shm = idr_find(&teedev->idr, id); in tee_shm_get_from_id()
425 if (!shm || shm->ctx != ctx) in tee_shm_get_from_id()
426 shm = ERR_PTR(-EINVAL); in tee_shm_get_from_id()
428 refcount_inc(&shm->refcount); in tee_shm_get_from_id()
430 return shm; in tee_shm_get_from_id()
438 void tee_shm_put(struct tee_shm *shm) in tee_shm_put() argument
440 struct tee_device *teedev = shm->ctx->teedev; in tee_shm_put()
444 if (refcount_dec_and_test(&shm->refcount)) { in tee_shm_put()
451 if (shm->flags & TEE_SHM_DMA_BUF) in tee_shm_put()
452 idr_remove(&teedev->idr, shm->id); in tee_shm_put()
458 tee_shm_release(teedev, shm); in tee_shm_put()