summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
diff options
context:
space:
mode:
authorAlex Waterman <alexw@nvidia.com>2015-06-03 16:41:04 -0400
committerTerje Bergstrom <tbergstrom@nvidia.com>2015-06-04 13:40:40 -0400
commit56d7896731c91595db3205777f308fbcaeac7340 (patch)
tree643d153aa24ffc6309463c1749b6c0de698c3427 /drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
parent1d8fdf56959240622073dd771dd9bfccf31b8f8e (diff)
gpu: nvgpu: Fix invalid GPFIFO entries
With the addition of the buddy allocator often times push buffers are allocated by the kernel in high GVA memory regions. These addresses, when written into a GPFIFO entry, have bits set in entry1 of the GPFIFO command. As a result, if no length is set, then these address bits will be interpreted as opcodes by the GPU. The bug fixed by this patch was caused by a wait_cmd being inserted into the GPFIFO with an address of a pushbuffer above 4GB and a zero length. This occured becasue the code that creates the wait_cmd was able to return what appeared to be a valid priv_cmd_entry even though there was nothing in that command. This bug does not appear before the buddy allocator because the FFF allocator always starts allocating from low addresses. As such when a channel's GPFIFO is allocated it gets an address below 32bits. The, because no higher address bits are set, entry1 of the GPFIFO is simply 0 and the GPU trets the command as a no-op. Change-Id: I9c1e600c368b55626e99f6f712f1821148bbb76d Signed-off-by: Alex Waterman <alexw@nvidia.com> Reviewed-on: http://git-master/r/752080 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
index b5bd6bf7..9b4b756d 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
@@ -113,6 +113,9 @@ static int gk20a_channel_syncpt_wait_fd(struct gk20a_channel_sync *s, int fd,
113 } 113 }
114 114
115 num_wait_cmds = nvhost_sync_num_pts(sync_fence); 115 num_wait_cmds = nvhost_sync_num_pts(sync_fence);
116 if (num_wait_cmds == 0)
117 return 0;
118
116 gk20a_channel_alloc_priv_cmdbuf(c, 4 * num_wait_cmds, &wait_cmd); 119 gk20a_channel_alloc_priv_cmdbuf(c, 4 * num_wait_cmds, &wait_cmd);
117 if (wait_cmd == NULL) { 120 if (wait_cmd == NULL) {
118 gk20a_err(dev_from_gk20a(c->g), 121 gk20a_err(dev_from_gk20a(c->g),