Commit 6906407e authored by Dave Airlie's avatar Dave Airlie

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
parents 90e5d2d4 a6cb3b86
...@@ -213,7 +213,14 @@ void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, ...@@ -213,7 +213,14 @@ void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
void adreno_flush(struct msm_gpu *gpu) void adreno_flush(struct msm_gpu *gpu)
{ {
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
uint32_t wptr = get_wptr(gpu->rb); uint32_t wptr;
/*
* Mask wptr value that we calculate to fit in the HW range. This is
* to account for the possibility that the last command fit exactly into
* the ringbuffer and rb->next hasn't wrapped to zero yet
*/
wptr = get_wptr(gpu->rb) & ((gpu->rb->size / 4) - 1);
/* ensure writes to ringbuffer have hit system memory: */ /* ensure writes to ringbuffer have hit system memory: */
mb(); mb();
......
...@@ -106,7 +106,8 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, ...@@ -106,7 +106,8 @@ static int submit_lookup_objects(struct msm_gem_submit *submit,
pagefault_disable(); pagefault_disable();
} }
if (submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) { if ((submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) ||
!(submit_bo.flags & MSM_SUBMIT_BO_FLAGS)) {
DRM_ERROR("invalid flags: %x\n", submit_bo.flags); DRM_ERROR("invalid flags: %x\n", submit_bo.flags);
ret = -EINVAL; ret = -EINVAL;
goto out_unlock; goto out_unlock;
...@@ -290,7 +291,7 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob ...@@ -290,7 +291,7 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob
{ {
uint32_t i, last_offset = 0; uint32_t i, last_offset = 0;
uint32_t *ptr; uint32_t *ptr;
int ret; int ret = 0;
if (offset % 4) { if (offset % 4) {
DRM_ERROR("non-aligned cmdstream buffer: %u\n", offset); 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,12 +319,13 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob
ret = copy_from_user(&submit_reloc, userptr, sizeof(submit_reloc)); ret = copy_from_user(&submit_reloc, userptr, sizeof(submit_reloc));
if (ret) if (ret)
return -EFAULT; goto out;
if (submit_reloc.submit_offset % 4) { if (submit_reloc.submit_offset % 4) {
DRM_ERROR("non-aligned reloc offset: %u\n", DRM_ERROR("non-aligned reloc offset: %u\n",
submit_reloc.submit_offset); submit_reloc.submit_offset);
return -EINVAL; ret = -EINVAL;
goto out;
} }
/* offset in dwords: */ /* offset in dwords: */
...@@ -332,12 +334,13 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob ...@@ -332,12 +334,13 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob
if ((off >= (obj->base.size / 4)) || if ((off >= (obj->base.size / 4)) ||
(off < last_offset)) { (off < last_offset)) {
DRM_ERROR("invalid offset %u at reloc %u\n", off, i); DRM_ERROR("invalid offset %u at reloc %u\n", off, i);
return -EINVAL; ret = -EINVAL;
goto out;
} }
ret = submit_bo(submit, submit_reloc.reloc_idx, NULL, &iova, &valid); ret = submit_bo(submit, submit_reloc.reloc_idx, NULL, &iova, &valid);
if (ret) if (ret)
return ret; goto out;
if (valid) if (valid)
continue; continue;
...@@ -354,9 +357,10 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob ...@@ -354,9 +357,10 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob
last_offset = off; last_offset = off;
} }
out:
msm_gem_put_vaddr_locked(&obj->base); msm_gem_put_vaddr_locked(&obj->base);
return 0; return ret;
} }
static void submit_cleanup(struct msm_gem_submit *submit) static void submit_cleanup(struct msm_gem_submit *submit)
......
...@@ -23,7 +23,8 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int size) ...@@ -23,7 +23,8 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int size)
struct msm_ringbuffer *ring; struct msm_ringbuffer *ring;
int ret; int ret;
size = ALIGN(size, 4); /* size should be dword aligned */ if (WARN_ON(!is_power_of_2(size)))
return ERR_PTR(-EINVAL);
ring = kzalloc(sizeof(*ring), GFP_KERNEL); ring = kzalloc(sizeof(*ring), GFP_KERNEL);
if (!ring) { if (!ring) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment