diff options
Diffstat (limited to 'drivers/gpu/drm/virtio/virtgpu_gem.c')
| -rw-r--r-- | drivers/gpu/drm/virtio/virtgpu_gem.c | 84 |
1 files changed, 55 insertions, 29 deletions
diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c index d6cb350ae52a..90c99d83c4cf 100644 --- a/drivers/gpu/drm/virtio/virtgpu_gem.c +++ b/drivers/gpu/drm/virtio/virtgpu_gem.c @@ -39,9 +39,6 @@ static int virtio_gpu_gem_create(struct drm_file *file, int ret; u32 handle; - if (vgdev->has_virgl_3d) - virtio_gpu_create_context(dev, file); - ret = virtio_gpu_object_create(vgdev, params, &obj, NULL); if (ret < 0) return ret; @@ -55,7 +52,7 @@ static int virtio_gpu_gem_create(struct drm_file *file, *obj_p = &obj->base.base; /* drop reference from allocate - handle holds it now */ - drm_gem_object_put_unlocked(&obj->base.base); + drm_gem_object_put(&obj->base.base); *handle_p = handle; return 0; @@ -67,6 +64,7 @@ int virtio_gpu_mode_dumb_create(struct drm_file *file_priv, { struct drm_gem_object *gobj; struct virtio_gpu_object_params params = { 0 }; + struct virtio_gpu_device *vgdev = dev->dev_private; int ret; uint32_t pitch; @@ -82,6 +80,13 @@ int virtio_gpu_mode_dumb_create(struct drm_file *file_priv, params.height = args->height; params.size = args->size; params.dumb = true; + + if (vgdev->has_resource_blob && !vgdev->has_virgl_3d) { + params.blob_mem = VIRTGPU_BLOB_MEM_GUEST; + params.blob_flags = VIRTGPU_BLOB_FLAG_USE_SHAREABLE; + params.blob = true; + } + ret = virtio_gpu_gem_create(file_priv, dev, ¶ms, &gobj, &args->handle); if (ret) @@ -94,21 +99,6 @@ fail: return ret; } -int virtio_gpu_mode_dumb_mmap(struct drm_file *file_priv, - struct drm_device *dev, - uint32_t handle, uint64_t *offset_p) -{ - struct drm_gem_object *gobj; - - BUG_ON(!offset_p); - gobj = drm_gem_object_lookup(file_priv, handle); - if (gobj == NULL) - return -ENOENT; - *offset_p = drm_vma_node_offset_addr(&gobj->vma_node); - drm_gem_object_put_unlocked(gobj); - return 0; -} - int virtio_gpu_gem_object_open(struct drm_gem_object *obj, struct drm_file *file) { @@ -119,13 +109,21 @@ int virtio_gpu_gem_object_open(struct drm_gem_object *obj, if (!vgdev->has_virgl_3d) goto out_notify; - objs = virtio_gpu_array_alloc(1); - if (!objs) - return -ENOMEM; - virtio_gpu_array_add_obj(objs, obj); + /* the context might still be missing when the first ioctl is + * DRM_IOCTL_MODE_CREATE_DUMB or DRM_IOCTL_PRIME_FD_TO_HANDLE + */ + if (!vgdev->has_context_init) + virtio_gpu_create_context(obj->dev, file); + + if (vfpriv->context_created) { + objs = virtio_gpu_array_alloc(1); + if (!objs) + return -ENOMEM; + virtio_gpu_array_add_obj(objs, obj); + + virtio_gpu_cmd_context_attach_resource(vgdev, vfpriv->ctx_id, objs); + } - virtio_gpu_cmd_context_attach_resource(vgdev, vfpriv->ctx_id, - objs); out_notify: virtio_gpu_notify(vgdev); return 0; @@ -151,12 +149,25 @@ void virtio_gpu_gem_object_close(struct drm_gem_object *obj, virtio_gpu_notify(vgdev); } +/* For drm panic */ +struct virtio_gpu_object_array *virtio_gpu_panic_array_alloc(void) +{ + struct virtio_gpu_object_array *objs; + + objs = kmalloc(sizeof(struct virtio_gpu_object_array), GFP_ATOMIC); + if (!objs) + return NULL; + + objs->nents = 0; + objs->total = 1; + return objs; +} + struct virtio_gpu_object_array *virtio_gpu_array_alloc(u32 nents) { struct virtio_gpu_object_array *objs; - size_t size = sizeof(*objs) + sizeof(objs->objs[0]) * nents; - objs = kmalloc(size, GFP_KERNEL); + objs = kmalloc(struct_size(objs, objs, nents), GFP_KERNEL); if (!objs) return NULL; @@ -205,6 +216,7 @@ void virtio_gpu_array_add_obj(struct virtio_gpu_object_array *objs, int virtio_gpu_array_lock_resv(struct virtio_gpu_object_array *objs) { + unsigned int i; int ret; if (objs->nents == 1) { @@ -213,6 +225,16 @@ int virtio_gpu_array_lock_resv(struct virtio_gpu_object_array *objs) ret = drm_gem_lock_reservations(objs->objs, objs->nents, &objs->ticket); } + if (ret) + return ret; + + for (i = 0; i < objs->nents; ++i) { + ret = dma_resv_reserve_fences(objs->objs[i]->resv, 1); + if (ret) { + virtio_gpu_array_unlock_resv(objs); + return ret; + } + } return ret; } @@ -232,15 +254,19 @@ void virtio_gpu_array_add_fence(struct virtio_gpu_object_array *objs, int i; for (i = 0; i < objs->nents; i++) - dma_resv_add_excl_fence(objs->objs[i]->resv, fence); + dma_resv_add_fence(objs->objs[i]->resv, fence, + DMA_RESV_USAGE_WRITE); } void virtio_gpu_array_put_free(struct virtio_gpu_object_array *objs) { u32 i; + if (!objs) + return; + for (i = 0; i < objs->nents; i++) - drm_gem_object_put_unlocked(objs->objs[i]); + drm_gem_object_put(objs->objs[i]); virtio_gpu_array_free(objs); } |
