diff mbox series

[8/9] drm/shmem-helpers: Ensure get_pages is not called on imported dma-buf

Message ID 20200511093554.211493-9-daniel.vetter@ffwll.ch (mailing list archive)
State New, archived
Headers show
Series shmem helper untangling | expand

Commit Message

Daniel Vetter May 11, 2020, 9:35 a.m. UTC
Just a bit of light paranoia. Also sprinkle this check over
drm_gem_shmem_get_sg_table, which should only be called when
exporting, same for the pin/unpin functions, on which it relies to
work correctly.

Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Noralf Trønnes <noralf@tronnes.org>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_gem_shmem_helper.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

Comments

Thomas Zimmermann May 14, 2020, 7:30 a.m. UTC | #1
Hi

Am 11.05.20 um 11:35 schrieb Daniel Vetter:
> Just a bit of light paranoia. Also sprinkle this check over
> drm_gem_shmem_get_sg_table, which should only be called when
> exporting, same for the pin/unpin functions, on which it relies to
> work correctly.
> 
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Noralf Trønnes <noralf@tronnes.org>
> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> ---
>  drivers/gpu/drm/drm_gem_shmem_helper.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
> index 117a7841e284..f7011338813e 100644
> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
> @@ -170,6 +170,8 @@ int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem)
>  {
>  	int ret;
>  
> +	WARN_ON(shmem->base.import_attach);
> +
>  	ret = mutex_lock_interruptible(&shmem->pages_lock);
>  	if (ret)
>  		return ret;
> @@ -225,6 +227,8 @@ int drm_gem_shmem_pin(struct drm_gem_object *obj)
>  {
>  	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
>  
> +	WARN_ON(shmem->base.import_attach);
> +

I don't understand this change. If a driver pins pages it now has to
check that the pages are not imported?


>  	return drm_gem_shmem_get_pages(shmem);
>  }
>  EXPORT_SYMBOL(drm_gem_shmem_pin);
> @@ -240,6 +244,8 @@ void drm_gem_shmem_unpin(struct drm_gem_object *obj)
>  {
>  	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
>  
> +	WARN_ON(shmem->base.import_attach);
> +
>  	drm_gem_shmem_put_pages(shmem);
>  }
>  EXPORT_SYMBOL(drm_gem_shmem_unpin);
> @@ -510,6 +516,8 @@ static void drm_gem_shmem_vm_open(struct vm_area_struct *vma)
>  	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
>  	int ret;
>  
> +	WARN_ON(shmem->base.import_attach);
> +
>  	ret = drm_gem_shmem_get_pages(shmem);
>  	WARN_ON_ONCE(ret != 0);
>  
> @@ -611,6 +619,8 @@ struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_object *obj)
>  {
>  	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
>  
> +	WARN_ON(shmem->base.import_attach);
> +
>  	return drm_prime_pages_to_sg(shmem->pages, obj->size >> PAGE_SHIFT);
>  }
>  EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_table);
>
Daniel Vetter June 3, 2020, 1:12 p.m. UTC | #2
On Thu, May 14, 2020 at 09:30:04AM +0200, Thomas Zimmermann wrote:
> Hi
> 
> Am 11.05.20 um 11:35 schrieb Daniel Vetter:
> > Just a bit of light paranoia. Also sprinkle this check over
> > drm_gem_shmem_get_sg_table, which should only be called when
> > exporting, same for the pin/unpin functions, on which it relies to
> > work correctly.
> > 
> > Cc: Gerd Hoffmann <kraxel@redhat.com>
> > Cc: Rob Herring <robh@kernel.org>
> > Cc: Noralf Trønnes <noralf@tronnes.org>
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > ---
> >  drivers/gpu/drm/drm_gem_shmem_helper.c | 10 ++++++++++
> >  1 file changed, 10 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
> > index 117a7841e284..f7011338813e 100644
> > --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
> > +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
> > @@ -170,6 +170,8 @@ int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem)
> >  {
> >  	int ret;
> >  
> > +	WARN_ON(shmem->base.import_attach);
> > +
> >  	ret = mutex_lock_interruptible(&shmem->pages_lock);
> >  	if (ret)
> >  		return ret;
> > @@ -225,6 +227,8 @@ int drm_gem_shmem_pin(struct drm_gem_object *obj)
> >  {
> >  	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
> >  
> > +	WARN_ON(shmem->base.import_attach);
> > +
> 
> I don't understand this change. If a driver pins pages it now has to
> check that the pages are not imported?

Nope. There's two classes of functions in the helpers, and I'm trying to
unconfuse them:

- stuff used to implement gem_funcs. These are obviously only ever used on
  native objects, never on imported ones (on imported ones we try to
  forward through the dma-buf layer to the exporter). drm_gem_shmem_pin is
  only used in that role to implement gem_funcs->pin. Calling it on an
  imported buffer is indeed a bug.

- the other set of functions are for drivers to do their stuff. The
  interface which (implicitly) pins stuff into places is various set of
  get_pages, which do have different paths for native and imported
  objects.

Apologies that I missed your question here, I merged all the patches
leading up to this one for now.

Thanks, Daniel

> 
> 
> >  	return drm_gem_shmem_get_pages(shmem);
> >  }
> >  EXPORT_SYMBOL(drm_gem_shmem_pin);
> > @@ -240,6 +244,8 @@ void drm_gem_shmem_unpin(struct drm_gem_object *obj)
> >  {
> >  	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
> >  
> > +	WARN_ON(shmem->base.import_attach);
> > +
> >  	drm_gem_shmem_put_pages(shmem);
> >  }
> >  EXPORT_SYMBOL(drm_gem_shmem_unpin);
> > @@ -510,6 +516,8 @@ static void drm_gem_shmem_vm_open(struct vm_area_struct *vma)
> >  	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
> >  	int ret;
> >  
> > +	WARN_ON(shmem->base.import_attach);
> > +
> >  	ret = drm_gem_shmem_get_pages(shmem);
> >  	WARN_ON_ONCE(ret != 0);
> >  
> > @@ -611,6 +619,8 @@ struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_object *obj)
> >  {
> >  	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
> >  
> > +	WARN_ON(shmem->base.import_attach);
> > +
> >  	return drm_prime_pages_to_sg(shmem->pages, obj->size >> PAGE_SHIFT);
> >  }
> >  EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_table);
> > 
> 
> -- 
> Thomas Zimmermann
> Graphics Driver Developer
> SUSE Software Solutions Germany GmbH
> Maxfeldstr. 5, 90409 Nürnberg, Germany
> (HRB 36809, AG Nürnberg)
> Geschäftsführer: Felix Imendörffer
>
Thomas Zimmermann June 8, 2020, 2:40 p.m. UTC | #3
Hi

Am 03.06.20 um 15:12 schrieb Daniel Vetter:
> On Thu, May 14, 2020 at 09:30:04AM +0200, Thomas Zimmermann wrote:
>> Hi
>>
>> Am 11.05.20 um 11:35 schrieb Daniel Vetter:
>>> Just a bit of light paranoia. Also sprinkle this check over
>>> drm_gem_shmem_get_sg_table, which should only be called when
>>> exporting, same for the pin/unpin functions, on which it relies to
>>> work correctly.
>>>
>>> Cc: Gerd Hoffmann <kraxel@redhat.com>
>>> Cc: Rob Herring <robh@kernel.org>
>>> Cc: Noralf Trønnes <noralf@tronnes.org>
>>> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
>>> ---
>>>  drivers/gpu/drm/drm_gem_shmem_helper.c | 10 ++++++++++
>>>  1 file changed, 10 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>> index 117a7841e284..f7011338813e 100644
>>> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
>>> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
>>> @@ -170,6 +170,8 @@ int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem)
>>>  {
>>>  	int ret;
>>>  
>>> +	WARN_ON(shmem->base.import_attach);
>>> +
>>>  	ret = mutex_lock_interruptible(&shmem->pages_lock);
>>>  	if (ret)
>>>  		return ret;
>>> @@ -225,6 +227,8 @@ int drm_gem_shmem_pin(struct drm_gem_object *obj)
>>>  {
>>>  	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
>>>  
>>> +	WARN_ON(shmem->base.import_attach);
>>> +
>>
>> I don't understand this change. If a driver pins pages it now has to
>> check that the pages are not imported?
> 
> Nope. There's two classes of functions in the helpers, and I'm trying to
> unconfuse them:
> 
> - stuff used to implement gem_funcs. These are obviously only ever used on
>   native objects, never on imported ones (on imported ones we try to
>   forward through the dma-buf layer to the exporter). drm_gem_shmem_pin is
>   only used in that role to implement gem_funcs->pin. Calling it on an
>   imported buffer is indeed a bug.
> 
> - the other set of functions are for drivers to do their stuff. The
>   interface which (implicitly) pins stuff into places is various set of
>   get_pages, which do have different paths for native and imported
>   objects.

Thanks for explaining. Patch is

Acked-by: Thomas Zimmermann <tzimmermann@suse.de>

> 
> Apologies that I missed your question here, I merged all the patches
> leading up to this one for now.
> 
> Thanks, Daniel
> 
>>
>>
>>>  	return drm_gem_shmem_get_pages(shmem);
>>>  }
>>>  EXPORT_SYMBOL(drm_gem_shmem_pin);
>>> @@ -240,6 +244,8 @@ void drm_gem_shmem_unpin(struct drm_gem_object *obj)
>>>  {
>>>  	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
>>>  
>>> +	WARN_ON(shmem->base.import_attach);
>>> +
>>>  	drm_gem_shmem_put_pages(shmem);
>>>  }
>>>  EXPORT_SYMBOL(drm_gem_shmem_unpin);
>>> @@ -510,6 +516,8 @@ static void drm_gem_shmem_vm_open(struct vm_area_struct *vma)
>>>  	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
>>>  	int ret;
>>>  
>>> +	WARN_ON(shmem->base.import_attach);
>>> +
>>>  	ret = drm_gem_shmem_get_pages(shmem);
>>>  	WARN_ON_ONCE(ret != 0);
>>>  
>>> @@ -611,6 +619,8 @@ struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_object *obj)
>>>  {
>>>  	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
>>>  
>>> +	WARN_ON(shmem->base.import_attach);
>>> +
>>>  	return drm_prime_pages_to_sg(shmem->pages, obj->size >> PAGE_SHIFT);
>>>  }
>>>  EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_table);
>>>
>>
>> -- 
>> Thomas Zimmermann
>> Graphics Driver Developer
>> SUSE Software Solutions Germany GmbH
>> Maxfeldstr. 5, 90409 Nürnberg, Germany
>> (HRB 36809, AG Nürnberg)
>> Geschäftsführer: Felix Imendörffer
>>
> 
> 
> 
>
Daniel Vetter June 8, 2020, 3:04 p.m. UTC | #4
On Mon, Jun 08, 2020 at 04:40:26PM +0200, Thomas Zimmermann wrote:
> Hi
> 
> Am 03.06.20 um 15:12 schrieb Daniel Vetter:
> > On Thu, May 14, 2020 at 09:30:04AM +0200, Thomas Zimmermann wrote:
> >> Hi
> >>
> >> Am 11.05.20 um 11:35 schrieb Daniel Vetter:
> >>> Just a bit of light paranoia. Also sprinkle this check over
> >>> drm_gem_shmem_get_sg_table, which should only be called when
> >>> exporting, same for the pin/unpin functions, on which it relies to
> >>> work correctly.
> >>>
> >>> Cc: Gerd Hoffmann <kraxel@redhat.com>
> >>> Cc: Rob Herring <robh@kernel.org>
> >>> Cc: Noralf Trønnes <noralf@tronnes.org>
> >>> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> >>> ---
> >>>  drivers/gpu/drm/drm_gem_shmem_helper.c | 10 ++++++++++
> >>>  1 file changed, 10 insertions(+)
> >>>
> >>> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
> >>> index 117a7841e284..f7011338813e 100644
> >>> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
> >>> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
> >>> @@ -170,6 +170,8 @@ int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem)
> >>>  {
> >>>  	int ret;
> >>>  
> >>> +	WARN_ON(shmem->base.import_attach);
> >>> +
> >>>  	ret = mutex_lock_interruptible(&shmem->pages_lock);
> >>>  	if (ret)
> >>>  		return ret;
> >>> @@ -225,6 +227,8 @@ int drm_gem_shmem_pin(struct drm_gem_object *obj)
> >>>  {
> >>>  	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
> >>>  
> >>> +	WARN_ON(shmem->base.import_attach);
> >>> +
> >>
> >> I don't understand this change. If a driver pins pages it now has to
> >> check that the pages are not imported?
> > 
> > Nope. There's two classes of functions in the helpers, and I'm trying to
> > unconfuse them:
> > 
> > - stuff used to implement gem_funcs. These are obviously only ever used on
> >   native objects, never on imported ones (on imported ones we try to
> >   forward through the dma-buf layer to the exporter). drm_gem_shmem_pin is
> >   only used in that role to implement gem_funcs->pin. Calling it on an
> >   imported buffer is indeed a bug.
> > 
> > - the other set of functions are for drivers to do their stuff. The
> >   interface which (implicitly) pins stuff into places is various set of
> >   get_pages, which do have different paths for native and imported
> >   objects.
> 
> Thanks for explaining. Patch is

Thanks for taking a look at all this, last 2 patches now also merged to
drm-misc-next.
-Daniel

> 
> Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
> 
> > 
> > Apologies that I missed your question here, I merged all the patches
> > leading up to this one for now.
> > 
> > Thanks, Daniel
> > 
> >>
> >>
> >>>  	return drm_gem_shmem_get_pages(shmem);
> >>>  }
> >>>  EXPORT_SYMBOL(drm_gem_shmem_pin);
> >>> @@ -240,6 +244,8 @@ void drm_gem_shmem_unpin(struct drm_gem_object *obj)
> >>>  {
> >>>  	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
> >>>  
> >>> +	WARN_ON(shmem->base.import_attach);
> >>> +
> >>>  	drm_gem_shmem_put_pages(shmem);
> >>>  }
> >>>  EXPORT_SYMBOL(drm_gem_shmem_unpin);
> >>> @@ -510,6 +516,8 @@ static void drm_gem_shmem_vm_open(struct vm_area_struct *vma)
> >>>  	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
> >>>  	int ret;
> >>>  
> >>> +	WARN_ON(shmem->base.import_attach);
> >>> +
> >>>  	ret = drm_gem_shmem_get_pages(shmem);
> >>>  	WARN_ON_ONCE(ret != 0);
> >>>  
> >>> @@ -611,6 +619,8 @@ struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_object *obj)
> >>>  {
> >>>  	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
> >>>  
> >>> +	WARN_ON(shmem->base.import_attach);
> >>> +
> >>>  	return drm_prime_pages_to_sg(shmem->pages, obj->size >> PAGE_SHIFT);
> >>>  }
> >>>  EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_table);
> >>>
> >>
> >> -- 
> >> Thomas Zimmermann
> >> Graphics Driver Developer
> >> SUSE Software Solutions Germany GmbH
> >> Maxfeldstr. 5, 90409 Nürnberg, Germany
> >> (HRB 36809, AG Nürnberg)
> >> Geschäftsführer: Felix Imendörffer
> >>
> > 
> > 
> > 
> > 
> 
> -- 
> Thomas Zimmermann
> Graphics Driver Developer
> SUSE Software Solutions Germany GmbH
> Maxfeldstr. 5, 90409 Nürnberg, Germany
> (HRB 36809, AG Nürnberg)
> Geschäftsführer: Felix Imendörffer
>
diff mbox series

Patch

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 117a7841e284..f7011338813e 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -170,6 +170,8 @@  int drm_gem_shmem_get_pages(struct drm_gem_shmem_object *shmem)
 {
 	int ret;
 
+	WARN_ON(shmem->base.import_attach);
+
 	ret = mutex_lock_interruptible(&shmem->pages_lock);
 	if (ret)
 		return ret;
@@ -225,6 +227,8 @@  int drm_gem_shmem_pin(struct drm_gem_object *obj)
 {
 	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
 
+	WARN_ON(shmem->base.import_attach);
+
 	return drm_gem_shmem_get_pages(shmem);
 }
 EXPORT_SYMBOL(drm_gem_shmem_pin);
@@ -240,6 +244,8 @@  void drm_gem_shmem_unpin(struct drm_gem_object *obj)
 {
 	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
 
+	WARN_ON(shmem->base.import_attach);
+
 	drm_gem_shmem_put_pages(shmem);
 }
 EXPORT_SYMBOL(drm_gem_shmem_unpin);
@@ -510,6 +516,8 @@  static void drm_gem_shmem_vm_open(struct vm_area_struct *vma)
 	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
 	int ret;
 
+	WARN_ON(shmem->base.import_attach);
+
 	ret = drm_gem_shmem_get_pages(shmem);
 	WARN_ON_ONCE(ret != 0);
 
@@ -611,6 +619,8 @@  struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_object *obj)
 {
 	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
 
+	WARN_ON(shmem->base.import_attach);
+
 	return drm_prime_pages_to_sg(shmem->pages, obj->size >> PAGE_SHIFT);
 }
 EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_table);