diff mbox series

drm/virtio: fix mmap page attributes

Message ID 20191210085759.14763-1-kraxel@redhat.com (mailing list archive)
State New, archived
Headers show
Series drm/virtio: fix mmap page attributes | expand

Commit Message

Gerd Hoffmann Dec. 10, 2019, 8:57 a.m. UTC
virtio-gpu uses cached mappings.  shmem helpers use writecombine though.
So roll our own mmap function, wrapping drm_gem_shmem_mmap(), to tweak
vm_page_prot accordingly.

Reported-by: Gurchetan Singh <gurchetansingh@chromium.org>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 drivers/gpu/drm/virtio/virtgpu_object.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

Comments

Thomas Zimmermann Dec. 10, 2019, 9:27 a.m. UTC | #1
Hi

Am 10.12.19 um 09:57 schrieb Gerd Hoffmann:
> virtio-gpu uses cached mappings.  shmem helpers use writecombine though.
> So roll our own mmap function, wrapping drm_gem_shmem_mmap(), to tweak
> vm_page_prot accordingly.
> 
> Reported-by: Gurchetan Singh <gurchetansingh@chromium.org>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  drivers/gpu/drm/virtio/virtgpu_object.c | 18 +++++++++++++++++-
>  1 file changed, 17 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
> index 017a9e0fc3bb..158610902054 100644
> --- a/drivers/gpu/drm/virtio/virtgpu_object.c
> +++ b/drivers/gpu/drm/virtio/virtgpu_object.c
> @@ -75,6 +75,22 @@ static void virtio_gpu_free_object(struct drm_gem_object *obj)
>  	drm_gem_shmem_free_object(obj);
>  }
>  
> +static int virtio_gpu_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
> +{
> +	pgprot_t prot;
> +	int ret;
> +
> +	ret = drm_gem_shmem_mmap(obj, vma);
> +	if (ret < 0)
> +		return ret;
> +
> +	/* virtio-gpu needs normal caching, so clear writecombine */
> +	prot = vm_get_page_prot(vma->vm_flags);
> +	prot = pgprot_decrypted(prot);
> +	vma->vm_page_prot = prot;
> +	return 0;
> +}

There's similar code in udl, [1] which still uses writecombine for
imported buffers. Virtio does not need this?

Aside from this, do you think we could handle all special cases within
shmem?

Best regards
Thomas

[1]
https://cgit.freedesktop.org/drm/drm-tip/tree/drivers/gpu/drm/udl/udl_gem.c?id=28ecf94a6f1072fc4744c06f5b3d267297125b37#n20

> +
>  static const struct drm_gem_object_funcs virtio_gpu_gem_funcs = {
>  	.free = virtio_gpu_free_object,
>  	.open = virtio_gpu_gem_object_open,
> @@ -86,7 +102,7 @@ static const struct drm_gem_object_funcs virtio_gpu_gem_funcs = {
>  	.get_sg_table = drm_gem_shmem_get_sg_table,
>  	.vmap = drm_gem_shmem_vmap,
>  	.vunmap = drm_gem_shmem_vunmap,
> -	.mmap = &drm_gem_shmem_mmap,
> +	.mmap = &virtio_gpu_gem_mmap,
>  };
>  
>  struct drm_gem_object *virtio_gpu_create_object(struct drm_device *dev,
>
Gurchetan Singh Dec. 11, 2019, 1:06 a.m. UTC | #2
On Tue, Dec 10, 2019 at 12:58 AM Gerd Hoffmann <kraxel@redhat.com> wrote:
>
> virtio-gpu uses cached mappings.  shmem helpers use writecombine though.
> So roll our own mmap function, wrapping drm_gem_shmem_mmap(), to tweak
> vm_page_prot accordingly.
>
> Reported-by: Gurchetan Singh <gurchetansingh@chromium.org>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  drivers/gpu/drm/virtio/virtgpu_object.c | 18 +++++++++++++++++-
>  1 file changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
> index 017a9e0fc3bb..158610902054 100644
> --- a/drivers/gpu/drm/virtio/virtgpu_object.c
> +++ b/drivers/gpu/drm/virtio/virtgpu_object.c
> @@ -75,6 +75,22 @@ static void virtio_gpu_free_object(struct drm_gem_object *obj)
>         drm_gem_shmem_free_object(obj);
>  }
>
> +static int virtio_gpu_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
> +{
> +       pgprot_t prot;
> +       int ret;
> +
> +       ret = drm_gem_shmem_mmap(obj, vma);
> +       if (ret < 0)
> +               return ret;
> +
> +       /* virtio-gpu needs normal caching, so clear writecombine */
> +       prot = vm_get_page_prot(vma->vm_flags);
> +       prot = pgprot_decrypted(prot);
> +       vma->vm_page_prot = prot;
> +       return 0;
> +}
> +
>  static const struct drm_gem_object_funcs virtio_gpu_gem_funcs = {
>         .free = virtio_gpu_free_object,
>         .open = virtio_gpu_gem_object_open,
> @@ -86,7 +102,7 @@ static const struct drm_gem_object_funcs virtio_gpu_gem_funcs = {
>         .get_sg_table = drm_gem_shmem_get_sg_table,
>         .vmap = drm_gem_shmem_vmap,

Do we need vmap/vmunap?  It seems optionable and also uses non-cacheable memory?

>         .vunmap = drm_gem_shmem_vunmap,
> -       .mmap = &drm_gem_shmem_mmap,
> +       .mmap = &virtio_gpu_gem_mmap,

Why the &virtio_gpu_gem_mmap?  Shouldn't just virtio_gpu_gem_mmap work?



>  };
>
>  struct drm_gem_object *virtio_gpu_create_object(struct drm_device *dev,
> --
> 2.18.1
>
Gerd Hoffmann Dec. 11, 2019, 8:15 a.m. UTC | #3
Hi,

> There's similar code in udl, [1] which still uses writecombine for
> imported buffers. Virtio does not need this?

virtio doesn't support dma-buf imports (yet).
So no worries for now.

Why pick writecombine for the imported buffer btw?
It'll probably be correct for the majority of imports, but it still
looks like a educated guess to me.  What if you import from vgem?

I guess we should either ...
  (1) Ask the exporting driver to handle things, simliar to how it is
      done for vmaps already, probably by calling dma_buf_mmap(), or
  (2) Refuse to mmap imported objects via drm api.

> Aside from this, do you think we could handle all special cases within
> shmem?

Probably makes sense to teach shmem helpers about caching.

cheers,
  Gerd
Michael J. Ruhl Dec. 12, 2019, 2:49 p.m. UTC | #4
>-----Original Message-----
>From: dri-devel <dri-devel-bounces@lists.freedesktop.org> On Behalf Of
>Gerd Hoffmann
>Sent: Tuesday, December 10, 2019 3:58 AM
>To: dri-devel@lists.freedesktop.org
>Cc: David Airlie <airlied@linux.ie>; open list <linux-kernel@vger.kernel.org>;
>open list:VIRTIO GPU DRIVER <virtualization@lists.linux-foundation.org>;
>Gerd Hoffmann <kraxel@redhat.com>; gurchetansingh@chromium.org
>Subject: [PATCH] drm/virtio: fix mmap page attributes
>
>virtio-gpu uses cached mappings.  shmem helpers use writecombine though.
>So roll our own mmap function, wrapping drm_gem_shmem_mmap(), to
>tweak
>vm_page_prot accordingly.
>
>Reported-by: Gurchetan Singh <gurchetansingh@chromium.org>
>Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
>---
> drivers/gpu/drm/virtio/virtgpu_object.c | 18 +++++++++++++++++-
> 1 file changed, 17 insertions(+), 1 deletion(-)
>
>diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c
>b/drivers/gpu/drm/virtio/virtgpu_object.c
>index 017a9e0fc3bb..158610902054 100644
>--- a/drivers/gpu/drm/virtio/virtgpu_object.c
>+++ b/drivers/gpu/drm/virtio/virtgpu_object.c
>@@ -75,6 +75,22 @@ static void virtio_gpu_free_object(struct
>drm_gem_object *obj)
> 	drm_gem_shmem_free_object(obj);
> }
>
>+static int virtio_gpu_gem_mmap(struct drm_gem_object *obj, struct
>vm_area_struct *vma)
>+{
>+	pgprot_t prot;
>+	int ret;
>+
>+	ret = drm_gem_shmem_mmap(obj, vma);
>+	if (ret < 0)
>+		return ret;
>+
>+	/* virtio-gpu needs normal caching, so clear writecombine */

A minor nit. 

I was looking at this code, trying to see where you were clearing the
writecombine bit.

Maybe a more clear comment would be:

virtio-gpu needs normal caching, re-do protection without writecombine

?

Mike

>+	prot = vm_get_page_prot(vma->vm_flags);
>+	prot = pgprot_decrypted(prot);
>+	vma->vm_page_prot = prot;
>+	return 0;
>+}
>+
> static const struct drm_gem_object_funcs virtio_gpu_gem_funcs = {
> 	.free = virtio_gpu_free_object,
> 	.open = virtio_gpu_gem_object_open,
>@@ -86,7 +102,7 @@ static const struct drm_gem_object_funcs
>virtio_gpu_gem_funcs = {
> 	.get_sg_table = drm_gem_shmem_get_sg_table,
> 	.vmap = drm_gem_shmem_vmap,
> 	.vunmap = drm_gem_shmem_vunmap,
>-	.mmap = &drm_gem_shmem_mmap,
>+	.mmap = &virtio_gpu_gem_mmap,
> };
>
> struct drm_gem_object *virtio_gpu_create_object(struct drm_device *dev,
>--
>2.18.1
>
>_______________________________________________
>dri-devel mailing list
>dri-devel@lists.freedesktop.org
>https://lists.freedesktop.org/mailman/listinfo/dri-devel
diff mbox series

Patch

diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
index 017a9e0fc3bb..158610902054 100644
--- a/drivers/gpu/drm/virtio/virtgpu_object.c
+++ b/drivers/gpu/drm/virtio/virtgpu_object.c
@@ -75,6 +75,22 @@  static void virtio_gpu_free_object(struct drm_gem_object *obj)
 	drm_gem_shmem_free_object(obj);
 }
 
+static int virtio_gpu_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
+{
+	pgprot_t prot;
+	int ret;
+
+	ret = drm_gem_shmem_mmap(obj, vma);
+	if (ret < 0)
+		return ret;
+
+	/* virtio-gpu needs normal caching, so clear writecombine */
+	prot = vm_get_page_prot(vma->vm_flags);
+	prot = pgprot_decrypted(prot);
+	vma->vm_page_prot = prot;
+	return 0;
+}
+
 static const struct drm_gem_object_funcs virtio_gpu_gem_funcs = {
 	.free = virtio_gpu_free_object,
 	.open = virtio_gpu_gem_object_open,
@@ -86,7 +102,7 @@  static const struct drm_gem_object_funcs virtio_gpu_gem_funcs = {
 	.get_sg_table = drm_gem_shmem_get_sg_table,
 	.vmap = drm_gem_shmem_vmap,
 	.vunmap = drm_gem_shmem_vunmap,
-	.mmap = &drm_gem_shmem_mmap,
+	.mmap = &virtio_gpu_gem_mmap,
 };
 
 struct drm_gem_object *virtio_gpu_create_object(struct drm_device *dev,