aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-01-08 18:13:20 -0500
committerDave Airlie <airlied@redhat.com>2017-01-08 18:13:26 -0500
commit6906407eeb690ed31b183a38ae10db2907cc3a58 (patch)
treef31d9bdd67bd74523e3dd5ac9e89490ec68361fd
parent90e5d2d45776451e58989361a182c067008d5941 (diff)
parenta6cb3b864b21b7345f824a4faa12b723c8aaf099 (diff)
Merge branch 'msm-fixes-4.10' of git://people.freedesktop.org/~robclark/linux into drm-fixes
A few fixes for 4.10.. the first fixes a long-standing logic bug, that by luck (ie. size of packets written into RB for a submit) wasn't hit on a3xx/a4xx but was causing intermittent GPU lockups on a5xx. And a couple other robustness issues that Jordan noticed. * 'msm-fixes-4.10' of git://people.freedesktop.org/~robclark/linux: drm/msm: Verify that MSM_SUBMIT_BO_FLAGS are set drm/msm: Put back the vaddr in submit_reloc() drm/msm: Ensure that the hardware write pointer is valid
-rw-r--r--drivers/gpu/drm/msm/adreno/adreno_gpu.c9
-rw-r--r--drivers/gpu/drm/msm/msm_gem_submit.c18
-rw-r--r--drivers/gpu/drm/msm/msm_ringbuffer.c3
3 files changed, 21 insertions, 9 deletions
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index a18126150e11..14ff87686a36 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -213,7 +213,14 @@ void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
213void adreno_flush(struct msm_gpu *gpu) 213void adreno_flush(struct msm_gpu *gpu)
214{ 214{
215 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); 215 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
216 uint32_t wptr = get_wptr(gpu->rb); 216 uint32_t wptr;
217
218 /*
219 * Mask wptr value that we calculate to fit in the HW range. This is
220 * to account for the possibility that the last command fit exactly into
221 * the ringbuffer and rb->next hasn't wrapped to zero yet
222 */
223 wptr = get_wptr(gpu->rb) & ((gpu->rb->size / 4) - 1);
217 224
218 /* ensure writes to ringbuffer have hit system memory: */ 225 /* ensure writes to ringbuffer have hit system memory: */
219 mb(); 226 mb();
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
index 166e84e4f0d4..489676568a10 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -106,7 +106,8 @@ static int submit_lookup_objects(struct msm_gem_submit *submit,
106 pagefault_disable(); 106 pagefault_disable();
107 } 107 }
108 108
109 if (submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) { 109 if ((submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) ||
110 !(submit_bo.flags & MSM_SUBMIT_BO_FLAGS)) {
110 DRM_ERROR("invalid flags: %x\n", submit_bo.flags); 111 DRM_ERROR("invalid flags: %x\n", submit_bo.flags);
111 ret = -EINVAL; 112 ret = -EINVAL;
112 goto out_unlock; 113 goto out_unlock;
@@ -290,7 +291,7 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob
290{ 291{
291 uint32_t i, last_offset = 0; 292 uint32_t i, last_offset = 0;
292 uint32_t *ptr; 293 uint32_t *ptr;
293 int ret; 294 int ret = 0;
294 295
295 if (offset % 4) { 296 if (offset % 4) {
296 DRM_ERROR("non-aligned cmdstream buffer: %u\n", offset); 297 DRM_ERROR("non-aligned cmdstream buffer: %u\n", offset);
@@ -318,12 +319,13 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob
318 319
319 ret = copy_from_user(&submit_reloc, userptr, sizeof(submit_reloc)); 320 ret = copy_from_user(&submit_reloc, userptr, sizeof(submit_reloc));
320 if (ret) 321 if (ret)
321 return -EFAULT; 322 goto out;
322 323
323 if (submit_reloc.submit_offset % 4) { 324 if (submit_reloc.submit_offset % 4) {
324 DRM_ERROR("non-aligned reloc offset: %u\n", 325 DRM_ERROR("non-aligned reloc offset: %u\n",
325 submit_reloc.submit_offset); 326 submit_reloc.submit_offset);
326 return -EINVAL; 327 ret = -EINVAL;
328 goto out;
327 } 329 }
328 330
329 /* offset in dwords: */ 331 /* offset in dwords: */
@@ -332,12 +334,13 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob
332 if ((off >= (obj->base.size / 4)) || 334 if ((off >= (obj->base.size / 4)) ||
333 (off < last_offset)) { 335 (off < last_offset)) {
334 DRM_ERROR("invalid offset %u at reloc %u\n", off, i); 336 DRM_ERROR("invalid offset %u at reloc %u\n", off, i);
335 return -EINVAL; 337 ret = -EINVAL;
338 goto out;
336 } 339 }
337 340
338 ret = submit_bo(submit, submit_reloc.reloc_idx, NULL, &iova, &valid); 341 ret = submit_bo(submit, submit_reloc.reloc_idx, NULL, &iova, &valid);
339 if (ret) 342 if (ret)
340 return ret; 343 goto out;
341 344
342 if (valid) 345 if (valid)
343 continue; 346 continue;
@@ -354,9 +357,10 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob
354 last_offset = off; 357 last_offset = off;
355 } 358 }
356 359
360out:
357 msm_gem_put_vaddr_locked(&obj->base); 361 msm_gem_put_vaddr_locked(&obj->base);
358 362
359 return 0; 363 return ret;
360} 364}
361 365
362static void submit_cleanup(struct msm_gem_submit *submit) 366static void submit_cleanup(struct msm_gem_submit *submit)
diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c
index f326cf6a32e6..67b34e069abf 100644
--- a/drivers/gpu/drm/msm/msm_ringbuffer.c
+++ b/drivers/gpu/drm/msm/msm_ringbuffer.c
@@ -23,7 +23,8 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int size)
23 struct msm_ringbuffer *ring; 23 struct msm_ringbuffer *ring;
24 int ret; 24 int ret;
25 25
26 size = ALIGN(size, 4); /* size should be dword aligned */ 26 if (WARN_ON(!is_power_of_2(size)))
27 return ERR_PTR(-EINVAL);
27 28
28 ring = kzalloc(sizeof(*ring), GFP_KERNEL); 29 ring = kzalloc(sizeof(*ring), GFP_KERNEL);
29 if (!ring) { 30 if (!ring) {