Lines Matching +full:shared +full:- +full:memory

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2015-2017, 2019-2021 Linaro Limited
33 return -EINVAL; in shm_get_kernel_pages()
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()
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()
64 dev_err(teedev->dev.parent, in tee_shm_release()
70 teedev_ctx_put(shm->ctx); in tee_shm_release()
80 struct tee_device *teedev = ctx->teedev; in shm_alloc_helper()
86 return ERR_PTR(-EINVAL); in shm_alloc_helper()
88 if (!teedev->pool) { in shm_alloc_helper()
90 ret = ERR_PTR(-EINVAL); in shm_alloc_helper()
96 ret = ERR_PTR(-ENOMEM); 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()
107 * to call teedev_ctx_get() or clear shm->ctx in case it's not 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()
128 * tee_shm_alloc_user_buf() - Allocate shared memory for user space
129 * @ctx: Context that allocates the shared memory
130 * @size: Requested size of shared memory
132 * Memory allocated as user space shared memory is automatically freed when
135 * memory.
142 struct tee_device *teedev = ctx->teedev; in tee_shm_alloc_user_buf()
147 mutex_lock(&teedev->mutex); in tee_shm_alloc_user_buf()
148 id = idr_alloc(&teedev->idr, NULL, 1, 0, GFP_KERNEL); in tee_shm_alloc_user_buf()
149 mutex_unlock(&teedev->mutex); in tee_shm_alloc_user_buf()
155 mutex_lock(&teedev->mutex); in tee_shm_alloc_user_buf()
156 idr_remove(&teedev->idr, id); in tee_shm_alloc_user_buf()
157 mutex_unlock(&teedev->mutex); in tee_shm_alloc_user_buf()
161 mutex_lock(&teedev->mutex); in tee_shm_alloc_user_buf()
162 ret = idr_replace(&teedev->idr, shm, id); in tee_shm_alloc_user_buf()
163 mutex_unlock(&teedev->mutex); in tee_shm_alloc_user_buf()
173 * tee_shm_alloc_kernel_buf() - Allocate shared memory for kernel buffer
174 * @ctx: Context that allocates the shared memory
175 * @size: Requested size of shared memory
177 * The returned memory registered in secure world and is suitable to be
178 * passed as a memory buffer in parameter argument to
179 * tee_client_invoke_func(). The memory allocated is later freed with a
188 return shm_alloc_helper(ctx, size, PAGE_SIZE, flags, -1); in tee_shm_alloc_kernel_buf()
193 * tee_shm_alloc_priv_buf() - Allocate shared memory for a privately shared
195 * @ctx: Context that allocates the shared memory
196 * @size: Requested size of shared memory
198 * This function returns similar shared memory as
199 * tee_shm_alloc_kernel_buf(), but with the difference that the memory
201 * passing memory not registered in advance.
212 return shm_alloc_helper(ctx, size, sizeof(long) * 2, flags, -1); in tee_shm_alloc_priv_buf()
220 struct tee_device *teedev = ctx->teedev; in register_shm_helper()
228 return ERR_PTR(-EINVAL); in register_shm_helper()
230 if (!teedev->desc->ops->shm_register || in register_shm_helper()
231 !teedev->desc->ops->shm_unregister) { in register_shm_helper()
232 ret = ERR_PTR(-ENOTSUPP); in register_shm_helper()
240 ret = ERR_PTR(-ENOMEM); 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()
252 num_pages = (roundup(addr + length, PAGE_SIZE) - start) / PAGE_SIZE; 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()
255 ret = ERR_PTR(-ENOMEM); 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()
268 rc = -ENOMEM; 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()
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()
297 * tee_shm_register_user_buf() - Register a userspace shared memory buffer
298 * @ctx: Context that registers the shared memory
299 * @addr: The userspace address of the shared buffer
300 * @length: Length of the shared buffer
308 struct tee_device *teedev = ctx->teedev; in tee_shm_register_user_buf()
314 return ERR_PTR(-EFAULT); in tee_shm_register_user_buf()
316 mutex_lock(&teedev->mutex); in tee_shm_register_user_buf()
317 id = idr_alloc(&teedev->idr, NULL, 1, 0, GFP_KERNEL); in tee_shm_register_user_buf()
318 mutex_unlock(&teedev->mutex); in tee_shm_register_user_buf()
324 mutex_lock(&teedev->mutex); in tee_shm_register_user_buf()
325 idr_remove(&teedev->idr, id); in tee_shm_register_user_buf()
326 mutex_unlock(&teedev->mutex); in tee_shm_register_user_buf()
330 mutex_lock(&teedev->mutex); in tee_shm_register_user_buf()
331 ret = idr_replace(&teedev->idr, shm, id); in tee_shm_register_user_buf()
332 mutex_unlock(&teedev->mutex); in tee_shm_register_user_buf()
342 * tee_shm_register_kernel_buf() - Register kernel memory to be shared with
344 * @ctx: Context that registers the shared memory
356 return register_shm_helper(ctx, (unsigned long)addr, length, flags, -1); in tee_shm_register_kernel_buf()
362 tee_shm_put(filp->private_data); in tee_shm_fop_release()
368 struct tee_shm *shm = filp->private_data; in tee_shm_fop_mmap()
369 size_t size = vma->vm_end - vma->vm_start; in tee_shm_fop_mmap()
371 /* Refuse sharing shared memory provided by application */ in tee_shm_fop_mmap()
372 if (shm->flags & TEE_SHM_USER_MAPPED) in tee_shm_fop_mmap()
373 return -EINVAL; in tee_shm_fop_mmap()
376 if (vma->vm_pgoff + vma_pages(vma) > shm->size >> PAGE_SHIFT) in tee_shm_fop_mmap()
377 return -EINVAL; in tee_shm_fop_mmap()
379 return remap_pfn_range(vma, vma->vm_start, shm->paddr >> PAGE_SHIFT, in tee_shm_fop_mmap()
380 size, vma->vm_page_prot); in tee_shm_fop_mmap()
390 * tee_shm_get_fd() - Increase reference count and return file descriptor
391 * @shm: Shared memory handle
392 * @returns user space file descriptor to shared memory
398 if (shm->id < 0) in tee_shm_get_fd()
399 return -EINVAL; in tee_shm_get_fd()
402 refcount_inc(&shm->refcount); in tee_shm_get_fd()
410 * tee_shm_free() - Free shared memory
411 * @shm: Handle to shared memory to free
420 * tee_shm_get_va() - Get virtual address of a shared memory plus an offset
421 * @shm: Shared memory handle
422 * @offs: Offset from start of this shared memory
423 * @returns virtual address of the shared memory + offs if offs is within
424 * the bounds of this shared memory, else an ERR_PTR
428 if (!shm->kaddr) in tee_shm_get_va()
429 return ERR_PTR(-EINVAL); in tee_shm_get_va()
430 if (offs >= shm->size) in tee_shm_get_va()
431 return ERR_PTR(-EINVAL); in tee_shm_get_va()
432 return (char *)shm->kaddr + offs; in tee_shm_get_va()
437 * tee_shm_get_pa() - Get physical address of a shared memory plus an offset
438 * @shm: Shared memory handle
439 * @offs: Offset from start of this shared memory
441 * @returns 0 if offs is within the bounds of this shared memory, else an
446 if (offs >= shm->size) in tee_shm_get_pa()
447 return -EINVAL; in tee_shm_get_pa()
449 *pa = shm->paddr + offs; in tee_shm_get_pa()
455 * tee_shm_get_from_id() - Find shared memory object and increase reference
457 * @ctx: Context owning the shared memory
458 * @id: Id of shared memory object
467 return ERR_PTR(-EINVAL); in tee_shm_get_from_id()
469 teedev = ctx->teedev; in tee_shm_get_from_id()
470 mutex_lock(&teedev->mutex); in tee_shm_get_from_id()
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()
481 mutex_unlock(&teedev->mutex); in tee_shm_get_from_id()
487 * tee_shm_put() - Decrease reference count on a shared memory handle
488 * @shm: Shared memory handle
492 struct tee_device *teedev = shm->ctx->teedev; in tee_shm_put()
495 mutex_lock(&teedev->mutex); 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()
507 mutex_unlock(&teedev->mutex); in tee_shm_put()