diff options
Diffstat (limited to 'drivers/gpu/drm/virtio')
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_drv.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_ioctl.c | 66 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_kms.c | 28 | ||||
-rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_object.c | 11 |
4 files changed, 66 insertions, 44 deletions
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 2f6c4ccbfd14..ce73895cf74b 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -209,6 +209,8 @@ struct virtio_gpu_device { struct virtio_gpu_fpriv { uint32_t ctx_id; + bool context_created; + struct mutex context_lock; }; /* virtio_ioctl.c */ @@ -363,6 +365,9 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, struct virtio_gpu_object_params *params, struct virtio_gpu_object **bo_ptr, struct virtio_gpu_fence *fence); + +bool virtio_gpu_is_shmem(struct drm_gem_object *obj); + /* virtgpu_prime.c */ struct drm_gem_object *virtgpu_gem_prime_import_sg_table( struct drm_device *dev, struct dma_buf_attachment *attach, diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c index bbc31aef51f1..336cc9143205 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -33,13 +33,34 @@ #include "virtgpu_drv.h" +static void virtio_gpu_create_context(struct drm_device *dev, + struct drm_file *file) +{ + struct virtio_gpu_device *vgdev = dev->dev_private; + struct virtio_gpu_fpriv *vfpriv = file->driver_priv; + char dbgname[TASK_COMM_LEN]; + + mutex_lock(&vfpriv->context_lock); + if (vfpriv->context_created) + goto out_unlock; + + get_task_comm(dbgname, current); + virtio_gpu_cmd_context_create(vgdev, vfpriv->ctx_id, + strlen(dbgname), dbgname); + virtio_gpu_notify(vgdev); + vfpriv->context_created = true; + +out_unlock: + mutex_unlock(&vfpriv->context_lock); +} + static int virtio_gpu_map_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file) { struct virtio_gpu_device *vgdev = dev->dev_private; struct drm_virtgpu_map *virtio_gpu_map = data; - return virtio_gpu_mode_dumb_mmap(file_priv, vgdev->ddev, + return virtio_gpu_mode_dumb_mmap(file, vgdev->ddev, virtio_gpu_map->handle, &virtio_gpu_map->offset); } @@ -51,11 +72,11 @@ static int virtio_gpu_map_ioctl(struct drm_device *dev, void *data, * VIRTIO_GPUReleaseInfo struct (first XXX bytes) */ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data, - struct drm_file *drm_file) + struct drm_file *file) { struct drm_virtgpu_execbuffer *exbuf = data; struct virtio_gpu_device *vgdev = dev->dev_private; - struct virtio_gpu_fpriv *vfpriv = drm_file->driver_priv; + struct virtio_gpu_fpriv *vfpriv = file->driver_priv; struct virtio_gpu_fence *out_fence; int ret; uint32_t *bo_handles = NULL; @@ -74,6 +95,7 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data, exbuf->fence_fd = -1; + virtio_gpu_create_context(dev, file); if (exbuf->flags & VIRTGPU_EXECBUF_FENCE_FD_IN) { struct dma_fence *in_fence; @@ -116,7 +138,7 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data, goto out_unused_fd; } - buflist = virtio_gpu_array_from_handles(drm_file, bo_handles, + buflist = virtio_gpu_array_from_handles(file, bo_handles, exbuf->num_bo_handles); if (!buflist) { ret = -ENOENT; @@ -178,7 +200,7 @@ out_unused_fd: } static int virtio_gpu_getparam_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file) { struct virtio_gpu_device *vgdev = dev->dev_private; struct drm_virtgpu_getparam *param = data; @@ -201,7 +223,7 @@ static int virtio_gpu_getparam_ioctl(struct drm_device *dev, void *data, } static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file) { struct virtio_gpu_device *vgdev = dev->dev_private; struct drm_virtgpu_resource_create *rc = data; @@ -212,7 +234,17 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, uint32_t handle = 0; struct virtio_gpu_object_params params = { 0 }; - if (vgdev->has_virgl_3d == false) { + if (vgdev->has_virgl_3d) { + virtio_gpu_create_context(dev, file); + params.virgl = true; + params.target = rc->target; + params.bind = rc->bind; + params.depth = rc->depth; + params.array_size = rc->array_size; + params.last_level = rc->last_level; + params.nr_samples = rc->nr_samples; + params.flags = rc->flags; + } else { if (rc->depth > 1) return -EINVAL; if (rc->nr_samples > 1) @@ -229,16 +261,6 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, params.width = rc->width; params.height = rc->height; params.size = rc->size; - if (vgdev->has_virgl_3d) { - params.virgl = true; - params.target = rc->target; - params.bind = rc->bind; - params.depth = rc->depth; - params.array_size = rc->array_size; - params.last_level = rc->last_level; - params.nr_samples = rc->nr_samples; - params.flags = rc->flags; - } /* allocate a single page size object */ if (params.size == 0) params.size = PAGE_SIZE; @@ -252,7 +274,7 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, return ret; obj = &qobj->base.base; - ret = drm_gem_handle_create(file_priv, obj, &handle); + ret = drm_gem_handle_create(file, obj, &handle); if (ret) { drm_gem_object_release(obj); return ret; @@ -265,13 +287,13 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, } static int virtio_gpu_resource_info_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file) { struct drm_virtgpu_resource_info *ri = data; struct drm_gem_object *gobj = NULL; struct virtio_gpu_object *qobj = NULL; - gobj = drm_gem_object_lookup(file_priv, ri->bo_handle); + gobj = drm_gem_object_lookup(file, ri->bo_handle); if (gobj == NULL) return -ENOENT; @@ -298,6 +320,7 @@ static int virtio_gpu_transfer_from_host_ioctl(struct drm_device *dev, if (vgdev->has_virgl_3d == false) return -ENOSYS; + virtio_gpu_create_context(dev, file); objs = virtio_gpu_array_from_handles(file, &args->bo_handle, 1); if (objs == NULL) return -ENOENT; @@ -346,6 +369,7 @@ static int virtio_gpu_transfer_to_host_ioctl(struct drm_device *dev, void *data, args->box.w, args->box.h, args->box.x, args->box.y, objs, NULL); } else { + virtio_gpu_create_context(dev, file); ret = virtio_gpu_array_lock_resv(objs); if (ret != 0) goto err_put_free; diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index ad3b673f5796..023a030ca7b9 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -52,19 +52,6 @@ static void virtio_gpu_config_changed_work_func(struct work_struct *work) events_clear, &events_clear); } -static int virtio_gpu_context_create(struct virtio_gpu_device *vgdev, - uint32_t nlen, const char *name) -{ - int handle = ida_alloc(&vgdev->ctx_id_ida, GFP_KERNEL); - - if (handle < 0) - return handle; - handle += 1; - virtio_gpu_cmd_context_create(vgdev, handle, nlen, name); - virtio_gpu_notify(vgdev); - return handle; -} - static void virtio_gpu_context_destroy(struct virtio_gpu_device *vgdev, uint32_t ctx_id) { @@ -260,8 +247,7 @@ int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file) { struct virtio_gpu_device *vgdev = dev->dev_private; struct virtio_gpu_fpriv *vfpriv; - int id; - char dbgname[TASK_COMM_LEN]; + int handle; /* can't create contexts without 3d renderer */ if (!vgdev->has_virgl_3d) @@ -272,14 +258,15 @@ int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file) if (!vfpriv) return -ENOMEM; - get_task_comm(dbgname, current); - id = virtio_gpu_context_create(vgdev, strlen(dbgname), dbgname); - if (id < 0) { + mutex_init(&vfpriv->context_lock); + + handle = ida_alloc(&vgdev->ctx_id_ida, GFP_KERNEL); + if (handle < 0) { kfree(vfpriv); - return id; + return handle; } - vfpriv->ctx_id = id; + vfpriv->ctx_id = handle + 1; file->driver_priv = vfpriv; return 0; } @@ -295,6 +282,7 @@ void virtio_gpu_driver_postclose(struct drm_device *dev, struct drm_file *file) vfpriv = file->driver_priv; virtio_gpu_context_destroy(vgdev, vfpriv->ctx_id); + mutex_destroy(&vfpriv->context_lock); kfree(vfpriv); file->driver_priv = NULL; } diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index 3d2a6d489bfc..c5cad949eb8d 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -95,7 +95,7 @@ static void virtio_gpu_free_object(struct drm_gem_object *obj) virtio_gpu_cleanup_object(bo); } -static const struct drm_gem_object_funcs virtio_gpu_gem_funcs = { +static const struct drm_gem_object_funcs virtio_gpu_shmem_funcs = { .free = virtio_gpu_free_object, .open = virtio_gpu_gem_object_open, .close = virtio_gpu_gem_object_close, @@ -106,9 +106,14 @@ 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 = drm_gem_shmem_mmap, }; +bool virtio_gpu_is_shmem(struct drm_gem_object *obj) +{ + return obj->funcs == &virtio_gpu_shmem_funcs; +} + struct drm_gem_object *virtio_gpu_create_object(struct drm_device *dev, size_t size) { @@ -118,7 +123,7 @@ struct drm_gem_object *virtio_gpu_create_object(struct drm_device *dev, if (!bo) return NULL; - bo->base.base.funcs = &virtio_gpu_gem_funcs; + bo->base.base.funcs = &virtio_gpu_shmem_funcs; return &bo->base.base; } |