// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2017, 2019-2021 Linaro Limited */ #include <linux/anon_inodes.h> #include <linux/device.h> #include <linux/idr.h> #include <linux/io.h> #include <linux/mm.h> #include <linux/sched.h> #include <linux/slab.h> #include <linux/tee_core.h> #include <linux/uaccess.h> #include <linux/uio.h> #include <linux/highmem.h> #include "tee_private.h" static void shm_put_kernel_pages(struct page **pages, size_t page_count) { … } static void shm_get_kernel_pages(struct page **pages, size_t page_count) { … } static void release_registered_pages(struct tee_shm *shm) { … } static void tee_shm_release(struct tee_device *teedev, struct tee_shm *shm) { … } static struct tee_shm *shm_alloc_helper(struct tee_context *ctx, size_t size, size_t align, u32 flags, int id) { … } /** * tee_shm_alloc_user_buf() - Allocate shared memory for user space * @ctx: Context that allocates the shared memory * @size: Requested size of shared memory * * Memory allocated as user space shared memory is automatically freed when * the TEE file pointer is closed. The primary usage of this function is * when the TEE driver doesn't support registering ordinary user space * memory. * * @returns a pointer to 'struct tee_shm' */ struct tee_shm *tee_shm_alloc_user_buf(struct tee_context *ctx, size_t size) { … } /** * tee_shm_alloc_kernel_buf() - Allocate shared memory for kernel buffer * @ctx: Context that allocates the shared memory * @size: Requested size of shared memory * * The returned memory registered in secure world and is suitable to be * passed as a memory buffer in parameter argument to * tee_client_invoke_func(). The memory allocated is later freed with a * call to tee_shm_free(). * * @returns a pointer to 'struct tee_shm' */ struct tee_shm *tee_shm_alloc_kernel_buf(struct tee_context *ctx, size_t size) { … } EXPORT_SYMBOL_GPL(…); /** * tee_shm_alloc_priv_buf() - Allocate shared memory for a privately shared * kernel buffer * @ctx: Context that allocates the shared memory * @size: Requested size of shared memory * * This function returns similar shared memory as * tee_shm_alloc_kernel_buf(), but with the difference that the memory * might not be registered in secure world in case the driver supports * passing memory not registered in advance. * * This function should normally only be used internally in the TEE * drivers. * * @returns a pointer to 'struct tee_shm' */ struct tee_shm *tee_shm_alloc_priv_buf(struct tee_context *ctx, size_t size) { … } EXPORT_SYMBOL_GPL(…); int tee_dyn_shm_alloc_helper(struct tee_shm *shm, size_t size, size_t align, int (*shm_register)(struct tee_context *ctx, struct tee_shm *shm, struct page **pages, size_t num_pages, unsigned long start)) { … } EXPORT_SYMBOL_GPL(…); void tee_dyn_shm_free_helper(struct tee_shm *shm, int (*shm_unregister)(struct tee_context *ctx, struct tee_shm *shm)) { … } EXPORT_SYMBOL_GPL(…); static struct tee_shm * register_shm_helper(struct tee_context *ctx, struct iov_iter *iter, u32 flags, int id) { … } /** * tee_shm_register_user_buf() - Register a userspace shared memory buffer * @ctx: Context that registers the shared memory * @addr: The userspace address of the shared buffer * @length: Length of the shared buffer * * @returns a pointer to 'struct tee_shm' */ struct tee_shm *tee_shm_register_user_buf(struct tee_context *ctx, unsigned long addr, size_t length) { … } /** * tee_shm_register_kernel_buf() - Register kernel memory to be shared with * secure world * @ctx: Context that registers the shared memory * @addr: The buffer * @length: Length of the buffer * * @returns a pointer to 'struct tee_shm' */ struct tee_shm *tee_shm_register_kernel_buf(struct tee_context *ctx, void *addr, size_t length) { … } EXPORT_SYMBOL_GPL(…); static int tee_shm_fop_release(struct inode *inode, struct file *filp) { … } static int tee_shm_fop_mmap(struct file *filp, struct vm_area_struct *vma) { … } static const struct file_operations tee_shm_fops = …; /** * tee_shm_get_fd() - Increase reference count and return file descriptor * @shm: Shared memory handle * @returns user space file descriptor to shared memory */ int tee_shm_get_fd(struct tee_shm *shm) { … } /** * tee_shm_free() - Free shared memory * @shm: Handle to shared memory to free */ void tee_shm_free(struct tee_shm *shm) { … } EXPORT_SYMBOL_GPL(…); /** * tee_shm_get_va() - Get virtual address of a shared memory plus an offset * @shm: Shared memory handle * @offs: Offset from start of this shared memory * @returns virtual address of the shared memory + offs if offs is within * the bounds of this shared memory, else an ERR_PTR */ void *tee_shm_get_va(struct tee_shm *shm, size_t offs) { … } EXPORT_SYMBOL_GPL(…); /** * tee_shm_get_pa() - Get physical address of a shared memory plus an offset * @shm: Shared memory handle * @offs: Offset from start of this shared memory * @pa: Physical address to return * @returns 0 if offs is within the bounds of this shared memory, else an * error code. */ int tee_shm_get_pa(struct tee_shm *shm, size_t offs, phys_addr_t *pa) { … } EXPORT_SYMBOL_GPL(…); /** * tee_shm_get_from_id() - Find shared memory object and increase reference * count * @ctx: Context owning the shared memory * @id: Id of shared memory object * @returns a pointer to 'struct tee_shm' on success or an ERR_PTR on failure */ struct tee_shm *tee_shm_get_from_id(struct tee_context *ctx, int id) { … } EXPORT_SYMBOL_GPL(…); /** * tee_shm_put() - Decrease reference count on a shared memory handle * @shm: Shared memory handle */ void tee_shm_put(struct tee_shm *shm) { … } EXPORT_SYMBOL_GPL(…);