]> Git Repo - linux.git/commitdiff
Merge branch 'etnaviv/fixes' of https://git.pengutronix.de/git/lst/linux into drm...
authorDave Airlie <[email protected]>
Wed, 27 Sep 2017 19:48:53 +0000 (05:48 +1000)
committerDave Airlie <[email protected]>
Wed, 27 Sep 2017 19:48:53 +0000 (05:48 +1000)
Just two small etnaviv fixes, one fixing a list corruption, the other
fixing a NULL ptr deref in an error path.

* 'etnaviv/fixes' of https://git.pengutronix.de/git/lst/linux:
  etnaviv: fix gem object list corruption
  etnaviv: fix submit error path

1  2 
drivers/gpu/drm/etnaviv/etnaviv_gem.c
drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c

index 5a634594a6cea2d2be20e19a0e359229a860775c,87b95eeedd9e84ea1733b1f004c5f37c72f34bb1..57881167ccd22c9c16df18e1d93401edef2e1f82
@@@ -68,7 -68,7 +68,7 @@@ static int etnaviv_gem_shmem_get_pages(
        struct page **p = drm_gem_get_pages(&etnaviv_obj->base);
  
        if (IS_ERR(p)) {
 -              dev_err(dev->dev, "could not get pages: %ld\n", PTR_ERR(p));
 +              dev_dbg(dev->dev, "could not get pages: %ld\n", PTR_ERR(p));
                return PTR_ERR(p);
        }
  
@@@ -265,7 -265,7 +265,7 @@@ void etnaviv_gem_mapping_reference(stru
  {
        struct etnaviv_gem_object *etnaviv_obj = mapping->object;
  
 -      drm_gem_object_reference(&etnaviv_obj->base);
 +      drm_gem_object_get(&etnaviv_obj->base);
  
        mutex_lock(&etnaviv_obj->lock);
        WARN_ON(mapping->use == 0);
@@@ -282,7 -282,7 +282,7 @@@ void etnaviv_gem_mapping_unreference(st
        mapping->use -= 1;
        mutex_unlock(&etnaviv_obj->lock);
  
 -      drm_gem_object_unreference_unlocked(&etnaviv_obj->base);
 +      drm_gem_object_put_unlocked(&etnaviv_obj->base);
  }
  
  struct etnaviv_vram_mapping *etnaviv_gem_mapping_get(
@@@ -358,7 -358,7 +358,7 @@@ out
                return ERR_PTR(ret);
  
        /* Take a reference on the object */
 -      drm_gem_object_reference(obj);
 +      drm_gem_object_get(obj);
        return mapping;
  }
  
@@@ -413,16 -413,6 +413,16 @@@ int etnaviv_gem_cpu_prep(struct drm_gem
        bool write = !!(op & ETNA_PREP_WRITE);
        int ret;
  
 +      if (!etnaviv_obj->sgt) {
 +              void *ret;
 +
 +              mutex_lock(&etnaviv_obj->lock);
 +              ret = etnaviv_gem_get_pages(etnaviv_obj);
 +              mutex_unlock(&etnaviv_obj->lock);
 +              if (IS_ERR(ret))
 +                      return PTR_ERR(ret);
 +      }
 +
        if (op & ETNA_PREP_NOSYNC) {
                if (!reservation_object_test_signaled_rcu(etnaviv_obj->resv,
                                                          write))
        }
  
        if (etnaviv_obj->flags & ETNA_BO_CACHED) {
 -              if (!etnaviv_obj->sgt) {
 -                      void *ret;
 -
 -                      mutex_lock(&etnaviv_obj->lock);
 -                      ret = etnaviv_gem_get_pages(etnaviv_obj);
 -                      mutex_unlock(&etnaviv_obj->lock);
 -                      if (IS_ERR(ret))
 -                              return PTR_ERR(ret);
 -              }
 -
                dma_sync_sg_for_cpu(dev->dev, etnaviv_obj->sgt->sgl,
                                    etnaviv_obj->sgt->nents,
                                    etnaviv_op_to_dma_dir(op));
@@@ -551,12 -551,15 +551,15 @@@ static const struct etnaviv_gem_ops etn
  void etnaviv_gem_free_object(struct drm_gem_object *obj)
  {
        struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);
+       struct etnaviv_drm_private *priv = obj->dev->dev_private;
        struct etnaviv_vram_mapping *mapping, *tmp;
  
        /* object should not be active */
        WARN_ON(is_active(etnaviv_obj));
  
+       mutex_lock(&priv->gem_lock);
        list_del(&etnaviv_obj->gem_node);
+       mutex_unlock(&priv->gem_lock);
  
        list_for_each_entry_safe(mapping, tmp, &etnaviv_obj->vram_list,
                                 obj_node) {
@@@ -662,8 -665,7 +665,8 @@@ static struct drm_gem_object *__etnaviv
                 * going to pin these pages.
                 */
                mapping = obj->filp->f_mapping;
 -              mapping_set_gfp_mask(mapping, GFP_HIGHUSER);
 +              mapping_set_gfp_mask(mapping, GFP_HIGHUSER |
 +                                   __GFP_RETRY_MAYFAIL | __GFP_NOWARN);
        }
  
        if (ret)
        return obj;
  
  fail:
 -      drm_gem_object_unreference_unlocked(obj);
 +      drm_gem_object_put_unlocked(obj);
        return ERR_PTR(ret);
  }
  
@@@ -689,14 -691,14 +692,14 @@@ int etnaviv_gem_new_handle(struct drm_d
  
        ret = etnaviv_gem_obj_add(dev, obj);
        if (ret < 0) {
 -              drm_gem_object_unreference_unlocked(obj);
 +              drm_gem_object_put_unlocked(obj);
                return ret;
        }
  
        ret = drm_gem_handle_create(file, obj, handle);
  
        /* drop reference from allocate - handle holds it now */
 -      drm_gem_object_unreference_unlocked(obj);
 +      drm_gem_object_put_unlocked(obj);
  
        return ret;
  }
@@@ -713,7 -715,7 +716,7 @@@ struct drm_gem_object *etnaviv_gem_new(
  
        ret = etnaviv_gem_obj_add(dev, obj);
        if (ret < 0) {
 -              drm_gem_object_unreference_unlocked(obj);
 +              drm_gem_object_put_unlocked(obj);
                return ERR_PTR(ret);
        }
  
@@@ -801,7 -803,7 +804,7 @@@ static void __etnaviv_gem_userptr_get_p
        }
  
        mutex_unlock(&etnaviv_obj->lock);
 -      drm_gem_object_unreference_unlocked(&etnaviv_obj->base);
 +      drm_gem_object_put_unlocked(&etnaviv_obj->base);
  
        mmput(work->mm);
        put_task_struct(work->task);
@@@ -859,7 -861,7 +862,7 @@@ static int etnaviv_gem_userptr_get_page
        }
  
        get_task_struct(current);
 -      drm_gem_object_reference(&etnaviv_obj->base);
 +      drm_gem_object_get(&etnaviv_obj->base);
  
        work->mm = mm;
        work->task = current;
@@@ -925,6 -927,6 +928,6 @@@ int etnaviv_gem_new_userptr(struct drm_
        ret = drm_gem_handle_create(file, &etnaviv_obj->base, handle);
  unreference:
        /* drop reference from allocate - handle holds it now */
 -      drm_gem_object_unreference_unlocked(&etnaviv_obj->base);
 +      drm_gem_object_put_unlocked(&etnaviv_obj->base);
        return ret;
  }
index 026ef4e02f85cab130586c5c0b8c9b97bd0101bb,b95362186f9c8bc927b48fe6b10f9b1d71470a92..46dfe0737f438d37e4e65dec320e9a7e773e3856
@@@ -37,7 -37,7 +37,7 @@@ static struct etnaviv_gem_submit *submi
        struct etnaviv_gem_submit *submit;
        size_t sz = size_vstruct(nr, sizeof(submit->bos[0]), sizeof(*submit));
  
 -      submit = kmalloc(sz, GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY);
 +      submit = kmalloc(sz, GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
        if (submit) {
                submit->dev = dev;
                submit->gpu = gpu;
@@@ -88,7 -88,7 +88,7 @@@ static int submit_lookup_objects(struc
                 * Take a refcount on the object. The file table lock
                 * prevents the object_idr's refcount on this being dropped.
                 */
 -              drm_gem_object_reference(obj);
 +              drm_gem_object_get(obj);
  
                submit->bos[i].obj = to_etnaviv_bo(obj);
        }
@@@ -291,7 -291,7 +291,7 @@@ static void submit_cleanup(struct etnav
                struct etnaviv_gem_object *etnaviv_obj = submit->bos[i].obj;
  
                submit_unlock_object(submit, i);
 -              drm_gem_object_unreference_unlocked(&etnaviv_obj->base);
 +              drm_gem_object_put_unlocked(&etnaviv_obj->base);
        }
  
        ww_acquire_fini(&submit->ticket);
@@@ -445,8 -445,10 +445,10 @@@ int etnaviv_ioctl_gem_submit(struct drm
        cmdbuf->user_size = ALIGN(args->stream_size, 8);
  
        ret = etnaviv_gpu_submit(gpu, submit, cmdbuf);
-       if (ret == 0)
-               cmdbuf = NULL;
+       if (ret)
+               goto out;
+       cmdbuf = NULL;
  
        if (args->flags & ETNA_SUBMIT_FENCE_FD_OUT) {
                /*
This page took 0.070604 seconds and 4 git commands to generate.