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