From fef7083e516ff6da4681ea8aaeedc114c6f2c821 Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Tue, 20 Dec 2016 14:48:35 -0800 Subject: gpu: nvgpu: Do not dereference NULL wait_cmd In gk20a_submit_prepare_syncs(), after we have allocated wait_cmd we check the results. If we failed to allocate wait_cmd, we still jump to the error label that tries to free wait_cmd. Create an own error labal for allocation before wait_cmd, and use that if we fail to allocate wait_cmd. Similarly create an error label for incr_cmd, and use that only once incr_cmd has actually been allocated. Change-Id: I1f8bc1d947c524038f5f237358a5e6b0dc2e6ac3 Signed-off-by: Terje Bergstrom Reviewed-on: http://git-master/r/1275742 GVS: Gerrit_Virtual_Submit --- drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'drivers/gpu/nvgpu') diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index 26285729..15170820 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c @@ -2548,11 +2548,16 @@ static int gk20a_submit_prepare_syncs(struct channel_gk20a *c, */ if (flags & NVGPU_SUBMIT_GPFIFO_FLAGS_FENCE_WAIT) { job->pre_fence = gk20a_alloc_fence(c); + if (!job->pre_fence) { + err = -ENOMEM; + goto fail; + } + if (!pre_alloc_enabled) job->wait_cmd = kzalloc(sizeof(struct priv_cmd_entry), GFP_KERNEL); - if (!job->wait_cmd || !job->pre_fence) { + if (!job->wait_cmd) { err = -ENOMEM; goto clean_up_pre_fence; } @@ -2572,7 +2577,7 @@ static int gk20a_submit_prepare_syncs(struct channel_gk20a *c, *wait_cmd = job->wait_cmd; *pre_fence = job->pre_fence; } else - goto clean_up_pre_fence; + goto clean_up_wait_cmd; } if ((flags & NVGPU_SUBMIT_GPFIFO_FLAGS_FENCE_GET) && @@ -2585,11 +2590,15 @@ static int gk20a_submit_prepare_syncs(struct channel_gk20a *c, * sync_pt/semaphore PB is added to the GPFIFO later on in submit. */ job->post_fence = gk20a_alloc_fence(c); + if (!job->post_fence) { + err = -ENOMEM; + goto clean_up_wait_cmd; + } if (!pre_alloc_enabled) job->incr_cmd = kzalloc(sizeof(struct priv_cmd_entry), GFP_KERNEL); - if (!job->incr_cmd || !job->post_fence) { + if (!job->incr_cmd) { err = -ENOMEM; goto clean_up_post_fence; } @@ -2606,25 +2615,27 @@ static int gk20a_submit_prepare_syncs(struct channel_gk20a *c, *incr_cmd = job->incr_cmd; *post_fence = job->post_fence; } else - goto clean_up_post_fence; + goto clean_up_incr_cmd; return 0; +clean_up_incr_cmd: + free_priv_cmdbuf(c, job->incr_cmd); + if (!pre_alloc_enabled) + job->incr_cmd = NULL; clean_up_post_fence: gk20a_fence_put(job->post_fence); job->post_fence = NULL; - free_priv_cmdbuf(c, job->incr_cmd); +clean_up_wait_cmd: + free_priv_cmdbuf(c, job->wait_cmd); if (!pre_alloc_enabled) - job->incr_cmd = NULL; + job->wait_cmd = NULL; clean_up_pre_fence: gk20a_fence_put(job->pre_fence); job->pre_fence = NULL; - free_priv_cmdbuf(c, job->wait_cmd); - if (!pre_alloc_enabled) - job->wait_cmd = NULL; +fail: *wait_cmd = NULL; *pre_fence = NULL; -fail: return err; } -- cgit v1.2.2