OSDN Git Service

drm/virtio: add case for shmem objects in virtio_gpu_cleanup_object(..)
authorGurchetan Singh <gurchetansingh@chromium.org>
Thu, 5 Mar 2020 01:32:12 +0000 (17:32 -0800)
committerGerd Hoffmann <kraxel@redhat.com>
Mon, 9 Mar 2020 09:44:34 +0000 (10:44 +0100)
This function can be reused for hostmem objects.

v2: move virtio_gpu_is_shmem() check to virtio_gpu_cleanup_object()
v3: use-after free fix

Signed-off-by: Gurchetan Singh <gurchetansingh@chromium.org>
Link: http://patchwork.freedesktop.org/patch/msgid/20200305013212.130640-2-gurchetansingh@chromium.org
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
drivers/gpu/drm/virtio/virtgpu_drv.h
drivers/gpu/drm/virtio/virtgpu_object.c

index 8e2027d..c1824bd 100644 (file)
@@ -371,7 +371,7 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,
                             struct virtio_gpu_object **bo_ptr,
                             struct virtio_gpu_fence *fence);
 
-bool virtio_gpu_is_shmem(struct drm_gem_object *obj);
+bool virtio_gpu_is_shmem(struct virtio_gpu_object *bo);
 
 /* virtgpu_prime.c */
 struct drm_gem_object *virtgpu_gem_prime_import_sg_table(
index 1f8b062..cc65e8b 100644 (file)
@@ -65,21 +65,26 @@ static void virtio_gpu_resource_id_put(struct virtio_gpu_device *vgdev, uint32_t
 void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo)
 {
        struct virtio_gpu_device *vgdev = bo->base.base.dev->dev_private;
-       struct virtio_gpu_object_shmem *shmem = to_virtio_gpu_shmem(bo);
 
-       if (shmem->pages) {
-               if (shmem->mapped) {
-                       dma_unmap_sg(vgdev->vdev->dev.parent,
-                                    shmem->pages->sgl, shmem->mapped,
-                                    DMA_TO_DEVICE);
-                       shmem->mapped = 0;
+       virtio_gpu_resource_id_put(vgdev, bo->hw_res_handle);
+       if (virtio_gpu_is_shmem(bo)) {
+               struct virtio_gpu_object_shmem *shmem = to_virtio_gpu_shmem(bo);
+
+               if (shmem->pages) {
+                       if (shmem->mapped) {
+                               dma_unmap_sg(vgdev->vdev->dev.parent,
+                                            shmem->pages->sgl, shmem->mapped,
+                                            DMA_TO_DEVICE);
+                               shmem->mapped = 0;
+                       }
+
+                       sg_free_table(shmem->pages);
+                       shmem->pages = NULL;
+                       drm_gem_shmem_unpin(&bo->base.base);
                }
-               sg_free_table(shmem->pages);
-               shmem->pages = NULL;
-               drm_gem_shmem_unpin(&bo->base.base);
+
+               drm_gem_shmem_free_object(&bo->base.base);
        }
-       virtio_gpu_resource_id_put(vgdev, bo->hw_res_handle);
-       drm_gem_shmem_free_object(&bo->base.base);
 }
 
 static void virtio_gpu_free_object(struct drm_gem_object *obj)
@@ -110,9 +115,9 @@ static const struct drm_gem_object_funcs virtio_gpu_shmem_funcs = {
        .mmap = drm_gem_shmem_mmap,
 };
 
-bool virtio_gpu_is_shmem(struct drm_gem_object *obj)
+bool virtio_gpu_is_shmem(struct virtio_gpu_object *bo)
 {
-       return obj->funcs == &virtio_gpu_shmem_funcs;
+       return bo->base.base.funcs == &virtio_gpu_shmem_funcs;
 }
 
 struct drm_gem_object *virtio_gpu_create_object(struct drm_device *dev,