2019-12-10 08:59:59

by Gerd Hoffmann

[permalink] [raw]
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 <[email protected]>
Signed-off-by: Gerd Hoffmann <[email protected]>
---
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,
.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


2019-12-10 09:28:11

by Thomas Zimmermann

[permalink] [raw]
Subject: Re: [PATCH] drm/virtio: fix mmap page attributes

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 <[email protected]>
> Signed-off-by: Gerd Hoffmann <[email protected]>
> ---
> 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,
>

--
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


Attachments:
signature.asc (499.00 B)
OpenPGP digital signature

2019-12-11 01:09:06

by Gurchetan Singh

[permalink] [raw]
Subject: Re: [PATCH] drm/virtio: fix mmap page attributes

On Tue, Dec 10, 2019 at 12:58 AM Gerd Hoffmann <[email protected]> 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 <[email protected]>
> Signed-off-by: Gerd Hoffmann <[email protected]>
> ---
> 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
>

2019-12-11 08:17:52

by Gerd Hoffmann

[permalink] [raw]
Subject: Re: [PATCH] drm/virtio: fix mmap page attributes

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

2019-12-12 14:50:30

by Michael J. Ruhl

[permalink] [raw]
Subject: RE: [PATCH] drm/virtio: fix mmap page attributes

>-----Original Message-----
>From: dri-devel <[email protected]> On Behalf Of
>Gerd Hoffmann
>Sent: Tuesday, December 10, 2019 3:58 AM
>To: [email protected]
>Cc: David Airlie <[email protected]>; open list <[email protected]>;
>open list:VIRTIO GPU DRIVER <[email protected]>;
>Gerd Hoffmann <[email protected]>; [email protected]
>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 <[email protected]>
>Signed-off-by: Gerd Hoffmann <[email protected]>
>---
> 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
>[email protected]
>https://lists.freedesktop.org/mailman/listinfo/dri-devel