diff options
author | Deepak <dbhosale@nvidia.com> | 2018-10-24 20:46:09 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2018-12-12 23:45:36 -0500 |
commit | 2d3e99067ea47d66a9490c405dcebc46e7fcdf03 (patch) | |
tree | 73bb05318d79d44569282ce42d06f0d3b1285c7f /drivers/gpu/nvgpu/vgpu | |
parent | d6278955f66dbfb5f992f9298e32ca86d66c6259 (diff) |
gpu: nvgpu: vgpu: Get channel reference
- In vGPU code path, function vgpu_channel_abort_cleanup() does not
obtain channel reference before using the channel structure
(channel_gk20a)
- vgpu_channel_abort_cleanup() is called by vgpu_intr_thread() which
runs commands obtained from interrupt queue from RM server.
- If there is a scenario where gk20a_channel_release() function runs
before guest receives notification from RM server to abort channel
cleanup, channel gets freed before vgpu_channel_abort_cleanup() runs.
- However, because vgpu_channel_abort_cleanup() does not take explicit
reference to the channel, it ends up accessing structures
(such as ch->g) which are set to NULL and thus we end up in a crash.
- This patch explicitly takes reference of channel before
vgpu_channel_abort_cleanup() is called.
- If gk20a_channel_release() runs before vgpu_channel_abort_cleanup()
and ends up freeing channel, we dont get reference to freed
channel in vgpu_channel_abort_cleanup() and thus we return from
function rather than continuing with freed channel as was the case
previously.
Bug 200453473
JIRA EVLR-3411
Change-Id: I311043b2231336616b28246531cf8a0dc151b0cd
Signed-off-by: Deepak Bhosale <dbhosale@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1932028
(cherry picked from commit b91228e506c14f04945e35b5c996f711bb30a155)
Reviewed-on: https://git-master.nvidia.com/r/1970807
Reviewed-by: Aparna Das <aparnad@nvidia.com>
Reviewed-by: Automatic_Commit_Validation_User
Tested-by: Karl Ding <kding@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Nirav Patel <nipatel@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/vgpu')
-rw-r--r-- | drivers/gpu/nvgpu/vgpu/vgpu.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/gpu/nvgpu/vgpu/vgpu.c b/drivers/gpu/nvgpu/vgpu/vgpu.c index 7d7df9b3..266b801e 100644 --- a/drivers/gpu/nvgpu/vgpu/vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/vgpu.c | |||
@@ -119,10 +119,16 @@ static void vgpu_handle_channel_event(struct gk20a *g, | |||
119 | 119 | ||
120 | static void vgpu_channel_abort_cleanup(struct gk20a *g, u32 chid) | 120 | static void vgpu_channel_abort_cleanup(struct gk20a *g, u32 chid) |
121 | { | 121 | { |
122 | struct channel_gk20a *ch = &g->fifo.channel[chid]; | 122 | struct channel_gk20a *ch = gk20a_channel_get(&g->fifo.channel[chid]); |
123 | |||
124 | if (ch == NULL) { | ||
125 | nvgpu_err(g, "invalid channel id %d", chid); | ||
126 | return; | ||
127 | } | ||
123 | 128 | ||
124 | ch->has_timedout = true; | 129 | ch->has_timedout = true; |
125 | g->ops.fifo.ch_abort_clean_up(ch); | 130 | g->ops.fifo.ch_abort_clean_up(ch); |
131 | gk20a_channel_put(ch); | ||
126 | } | 132 | } |
127 | 133 | ||
128 | static void vgpu_set_error_notifier(struct gk20a *g, | 134 | static void vgpu_set_error_notifier(struct gk20a *g, |