From 062d07cb6fc96e651aa1e7b46080207fc914585d Mon Sep 17 00:00:00 2001 From: Chris Goldsworthy Date: Thu, 12 May 2022 19:59:15 -0700 Subject: [PATCH] mem-buf: Port the mem-buf headers from msm-5.15 Port the mem-buf headers from 5.15 as of commit f899231bc38b ("Merge "msm: adsprpc: Handle length and variable scope""). Re-add mem-buf references in mem-buf-exporter.h. Change-Id: I89dffcaff907a6b774bd06cfada883414636dcbe Signed-off-by: Chris Goldsworthy --- include/linux/mem-buf-exporter.h | 8 ++ include/linux/mem-buf.h | 119 ++++++++++++++++ include/uapi/linux/mem-buf.h | 235 +++++++++++++++++++++++++++++++ 3 files changed, 362 insertions(+) create mode 100644 include/linux/mem-buf.h create mode 100644 include/uapi/linux/mem-buf.h diff --git a/include/linux/mem-buf-exporter.h b/include/linux/mem-buf-exporter.h index d1b86d36691d..9ff6e4491d84 100644 --- a/include/linux/mem-buf-exporter.h +++ b/include/linux/mem-buf-exporter.h @@ -7,6 +7,7 @@ #define _MEM_BUF_EXPORTER_H #include +#include #include int mem_buf_dma_buf_attach(struct dma_buf *dmabuf, @@ -54,6 +55,13 @@ struct mem_buf_vmperm *mem_buf_vmperm_alloc(struct sg_table *sgt); struct mem_buf_vmperm *mem_buf_vmperm_alloc_staticvm(struct sg_table *sgt, int *vmids, int *perms, u32 nr_acl_entries); +/* + * A dmabuf in the "MEMACCEPT" state. + */ +struct mem_buf_vmperm *mem_buf_vmperm_alloc_accept(struct sg_table *sgt, + gh_memparcel_handle_t memparcel_hdl); + + /* * Performs the expected close step based on whether the dmabuf * is of the "STATICVM" "MEMACCEPT" or "DEFAULT" type. diff --git a/include/linux/mem-buf.h b/include/linux/mem-buf.h new file mode 100644 index 000000000000..a018fe1c89eb --- /dev/null +++ b/include/linux/mem-buf.h @@ -0,0 +1,119 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + */ + +#ifndef _MEM_BUF_H +#define _MEM_BUF_H + +#include +#include +#include +#include +#include +#include + +/* Used to obtain the underlying vmperm struct of a DMA-BUF */ +struct mem_buf_vmperm *to_mem_buf_vmperm(struct dma_buf *dmabuf); + +/* Returns true if the local VM has exclusive access and is the owner */ +bool mem_buf_dma_buf_exclusive_owner(struct dma_buf *dmabuf); + +/* + * Returns a copy of the Virtual Machine vmids & permissions of the dmabuf. + * The caller must kfree() when finished. + */ +int mem_buf_dma_buf_copy_vmperm(struct dma_buf *dmabuf, int **vmids, int **perms, + int *nr_acl_entries); + +typedef int (*mem_buf_dma_buf_destructor)(void *dtor_data); +int mem_buf_dma_buf_set_destructor(struct dma_buf *dmabuf, + mem_buf_dma_buf_destructor dtor, + void *dtor_data); + +/** + * struct mem_buf_allocation_data - Data structure that contains information + * about a memory buffer allocation request. + * @size: The size (in bytes) of the memory to be requested from a remote VM + * @nr_acl_entries: The number of ACL entries in @acl_list + * @acl_list: A list of VMID and permission pairs that describe what VMIDs will + * have access to the memory, and with what permissions + * @src_mem_type: The type of memory that the remote VM should allocate + * (e.g. ION memory) + * @src_data: A pointer to memory type specific data that the remote VM may need + * when performing an allocation (e.g. ION memory allocations require a heap ID) + * @dst_mem_type: The type of memory that the native VM wants (e.g. ION memory) + * @dst_data: A pointer to memory type specific data that the native VM may + * need when adding the memory from the remote VM (e.g. ION memory requires a + * heap ID to add the memory to). + */ +struct mem_buf_allocation_data { + size_t size; + unsigned int nr_acl_entries; + int *vmids; + int *perms; + enum mem_buf_mem_type src_mem_type; + void *src_data; + enum mem_buf_mem_type dst_mem_type; + void *dst_data; +}; + +struct mem_buf_lend_kernel_arg { + unsigned int nr_acl_entries; + int *vmids; + int *perms; + gh_memparcel_handle_t memparcel_hdl; + u32 flags; + u64 label; +}; + +int mem_buf_lend(struct dma_buf *dmabuf, + struct mem_buf_lend_kernel_arg *arg); + +/* + * mem_buf_share + * Grant the local VM, as well as one or more remote VMs access + * to the dmabuf. The permissions of the local VM default to RWX + * unless otherwise specified. + */ +int mem_buf_share(struct dma_buf *dmabuf, + struct mem_buf_lend_kernel_arg *arg); + + +struct mem_buf_retrieve_kernel_arg { + int sender_vmid; + unsigned int nr_acl_entries; + int *vmids; + int *perms; + gh_memparcel_handle_t memparcel_hdl; + int fd_flags; +}; +struct dma_buf *mem_buf_retrieve(struct mem_buf_retrieve_kernel_arg *arg); +int mem_buf_reclaim(struct dma_buf *dmabuf); + +#if IS_ENABLED(CONFIG_QCOM_MEM_BUF) + +int mem_buf_get_fd(void *membuf_desc); + +void mem_buf_put(void *membuf_desc); + +void *mem_buf_get(int fd); + +#else + +static inline int mem_buf_get_fd(void *membuf_desc) +{ + return -ENODEV; +} + +static inline void mem_buf_put(void *membuf_desc) +{ +} + +static inline void *mem_buf_get(int fd) +{ + return ERR_PTR(-ENODEV); +} + +#endif /* CONFIG_QCOM_MEM_BUF */ +#endif /* _MEM_BUF_H */ diff --git a/include/uapi/linux/mem-buf.h b/include/uapi/linux/mem-buf.h new file mode 100644 index 000000000000..3bfd4505d757 --- /dev/null +++ b/include/uapi/linux/mem-buf.h @@ -0,0 +1,235 @@ +/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + */ + +#ifndef _UAPI_LINUX_MEM_BUF_H +#define _UAPI_LINUX_MEM_BUF_H + +#include +#include + +#define MEM_BUF_IOC_MAGIC 'M' + +/** + * enum mem_buf_mem_type: Types of memory that can be allocated from and to + * @MEM_BUF_ION_MEM_TYPE: The memory for the source or destination is ION memory + */ +enum mem_buf_mem_type { + MEM_BUF_ION_MEM_TYPE, + MEM_BUF_MAX_MEM_TYPE, +}; +#define MEM_BUF_DMAHEAP_MEM_TYPE (MEM_BUF_ION_MEM_TYPE + 1) + +/* The mem-buf values that represent VMIDs for an ACL. */ +#define MEM_BUF_VMID_PRIMARY_VM 0 +#define MEM_BUF_VMID_TRUSTED_VM 1 + +#define MEM_BUF_PERM_FLAG_READ (1U << 0) +#define MEM_BUF_PERM_FLAG_WRITE (1U << 1) +#define MEM_BUF_PERM_FLAG_EXEC (1U << 2) +#define MEM_BUF_PERM_VALID_FLAGS\ + (MEM_BUF_PERM_FLAG_READ | MEM_BUF_PERM_FLAG_WRITE |\ + MEM_BUF_PERM_FLAG_EXEC) + +#define MEM_BUF_MAX_NR_ACL_ENTS 16 + +/** + * struct acl_entry: Represents the access control permissions for a VMID. + * @vmid: The mem-buf VMID specifier associated with the VMID that will access + * the memory. + * @perms: The access permissions for the VMID in @vmid. This flag is + * interpreted as a bitmap, and thus, should be a combination of one or more + * of the MEM_BUF_PERM_FLAG_* flags. + */ +struct acl_entry { + __u32 vmid; + __u32 perms; +}; + +/** + * struct mem_buf_ion_data: Data that is unique to memory that is of type + * MEM_BUF_ION_MEM_TYPE. + * @heap_id: The heap ID of where memory should be allocated from or added to. + */ +struct mem_buf_ion_data { + __u32 heap_id; +}; + +#define MEM_BUF_MAX_DMAHEAP_NAME_LEN 128 +/** + * struct mem_buf_dmaheap_data: Data that is unique to memory that is of type + * MEM_BUF_DMAHEAP_MEM_TYPE. + * @heap_name: array of characters containing the heap name. + */ +struct mem_buf_dmaheap_data { + __u64 heap_name; +}; + +/** + * struct mem_buf_alloc_ioctl_arg: A request to allocate memory from another + * VM to other VMs. + * @size: The size of the allocation. + * @acl_list: An array of structures, where each structure specifies a VMID + * and the access permissions that the VMID will have to the memory to be + * allocated. + * @nr_acl_entries: The number of ACL entries in @acl_list. + * @src_mem_type: The type of memory that the source VM should allocate from. + * This should be one of the mem_buf_mem_type enum values. + * @src_data: A pointer to data that the source VM should interpret when + * performing the allocation. + * @dst_mem_type: The type of memory that the destination VM should treat the + * incoming allocation from the source VM as. This should be one of the + * mem_buf_mem_type enum values. + * @mem_buf_fd: A file descriptor representing the memory that was allocated + * from the source VM and added to the current VM. Calling close() on this file + * descriptor will deallocate the memory from the current VM, and return it + * to the source VM. + * * @dst_data: A pointer to data that the destination VM should interpret when + * adding the memory to the current VM. + * + * All reserved fields must be zeroed out by the caller prior to invoking the + * allocation IOCTL command with this argument. + */ +struct mem_buf_alloc_ioctl_arg { + __u64 size; + __u64 acl_list; + __u32 nr_acl_entries; + __u32 src_mem_type; + __u64 src_data; + __u32 dst_mem_type; + __u32 mem_buf_fd; + __u64 dst_data; + __u64 reserved0; + __u64 reserved1; + __u64 reserved2; +}; + +#define MEM_BUF_IOC_ALLOC _IOWR(MEM_BUF_IOC_MAGIC, 0,\ + struct mem_buf_alloc_ioctl_arg) + +/** + * struct mem_buf_lend_ioctl_arg: A request to lend memory from the local VM + * VM to one or more remote VMs. + * @dma_buf_fd: The fd of the dma-buf that will be exported to another VM. + * @nr_acl_entries: The number of ACL entries in @acl_list. + * @acl_list: An array of structures, where each structure specifies a VMID + * and the access permissions that the VMID will have to the memory to be + * exported. Must not include the local VMID. + * @memparcel_hdl: The handle associated with the memparcel that was created by + * granting access to the dma-buf for the VMIDs specified in @acl_list. + * + * All reserved fields must be zeroed out by the caller prior to invoking the + * import IOCTL command with this argument. + */ +struct mem_buf_lend_ioctl_arg { + __u32 dma_buf_fd; + __u32 nr_acl_entries; + __u64 acl_list; + __u64 memparcel_hdl; + __u64 reserved0; + __u64 reserved1; + __u64 reserved2; +}; + +#define MEM_BUF_IOC_LEND _IOWR(MEM_BUF_IOC_MAGIC, 3,\ + struct mem_buf_lend_ioctl_arg) + +#define MEM_BUF_VALID_FD_FLAGS (O_CLOEXEC | O_ACCMODE) +/** + * struct mem_buf_retrieve_ioctl_arg: A request to retrieve memory from another + * VM as a dma-buf + * @sender_vm_fd: An open file descriptor identifing the VM who sent the handle. + * @nr_acl_entries: The number of ACL entries in @acl_list. + * @acl_list: An array of structures, where each structure specifies a VMID + * and the access permissions that the VMID should have for the memparcel. + * @memparcel_hdl: The handle that corresponds to the memparcel we are + * importing. + * @dma_buf_import_fd: A dma-buf file descriptor that the client can use to + * access the buffer. This fd must be closed to release the memory. + * @fd_flags: file descriptor flags used when allocating + * + * All reserved fields must be zeroed out by the caller prior to invoking the + * import IOCTL command with this argument. + */ +struct mem_buf_retrieve_ioctl_arg { + __u32 sender_vm_fd; + __u32 nr_acl_entries; + __u64 acl_list; + __u64 memparcel_hdl; + __u32 dma_buf_import_fd; + __u32 fd_flags; + __u64 reserved0; + __u64 reserved1; + __u64 reserved2; +}; + +#define MEM_BUF_IOC_RETRIEVE _IOWR(MEM_BUF_IOC_MAGIC, 4,\ + struct mem_buf_retrieve_ioctl_arg) + +/** + * struct mem_buf_reclaim_ioctl_arg: A request to reclaim memory from another + * VM. The other VM must have relinquished access, and the current VM must be + * the original owner of the memory. The dma-buf file will not be closed by + * this operation. + * @memparcel_hdl: The handle that corresponds to the memparcel we are + * reclaiming. + * @dma_buf_fd: A dma-buf file descriptor that the client can use to + * access the buffer. + * + * All reserved fields must be zeroed out by the caller prior to invoking the + * import IOCTL command with this argument. + */ +struct mem_buf_reclaim_ioctl_arg { + __u64 memparcel_hdl; + __u32 dma_buf_fd; + __u32 reserved0; + __u64 reserved1; + __u64 reserved2; +}; + +#define MEM_BUF_IOC_RECLAIM _IOWR(MEM_BUF_IOC_MAGIC, 3,\ + struct mem_buf_reclaim_ioctl_arg) + +/** + * struct mem_buf_share_ioctl_arg: An request to share memory between the + * local VM and one or more remote VMs. + * @dma_buf_fd: The fd of the dma-buf that will be exported to another VM. + * @nr_acl_entries: The number of ACL entries in @acl_list. + * @acl_list: An array of structures, where each structure specifies a VMID + * and the access permissions that the VMID will have to the memory to be + * exported. Must include the local VMID. + * @memparcel_hdl: The handle associated with the memparcel that was created by + * granting access to the dma-buf for the VMIDs specified in @acl_list. + * + * All reserved fields must be zeroed out by the caller prior to invoking the + * import IOCTL command with this argument. + */ +struct mem_buf_share_ioctl_arg { + __u32 dma_buf_fd; + __u32 nr_acl_entries; + __u64 acl_list; + __u64 memparcel_hdl; + __u64 reserved0; + __u64 reserved1; + __u64 reserved2; +}; + +#define MEM_BUF_IOC_SHARE _IOWR(MEM_BUF_IOC_MAGIC, 6,\ + struct mem_buf_share_ioctl_arg) + +/** + * struct mem_buf_exclusive_owner_ioctl_arg: A request to see if a DMA-BUF + * is owned by and belongs exclusively to this VM. + * @dma_buf_fd: The fd of the dma-buf the user wants to obtain information on + * @is_exclusive_owner: + */ +struct mem_buf_exclusive_owner_ioctl_arg { + __u32 dma_buf_fd; + __u32 is_exclusive_owner; +}; + +#define MEM_BUF_IOC_EXCLUSIVE_OWNER _IOWR(MEM_BUF_IOC_MAGIC, 2,\ + struct mem_buf_exclusive_owner_ioctl_arg) + +#endif /* _UAPI_LINUX_MEM_BUF_H */