diff --git a/drivers/video/tegra/nvmap/Makefile.memory.configs b/drivers/video/tegra/nvmap/Makefile.memory.configs index 509df4b4..97880937 100644 --- a/drivers/video/tegra/nvmap/Makefile.memory.configs +++ b/drivers/video/tegra/nvmap/Makefile.memory.configs @@ -106,6 +106,11 @@ NVMAP_CONFIG_DMABUF_DEFERRED_UNMAPPING := n #Config for enabling nvmap_register_vidmem_carveout NVMAP_CONFIG_VIDMEM_CARVEOUT := n + +# Config for enabling Foreign buffer support (for OpenRM created buffer) +# This config protects the code added for supporting APIs like NvRmMemQueryHandleParams +# for Foreign fd for a buffer created by OpenRM. +NVMAP_CONFIG_ENABLE_FOREIGN_BUFFER := y ################################################################################ # Section 3 # Enable/Disable configs based upon the kernel version @@ -181,5 +186,8 @@ ifeq ($(NVMAP_CONFIG_CACHE_FLUSH_AT_ALLOC),y) ccflags-y += -DNVMAP_CONFIG_CACHE_FLUSH_AT_ALLOC endif #NVMAP_CONFIG_CACHE_FLUSH_AT_ALLOC +ifeq ($(NVMAP_CONFIG_ENABLE_FOREIGN_BUFFER),y) +ccflags-y += -DNVMAP_CONFIG_ENABLE_FOREIGN_BUFFER +endif #NVMAP_CONFIG_ENABLE_FOREIGN_BUFFER endif #NVMAP_CONFIG endif #CONFIG_ARCH_TEGRA diff --git a/drivers/video/tegra/nvmap/nvmap_ioctl.c b/drivers/video/tegra/nvmap/nvmap_ioctl.c index 2a4dbe7f..040fcefb 100644 --- a/drivers/video/tegra/nvmap/nvmap_ioctl.c +++ b/drivers/video/tegra/nvmap/nvmap_ioctl.c @@ -896,7 +896,7 @@ int nvmap_ioctl_get_available_heaps(struct file *filp, void __user *arg) int nvmap_ioctl_get_handle_parameters(struct file *filp, void __user *arg) { struct nvmap_client *client = filp->private_data; - struct nvmap_handle_parameters op; + struct nvmap_handle_parameters op = {0}; struct nvmap_handle *handle; bool is_ro = false; @@ -904,8 +904,26 @@ int nvmap_ioctl_get_handle_parameters(struct file *filp, void __user *arg) return -EFAULT; handle = nvmap_handle_get_from_id(client, op.handle); - if (IS_ERR_OR_NULL(handle)) + if (IS_ERR_OR_NULL(handle)) { +#if defined(NVMAP_CONFIG_ENABLE_FOREIGN_BUFFER) && defined(NVMAP_CONFIG_HANDLE_AS_ID) + struct dma_buf *dmabuf; + + dmabuf = dma_buf_get((int)op.handle); + if (!IS_ERR_OR_NULL(dmabuf)) { + /* Foreign buffer */ + op.size = dmabuf->size; + op.align = PAGE_SIZE; + if (copy_to_user(arg, &op, sizeof(op))) { + pr_err("Failed to copy to userspace\n"); + dma_buf_put(dmabuf); + goto exit; + } + dma_buf_put(dmabuf); + return 0; + } +#endif /* NVMAP_CONFIG_ENABLE_FOREIGN_BUFFER && NVMAP_CONFIG_HANDLE_AS_ID */ goto exit; + } if (!handle->alloc) { op.heap = 0; @@ -1130,6 +1148,19 @@ int nvmap_ioctl_dup_handle(struct file *filp, void __user *arg) if (client == NULL) return -ENODEV; +#if defined(NVMAP_CONFIG_ENABLE_FOREIGN_BUFFER) && defined(NVMAP_CONFIG_HANDLE_AS_ID) + dmabuf = dma_buf_get(op.handle); + /* + * Foreign fd should return unique error number to userspace NvRmMem + * function for handle duplication, so that userspace can use dup system + * call to duplicate the fd. + */ + if (!IS_ERR_OR_NULL(dmabuf)) { + dma_buf_put(dmabuf); + return -EOPNOTSUPP; + } +#endif /* NVMAP_CONFIG_ENABLE_FOREIGN_BUFFER && NVMAP_CONFIG_HANDLE_AS_ID */ + if (is_nvmap_id_ro(client, op.handle, &is_ro) != 0) { pr_err("Handle ID RO check failed\n"); return -EINVAL;