video: tegra: nvhost: validate nvmap_handle_ref
Bibek Basu [Tue, 8 Jul 2014 08:54:49 +0000 (13:54 +0530)]
nvhost_job_unpin should always get the nvmap_handle_ref
from rb_entry after validating handle and presence
in the tree.

Bug 1478467

Change-Id: Ibf5f64a1a82fea8adbf7500bdb36b76357776448
Signed-off-by: Bibek Basu <bbasu@nvidia.com>
Reviewed-on: http://git-master/r/436076
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Venkat Moganty <vmoganty@nvidia.com>
Reviewed-by: Matthew Pedro <mapedro@nvidia.com>

drivers/video/tegra/host/nvhost_job.c
drivers/video/tegra/host/nvmap.c
drivers/video/tegra/host/nvmap.h
drivers/video/tegra/nvmap/nvmap.c
include/linux/nvmap.h

index f0f7e64..5587f51 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Tegra Graphics Host Job
  *
- * Copyright (c) 2010-2012, NVIDIA Corporation.
+ * Copyright (c) 2010-2014, 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,
@@ -30,6 +30,7 @@
 #include "dev.h"
 #include "nvhost_memmgr.h"
 #include "chip_support.h"
+#include "nvmap.h"
 
 /* Magic to use to fill freed handle slots */
 #define BAD_MAGIC 0xdeadbeef
@@ -327,8 +328,10 @@ void nvhost_job_unpin(struct nvhost_job *job)
        int i;
 
        for (i = 0; i < job->num_unpins; i++) {
-               mem_op().unpin(job->memmgr, job->unpins[i]);
-               mem_op().put(job->memmgr, job->unpins[i]);
+               struct mem_handle *handle;
+               handle = nvhost_nvmap_validate_ref(job->memmgr, job->unpins[i]);
+               mem_op().unpin(job->memmgr, handle);
+               mem_op().put(job->memmgr, handle);
        }
 
        memset(job->unpins, BAD_MAGIC,
index fd82f40..b8361c4 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Tegra Graphics Host Nvmap support
  *
- * Copyright (c) 2012, NVIDIA Corporation.
+ * Copyright (c) 2012-2014, 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,
@@ -82,6 +82,15 @@ struct mem_handle *nvhost_nvmap_get(struct mem_mgr *mgr, u32 id)
                nvmap_duplicate_handle_id((struct nvmap_client *)mgr, id);
 }
 
+struct mem_handle *nvhost_nvmap_validate_ref(struct mem_mgr *mgr,
+                               struct mem_handle *handle)
+{
+       unsigned long ref;
+       ref = nvmap_validate_ref((struct nvmap_client *)mgr,
+                       (struct nvmap_handle_ref *)handle);
+       return (struct mem_handle *)ref;
+}
+
 int nvhost_init_nvmap_support(struct nvhost_chip_support *chip)
 {
        chip->mem.alloc_mgr = nvhost_nvmap_alloc_mgr;
index 90f64d4..25e3535 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Tegra Graphics Host nvmap memory manager
  *
- * Copyright (c) 2010-2012, NVIDIA Corporation.
+ * Copyright (c) 2010-2014, 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,
@@ -23,5 +23,6 @@
 
 struct nvhost_chip_support;
 int nvhost_init_nvmap_support(struct nvhost_chip_support *op);
-
+struct mem_handle *nvhost_nvmap_validate_ref(struct mem_mgr *mgr,
+                               struct mem_handle *handle);
 #endif
index 19b821d..07463f7 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Memory manager for Tegra GPU
  *
- * Copyright (c) 2009-2012, NVIDIA Corporation.
+ * Copyright (c) 2009-2014, 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
@@ -366,7 +366,6 @@ phys_addr_t nvmap_pin(struct nvmap_client *client,
        h = nvmap_handle_get(ref->handle);
        if (WARN_ON(!h))
                return -EINVAL;
-
        atomic_inc(&ref->pin);
 
        if (WARN_ON(mutex_lock_interruptible(&client->share->pin_lock))) {
@@ -384,7 +383,6 @@ phys_addr_t nvmap_pin(struct nvmap_client *client,
                        map_iovmm_area(h);
                phys = handle_phys(h);
        }
-
        return ret ?: phys;
 }
 
@@ -618,3 +616,15 @@ int nvmap_mark_global(struct nvmap_client *client, struct nvmap_handle_ref *r)
 
        return 0;
 }
+
+unsigned long nvmap_validate_ref(struct nvmap_client *client,
+                               struct nvmap_handle_ref *r)
+{
+       struct nvmap_handle_ref *ref;
+       unsigned long id = nvmap_ref_to_id(r);
+
+       nvmap_ref_lock(client);
+       ref = _nvmap_validate_id_locked(client, id);
+       nvmap_ref_unlock(client);
+       return (unsigned long)ref;
+}
index 9cc978e..c805f4c 100644 (file)
@@ -3,7 +3,7 @@
  *
  * structure declarations for nvmem and nvmap user-space ioctls
  *
- * Copyright (c) 2009-2012, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2009-2014, 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
@@ -126,6 +126,9 @@ struct nvmap_handle_ref *nvmap_duplicate_handle_id(struct nvmap_client *client,
 
 int nvmap_mark_global(struct nvmap_client *client, struct nvmap_handle_ref *r);
 
+unsigned long nvmap_validate_ref(struct nvmap_client *client,
+                               struct nvmap_handle_ref *r);
+
 struct nvmap_platform_carveout {
        const char *name;
        unsigned int usage_mask;