]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
video: tegra: nvmap: Add cache list IOCTL
authorSri Krishna chowdary <schowdary@nvidia.com>
Thu, 3 Apr 2014 10:39:16 +0000 (16:09 +0530)
committerTony Ly <tly@nvidia.com>
Wed, 7 May 2014 18:51:36 +0000 (11:51 -0700)
Bug 1423574
Bug 1373180

Change-Id: I0fe2bf588a3f33692efa398874bad807e6b045e5
Signed-off-by: Sri Krishna chowdary <schowdary@nvidia.com>
Reviewed-on: http://git-master/r/392389
(cherry picked from commit 79c71b97db52ec5b28aba60c2331f397e7dc1b7e)
Reviewed-on: http://git-master/r/405133
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
GVS: Gerrit_Virtual_Submit

drivers/video/tegra/nvmap/nvmap_dev.c
drivers/video/tegra/nvmap/nvmap_ioctl.c
drivers/video/tegra/nvmap/nvmap_mm.c
include/linux/nvmap.h

index 82cccea2714e476761febcf587d586bd74fcea06..4372795dc14dd5ad81e94d6c895a3f3253739721 100644 (file)
@@ -725,6 +725,10 @@ static long nvmap_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                err = nvmap_ioctl_cache_maint(filp, uarg, false);
                break;
 
+       case NVMAP_IOC_CACHE_LIST:
+               err = nvmap_ioctl_cache_maint_list(filp, uarg);
+               break;
+
        case NVMAP_IOC_SHARE:
                err = nvmap_ioctl_share_dmabuf(filp, uarg);
                break;
index 17f6897de86163ebd3f18ea0d3419dd4e46f1f79..eda48786e995a68dde0cdc4c0b3a7cda39e902a8 100644 (file)
@@ -1121,3 +1121,61 @@ static ssize_t rw_handle(struct nvmap_client *client, struct nvmap_handle *h,
        nvmap_free_pte(nvmap_dev, pte);
        return ret ?: copied;
 }
+
+int nvmap_ioctl_cache_maint_list(struct file *filp, void __user *arg)
+{
+       struct nvmap_cache_op_list op;
+       u32 *handle_ptr;
+       u32 *offset_ptr;
+       u32 *size_ptr;
+       struct nvmap_handle **refs;
+       int i, err = 0;
+
+       if (copy_from_user(&op, arg, sizeof(op)))
+               return -EFAULT;
+
+       if (!op.nr)
+               return -EINVAL;
+
+       if (!access_ok(VERIFY_READ, op.handles, op.nr * sizeof(u32)))
+               return -EFAULT;
+
+       if (!access_ok(VERIFY_READ, op.offsets, op.nr * sizeof(u32)))
+               return -EFAULT;
+
+       if (!access_ok(VERIFY_READ, op.sizes, op.nr * sizeof(u32)))
+               return -EFAULT;
+
+       if (!op.offsets || !op.sizes)
+               return -EINVAL;
+
+       refs = kcalloc(op.nr, sizeof(*refs), GFP_KERNEL);
+
+       if (!refs)
+               return -ENOMEM;
+
+       handle_ptr = (u32 *)(uintptr_t)op.handles;
+       offset_ptr = (u32 *)(uintptr_t)op.offsets;
+       size_ptr = (u32 *)(uintptr_t)op.sizes;
+
+       for (i = 0; i < op.nr; i++) {
+               u32 handle;
+
+               if (copy_from_user(&handle, &handle_ptr[i], sizeof(handle))) {
+                       err = -EFAULT;
+                       goto free_mem;
+               }
+
+               refs[i] = unmarshal_user_handle(handle);
+               if (!refs[i]) {
+                       err = -EINVAL;
+                       goto free_mem;
+               }
+       }
+
+       err = nvmap_do_cache_maint_list(refs, offset_ptr, size_ptr, op.op, op.nr);
+
+free_mem:
+       kfree(refs);
+       return err;
+}
index cbeec83f831264e328a0718b71eb13e7ce2cb514..3417ccda1b7b795d4c7bc16d17a68a4002f42fc1 100644 (file)
@@ -101,14 +101,11 @@ void nvmap_flush_cache(struct page **pages, int numpages)
 int nvmap_do_cache_maint_list(struct nvmap_handle **handles, u32 *offsets,
                              u32 *sizes, int op, int nr)
 {
-       int i, err = 0;
+       int i;
        u64 total = 0;
 
-       for (i = 0; i < nr; i++) {
-               offsets[i] = sizes[i] ? offsets[i] : 0;
-               sizes[i] = sizes[i] ? sizes[i] : handles[i]->size;
-               total += sizes[i];
-       }
+       for (i = 0; i < nr; i++)
+               total += sizes[i] ? sizes[i] : handles[i]->size;
 
        /* Full flush in the case the passed list is bigger than our
         * threshold. */
@@ -128,16 +125,18 @@ int nvmap_do_cache_maint_list(struct nvmap_handle **handles, u32 *offsets,
                                        nvmap_stats_read(NS_CFLUSH_DONE));
        } else {
                for (i = 0; i < nr; i++) {
-                       err = __nvmap_do_cache_maint(handles[i]->owner,
-                                                    handles[i], offsets[i],
-                                                    offsets[i] + sizes[i],
-                                                    op, false);
+                       u32 size = sizes[i] ? sizes[i] : handles[i]->size;
+                       u32 offset = sizes[i] ? offsets[i] : 0;
+                       int err = __nvmap_do_cache_maint(handles[i]->owner,
+                                                        handles[i], offset,
+                                                        offset + size,
+                                                        op, false);
                        if (err)
-                               break;
+                               return err;
                }
        }
 
-       return err;
+       return 0;
 }
 
 void nvmap_zap_handle(struct nvmap_handle *handle,
index 706d462dbb83b59d920c9de7de208c587777a5f7..855f0074301b3e8caecc5d0465a587ee2a69a7c9 100644 (file)
@@ -236,12 +236,13 @@ struct nvmap_cache_op_32 {
 #endif
 
 struct nvmap_cache_op_list {
-#ifdef CONFIG_COMPAT
-       __u32 handles;          /* Uspace ptr to list of handles */
-#else
-       struct nvmap_handle **handles;
-#endif
+       __u64 handles;          /* Ptr to u32 type array, holding handles */
+       __u64 offsets;          /* Ptr to u32 type array, holding offsets
+                                * into handle mem */
+       __u64 sizes;            /* Ptr to u32 type array, holindg sizes of memory
+                                * regions within each handle */
        __u32 nr;               /* Number of handles */
+       __s32 op;               /* wb/wb_inv/inv */
 };
 
 #define NVMAP_IOC_MAGIC 'N'