gpu: nvgpu: Add ref counting to channels
Alex Waterman [Thu, 13 Oct 2016 17:03:59 +0000 (10:03 -0700)]
Make sure that the VM owned by a channel lives for at least
as long as that channel does. If the channel's VM is cleaned
up before the channel then use-after-free bugs can occur.

Bug: 31680980
NvBug 1825464
Bug: 1885921

Change-Id: I0711781492a764b643c2ed1da1b3ba87fda72744
Signed-off-by: Alex Waterman <alexw@nvidia.com>
Reviewed-on: https://git-psac.nvidia.com/r/#/c/9261
Signed-off-by: Debarshi Dutta <ddutta@nvidia.com>
(cherry picked from commit e205f2720fcee61886e7979e9588602d691507ea)
Reviewed-on: https://git-master.nvidia.com/r/1681801
GVS: Gerrit_Virtual_Submit
Reviewed-by: Bibek Basu <bbasu@nvidia.com>

drivers/gpu/nvgpu/gk20a/channel_gk20a.c
drivers/gpu/nvgpu/gk20a/mm_gk20a.c

index 947b1dc..0a48f6a 100644 (file)
@@ -669,7 +669,7 @@ void gk20a_free_channel(struct channel_gk20a *ch, bool finish)
        memset(&ch->ramfc, 0, sizeof(struct mem_desc_sub));
 
        /* free gpfifo */
-       if (ch->gpfifo.gpu_va)
+       if (ch->vm && ch->gpfifo.gpu_va)
                gk20a_gmmu_unmap(ch_vm, ch->gpfifo.gpu_va,
                        ch->gpfifo.size, gk20a_mem_flag_none);
        if (ch->gpfifo.cpu_va)
@@ -698,8 +698,9 @@ unbind:
        channel_gk20a_unbind(ch);
        channel_gk20a_free_inst(g, ch);
 
-       ch->vpr = false;
+       gk20a_vm_put(ch->vm); /* Don't use VM after this. */
        ch->vm = NULL;
+       ch->vpr = false;
        WARN_ON(ch->sync);
 
        /* unlink all debug sessions */
index 59dc365..5a828d3 100644 (file)
@@ -2427,6 +2427,7 @@ int gk20a_vm_bind_channel(struct gk20a_as_share *as_share,
 
        gk20a_dbg_fn("");
 
+       gk20a_vm_get(vm);
        ch->vm = vm;
        err = channel_gk20a_commit_va(ch);
        if (err)