gpu: nvgpu: sanitize gk20a_vm_alloc_share()
Sami Kiminki [Wed, 5 Nov 2014 18:34:25 +0000 (20:34 +0200)]
Add sanity check for big_page_size parameter to avoid invoking
gk20a_init_vm() with a bogus big page size, potentially hitting a
BUG_ON there. Also, reorganize the code a bit to avoid memory leak in
case of bogus big page size, and properly forward the return value
from gk20a_init_vm().

Change-Id: I4eeada75415d2e9539b5e8859099cce35cd86db3
Signed-off-by: Sami Kiminki <skiminki@nvidia.com>
Reviewed-on: http://git-master/r/594469
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>

drivers/gpu/nvgpu/gk20a/mm_gk20a.c

index 1cdb2f8..e4186c9 100644 (file)
@@ -2341,10 +2341,19 @@ int gk20a_vm_alloc_share(struct gk20a_as_share *as_share, u32 big_page_size)
        struct vm_gk20a *vm;
        char name[32];
        int err;
-       u32 default_big_page_size;
 
        gk20a_dbg_fn("");
 
+       if (big_page_size == 0)
+               big_page_size =
+                       gk20a_get_platform(g->dev)->default_big_page_size;
+
+       if (!is_power_of_2(big_page_size))
+               return -EINVAL;
+
+       if (!(big_page_size & g->gpu_characteristics.available_big_page_sizes))
+               return -EINVAL;
+
        vm = kzalloc(sizeof(*vm), GFP_KERNEL);
        if (!vm)
                return -ENOMEM;
@@ -2355,20 +2364,10 @@ int gk20a_vm_alloc_share(struct gk20a_as_share *as_share, u32 big_page_size)
 
        snprintf(name, sizeof(name), "gk20a_as_%d", as_share->id);
 
-       default_big_page_size =
-               gk20a_get_platform(g->dev)->default_big_page_size;
-
-       if (big_page_size == 0)
-               big_page_size = default_big_page_size;
-
-       if (big_page_size != default_big_page_size &&
-           !g->ops.mm.set_big_page_size)
-               return -EINVAL;
-
        err = gk20a_init_vm(mm, vm, big_page_size, big_page_size << 10,
                            mm->channel.size, true, name);
 
-       return 0;
+       return err;
 }
 
 int gk20a_vm_release_share(struct gk20a_as_share *as_share)