video: tegra: nvmap: use dmabuf fd to share handles
Krishna Reddy [Wed, 3 Jul 2013 23:55:18 +0000 (16:55 -0700)]
fix incorrect error handling in nvmap_share_dmabuf.
remove unnecessary dependency on DMA_SHARED_BUFFER.
cleanup nvmap dmabuf implementation.

Change-Id: If427fb8c29116b797e7e998e1c68ff0081acc559
Signed-off-by: Krishna Reddy <vdumpa@nvidia.com>
Reviewed-on: http://git-master/r/244907
(cherry picked from commit ebda92705d3f7925e9edfbda7b715f33d2d93fcf)
Reviewed-on: http://git-master/r/251670
Reviewed-by: Mandar Padmawar <mpadmawar@nvidia.com>
Tested-by: Mandar Padmawar <mpadmawar@nvidia.com>

drivers/video/tegra/nvmap/Makefile
drivers/video/tegra/nvmap/nvmap_dmabuf.c
drivers/video/tegra/nvmap/nvmap_handle.c
drivers/video/tegra/nvmap/nvmap_ioctl.c
drivers/video/tegra/nvmap/nvmap_ioctl.h
drivers/video/tegra/nvmap/nvmap_priv.h

index 6047f16..a72587f 100644 (file)
@@ -5,5 +5,5 @@ obj-y += nvmap_handle.o
 obj-y += nvmap_heap.o
 obj-y += nvmap_ioctl.o
 obj-${CONFIG_IOMMU_API}        += nvmap_iommu.o
-obj-${CONFIG_DMA_SHARED_BUFFER} += nvmap_dmabuf.o
+obj-y += nvmap_dmabuf.o
 obj-${CONFIG_NVMAP_RECLAIM_UNPINNED_VM} += nvmap_mru.o
index 7510cf1..da9d0f4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * dma_buf exporter for nvmap
  *
- * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2012-2013, NVIDIA CORPORATION.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -169,11 +169,11 @@ static struct dma_buf_ops nvmap_dma_buf_ops = {
        .vunmap         = nvmap_dmabuf_vunmap,
 };
 
-struct dma_buf *nvmap_share_dmabuf(struct nvmap_client *client, ulong id)
+struct dma_buf *nvmap_get_dmabuf(struct nvmap_client *client, ulong id)
 {
+       int err;
        struct dma_buf *dmabuf;
        struct nvmap_handle_info *info;
-       int err;
        struct nvmap_handle *handle;
 
        if (!nvmap_client_get(client))
@@ -211,14 +211,46 @@ err_nvmap_validate_get:
        nvmap_client_put(client);
        return ERR_PTR(err);
 }
-EXPORT_SYMBOL_GPL(nvmap_share_dmabuf);
+
+int nvmap_get_dmabuf_fd(struct nvmap_client *client, ulong id)
+{
+       int fd;
+       struct dma_buf *dmabuf;
+
+       dmabuf = nvmap_get_dmabuf(client, id);
+       if (IS_ERR(dmabuf))
+               return PTR_ERR(dmabuf);
+       fd = dma_buf_fd(dmabuf, O_CLOEXEC);
+       if (fd < 0)
+               goto err_out;
+       return fd;
+
+err_out:
+       dma_buf_put(dmabuf);
+       return fd;
+}
+
+ulong nvmap_get_id_from_dmabuf_fd(struct nvmap_client *client, int fd)
+{
+       ulong id = -EINVAL;
+       struct dma_buf *dmabuf;
+       struct nvmap_handle_info *info;
+
+       dmabuf = dma_buf_get(fd);
+       if (IS_ERR(dmabuf))
+               return PTR_ERR(dmabuf);
+       if (dmabuf->ops == &nvmap_dma_buf_ops) {
+               info = dmabuf->priv;
+               id = info->id;
+       }
+       dma_buf_put(dmabuf);
+       return id;
+}
 
 int nvmap_ioctl_share_dmabuf(struct file *filp, void __user *arg)
 {
-       int err;
        struct nvmap_create_handle op;
        struct nvmap_client *client = filp->private_data;
-       struct dma_buf *dmabuf;
        ulong handle;
 
        BUG_ON(!client);
@@ -230,23 +262,13 @@ int nvmap_ioctl_share_dmabuf(struct file *filp, void __user *arg)
        if (!handle)
                return -EINVAL;
 
-       dmabuf = nvmap_share_dmabuf(client, handle);
-       if (IS_ERR(dmabuf))
-               return -EINVAL;
-
-       op.fd = dma_buf_fd(dmabuf, O_CLOEXEC);
-       if (op.fd < 0) {
-               err = op.fd;
-               goto err_out;
-       }
+       op.fd = nvmap_get_dmabuf_fd(client, handle);
+       if (op.fd < 0)
+               return op.fd;
 
        if (copy_to_user((void __user *)arg, &op, sizeof(op))) {
-               err = -EFAULT;
-               goto err_out;
+               sys_close(op.fd);
+               return -EFAULT;
        }
        return 0;
-
-err_out:
-       nvmap_dmabuf_release(dmabuf);
-       return err;
 }
index a22cbd6..3542d31 100644 (file)
@@ -1115,23 +1115,15 @@ struct nvmap_handle_ref *nvmap_duplicate_handle_user_id(
 struct nvmap_handle_ref *nvmap_create_handle_from_fd(
                        struct nvmap_client *client, int fd)
 {
-       struct nvmap_handle_ref *ref = NULL;
-       struct file *file = fget(fd);
        unsigned long id;
+       struct nvmap_handle_ref *ref;
 
        BUG_ON(!client || client->dev != nvmap_dev);
 
-       if (!file)
-               return ERR_PTR(-EINVAL);
-
-       if (file->f_op != &nvmap_fd_fops) {
-               fput(file);
-               return ERR_PTR(-EINVAL);
-       }
-
-       id = (unsigned long)file->private_data;
+       id = nvmap_get_id_from_dmabuf_fd(client, fd);
+       if (IS_ERR_VALUE(id))
+               return ERR_PTR(id);
        ref = nvmap_duplicate_handle_id(client, id, 1);
-       fput(file);
        return ref;
 }
 
index be0b1d2..65da949 100644 (file)
@@ -20,7 +20,6 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-#include <linux/anon_inodes.h>
 #include <linux/dma-mapping.h>
 #include <linux/export.h>
 #include <linux/fs.h>
@@ -257,12 +256,9 @@ const struct file_operations nvmap_fd_fops = {
 
 int nvmap_ioctl_getfd(struct file *filp, void __user *arg)
 {
-       struct nvmap_client *client = filp->private_data;
-       struct nvmap_create_handle op;
-       struct nvmap_handle *h = NULL;
-       int fd;
-       struct file *file;
        ulong handle;
+       struct nvmap_create_handle op;
+       struct nvmap_client *client = filp->private_data;
 
        if (copy_from_user(&op, arg, sizeof(op)))
                return -EFAULT;
@@ -271,29 +267,15 @@ int nvmap_ioctl_getfd(struct file *filp, void __user *arg)
        if (!handle)
                return -EINVAL;
 
-       h = nvmap_get_handle_id(client, handle);
-
-       if (!h)
-               return -EPERM;
-
-       fd = get_unused_fd();
-       if (fd < 0)
-               goto fail_fd;
-
-       file = anon_inode_getfile("nvmap_share_fd",
-                                   &nvmap_fd_fops, h, O_RDWR);
-       if (IS_ERR_OR_NULL(file))
-               goto fail_file;
-       fd_install(fd, file);
+       op.fd = nvmap_get_dmabuf_fd(client, handle);
+       if (op.fd < 0)
+               return op.fd;
 
-       op.fd = fd;
-       return copy_to_user(arg, &op, sizeof(op)) ? -EFAULT : 0;
-
-fail_file:
-       put_unused_fd(fd);
-fail_fd:
-       nvmap_handle_put(h);
-       return -ENFILE;
+       if (copy_to_user(arg, &op, sizeof(op))) {
+               sys_close(op.fd);
+               return -EFAULT;
+       }
+       return 0;
 }
 
 int nvmap_ioctl_alloc(struct file *filp, void __user *arg)
index 60946f5..56ef317 100644 (file)
@@ -3,7 +3,7 @@
  *
  * ioctl declarations for nvmap
  *
- * Copyright (c) 2010-2013, NVIDIA Corporation.
+ * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -196,14 +196,7 @@ int nvmap_ioctl_cache_maint(struct file *filp, void __user *arg);
 
 int nvmap_ioctl_rw_handle(struct file *filp, int is_read, void __user* arg);
 
-#ifdef CONFIG_DMA_SHARED_BUFFER
 int nvmap_ioctl_share_dmabuf(struct file *filp, void __user *arg);
-#else
-static inline int nvmap_ioctl_share_dmabuf(struct file *filp, void __user *arg)
-{
-       return -EINVAL;
-}
-#endif /* !CONFIG_DMA_SHARED_BUFFER */
 
 #endif /* __KERNEL__ */
 
index 9c9efc8..19a11f8 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/wait.h>
 #include <linux/atomic.h>
 #include <linux/dma-buf.h>
+#include <linux/syscalls.h>
 #include <linux/nvmap.h>
 #include "nvmap_heap.h"
 #include <linux/workqueue.h>
@@ -318,16 +319,8 @@ int _nvmap_pin(struct nvmap_client *c, struct nvmap_handle_ref *r,
 void nvmap_unpin_handles(struct nvmap_client *client,
                         struct nvmap_handle **h, int nr);
 
-#ifdef CONFIG_DMA_SHARED_BUFFER
-/* dma-buf exporter */
-struct dma_buf *nvmap_share_dmabuf(struct nvmap_client *client, ulong id);
-#else
-static inline struct dma_buf *nvmap_share_dmabuf(struct nvmap_client *client,
-                                                ulong id)
-{
-       return NULL;
-}
-#endif /* !CONFIG_DMA_SHARED_BUFFER */
+int nvmap_get_dmabuf_fd(struct nvmap_client *client, ulong id);
+ulong nvmap_get_id_from_dmabuf_fd(struct nvmap_client *client, int fd);
 
 #ifdef CONFIG_COMPAT
 ulong unmarshal_user_handle(__u32 handle);