Lines Matching refs:shm
44 static void release_registered_pages(struct tee_shm *shm) in release_registered_pages() argument
46 if (shm->pages) { in release_registered_pages()
47 if (shm->flags & TEE_SHM_USER_MAPPED) in release_registered_pages()
48 unpin_user_pages(shm->pages, shm->num_pages); in release_registered_pages()
50 shm_put_kernel_pages(shm->pages, shm->num_pages); in release_registered_pages()
52 kfree(shm->pages); in release_registered_pages()
56 static void tee_shm_release(struct tee_device *teedev, struct tee_shm *shm) in tee_shm_release() argument
58 if (shm->flags & TEE_SHM_POOL) { in tee_shm_release()
59 teedev->pool->ops->free(teedev->pool, shm); in tee_shm_release()
60 } else if (shm->flags & TEE_SHM_DYNAMIC) { in tee_shm_release()
61 int rc = teedev->desc->ops->shm_unregister(shm->ctx, shm); in tee_shm_release()
65 "unregister shm %p failed: %d", shm, rc); in tee_shm_release()
67 release_registered_pages(shm); in tee_shm_release()
70 teedev_ctx_put(shm->ctx); in tee_shm_release()
72 kfree(shm); in tee_shm_release()
81 struct tee_shm *shm; in shm_alloc_helper() local
94 shm = kzalloc(sizeof(*shm), GFP_KERNEL); in shm_alloc_helper()
95 if (!shm) { in shm_alloc_helper()
100 refcount_set(&shm->refcount, 1); in shm_alloc_helper()
101 shm->flags = flags; in shm_alloc_helper()
102 shm->id = id; in shm_alloc_helper()
110 shm->ctx = ctx; in shm_alloc_helper()
112 rc = teedev->pool->ops->alloc(teedev->pool, shm, size, align); in shm_alloc_helper()
119 return shm; in shm_alloc_helper()
121 kfree(shm); in shm_alloc_helper()
143 struct tee_shm *shm; in tee_shm_alloc_user_buf() local
153 shm = shm_alloc_helper(ctx, size, PAGE_SIZE, flags, id); in tee_shm_alloc_user_buf()
154 if (IS_ERR(shm)) { in tee_shm_alloc_user_buf()
158 return shm; in tee_shm_alloc_user_buf()
162 ret = idr_replace(&teedev->idr, shm, id); in tee_shm_alloc_user_buf()
165 tee_shm_free(shm); in tee_shm_alloc_user_buf()
169 return shm; in tee_shm_alloc_user_buf()
221 struct tee_shm *shm; in register_shm_helper() local
238 shm = kzalloc(sizeof(*shm), GFP_KERNEL); in register_shm_helper()
239 if (!shm) { in register_shm_helper()
244 refcount_set(&shm->refcount, 1); in register_shm_helper()
245 shm->flags = flags; in register_shm_helper()
246 shm->ctx = ctx; in register_shm_helper()
247 shm->id = id; in register_shm_helper()
250 shm->offset = addr - start; in register_shm_helper()
251 shm->size = length; in register_shm_helper()
253 shm->pages = kcalloc(num_pages, sizeof(*shm->pages), GFP_KERNEL); in register_shm_helper()
254 if (!shm->pages) { in register_shm_helper()
261 shm->pages); in register_shm_helper()
263 rc = shm_get_kernel_pages(start, num_pages, shm->pages); in register_shm_helper()
265 shm->num_pages = rc; in register_shm_helper()
273 rc = teedev->desc->ops->shm_register(ctx, shm, shm->pages, in register_shm_helper()
274 shm->num_pages, start); in register_shm_helper()
280 return shm; in register_shm_helper()
283 unpin_user_pages(shm->pages, shm->num_pages); in register_shm_helper()
285 shm_put_kernel_pages(shm->pages, shm->num_pages); in register_shm_helper()
286 kfree(shm->pages); in register_shm_helper()
288 kfree(shm); in register_shm_helper()
309 struct tee_shm *shm; in tee_shm_register_user_buf() local
322 shm = register_shm_helper(ctx, addr, length, flags, id); in tee_shm_register_user_buf()
323 if (IS_ERR(shm)) { in tee_shm_register_user_buf()
327 return shm; in tee_shm_register_user_buf()
331 ret = idr_replace(&teedev->idr, shm, id); in tee_shm_register_user_buf()
334 tee_shm_free(shm); in tee_shm_register_user_buf()
338 return shm; in tee_shm_register_user_buf()
368 struct tee_shm *shm = filp->private_data; in tee_shm_fop_mmap() local
372 if (shm->flags & TEE_SHM_USER_MAPPED) in tee_shm_fop_mmap()
376 if (vma->vm_pgoff + vma_pages(vma) > shm->size >> PAGE_SHIFT) in tee_shm_fop_mmap()
379 return remap_pfn_range(vma, vma->vm_start, shm->paddr >> PAGE_SHIFT, in tee_shm_fop_mmap()
394 int tee_shm_get_fd(struct tee_shm *shm) in tee_shm_get_fd() argument
398 if (shm->id < 0) in tee_shm_get_fd()
402 refcount_inc(&shm->refcount); in tee_shm_get_fd()
403 fd = anon_inode_getfd("tee_shm", &tee_shm_fops, shm, O_RDWR); in tee_shm_get_fd()
405 tee_shm_put(shm); in tee_shm_get_fd()
413 void tee_shm_free(struct tee_shm *shm) in tee_shm_free() argument
415 tee_shm_put(shm); in tee_shm_free()
426 void *tee_shm_get_va(struct tee_shm *shm, size_t offs) in tee_shm_get_va() argument
428 if (!shm->kaddr) in tee_shm_get_va()
430 if (offs >= shm->size) in tee_shm_get_va()
432 return (char *)shm->kaddr + offs; in tee_shm_get_va()
444 int tee_shm_get_pa(struct tee_shm *shm, size_t offs, phys_addr_t *pa) in tee_shm_get_pa() argument
446 if (offs >= shm->size) in tee_shm_get_pa()
449 *pa = shm->paddr + offs; in tee_shm_get_pa()
464 struct tee_shm *shm; in tee_shm_get_from_id() local
471 shm = idr_find(&teedev->idr, id); in tee_shm_get_from_id()
477 if (!shm || shm->ctx != ctx) in tee_shm_get_from_id()
478 shm = ERR_PTR(-EINVAL); in tee_shm_get_from_id()
480 refcount_inc(&shm->refcount); in tee_shm_get_from_id()
482 return shm; in tee_shm_get_from_id()
490 void tee_shm_put(struct tee_shm *shm) in tee_shm_put() argument
492 struct tee_device *teedev = shm->ctx->teedev; in tee_shm_put()
496 if (refcount_dec_and_test(&shm->refcount)) { in tee_shm_put()
503 if (shm->id >= 0) in tee_shm_put()
504 idr_remove(&teedev->idr, shm->id); in tee_shm_put()
510 tee_shm_release(teedev, shm); in tee_shm_put()