0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #include <drm/drm_prime.h>
0026 #include <linux/virtio_dma_buf.h>
0027
0028 #include "virtgpu_drv.h"
0029
0030 static int virtgpu_virtio_get_uuid(struct dma_buf *buf,
0031 uuid_t *uuid)
0032 {
0033 struct drm_gem_object *obj = buf->priv;
0034 struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);
0035 struct virtio_gpu_device *vgdev = obj->dev->dev_private;
0036
0037 wait_event(vgdev->resp_wq, bo->uuid_state != STATE_INITIALIZING);
0038 if (bo->uuid_state != STATE_OK)
0039 return -ENODEV;
0040
0041 uuid_copy(uuid, &bo->uuid);
0042
0043 return 0;
0044 }
0045
0046 static struct sg_table *
0047 virtgpu_gem_map_dma_buf(struct dma_buf_attachment *attach,
0048 enum dma_data_direction dir)
0049 {
0050 struct drm_gem_object *obj = attach->dmabuf->priv;
0051 struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);
0052
0053 if (virtio_gpu_is_vram(bo))
0054 return virtio_gpu_vram_map_dma_buf(bo, attach->dev, dir);
0055
0056 return drm_gem_map_dma_buf(attach, dir);
0057 }
0058
0059 static void virtgpu_gem_unmap_dma_buf(struct dma_buf_attachment *attach,
0060 struct sg_table *sgt,
0061 enum dma_data_direction dir)
0062 {
0063 struct drm_gem_object *obj = attach->dmabuf->priv;
0064 struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);
0065
0066 if (virtio_gpu_is_vram(bo)) {
0067 virtio_gpu_vram_unmap_dma_buf(attach->dev, sgt, dir);
0068 return;
0069 }
0070
0071 drm_gem_unmap_dma_buf(attach, sgt, dir);
0072 }
0073
0074 static const struct virtio_dma_buf_ops virtgpu_dmabuf_ops = {
0075 .ops = {
0076 .cache_sgt_mapping = true,
0077 .attach = virtio_dma_buf_attach,
0078 .detach = drm_gem_map_detach,
0079 .map_dma_buf = virtgpu_gem_map_dma_buf,
0080 .unmap_dma_buf = virtgpu_gem_unmap_dma_buf,
0081 .release = drm_gem_dmabuf_release,
0082 .mmap = drm_gem_dmabuf_mmap,
0083 .vmap = drm_gem_dmabuf_vmap,
0084 .vunmap = drm_gem_dmabuf_vunmap,
0085 },
0086 .device_attach = drm_gem_map_attach,
0087 .get_uuid = virtgpu_virtio_get_uuid,
0088 };
0089
0090 int virtio_gpu_resource_assign_uuid(struct virtio_gpu_device *vgdev,
0091 struct virtio_gpu_object *bo)
0092 {
0093 struct virtio_gpu_object_array *objs;
0094
0095 objs = virtio_gpu_array_alloc(1);
0096 if (!objs)
0097 return -ENOMEM;
0098
0099 virtio_gpu_array_add_obj(objs, &bo->base.base);
0100
0101 return virtio_gpu_cmd_resource_assign_uuid(vgdev, objs);
0102 }
0103
0104 struct dma_buf *virtgpu_gem_prime_export(struct drm_gem_object *obj,
0105 int flags)
0106 {
0107 struct dma_buf *buf;
0108 struct drm_device *dev = obj->dev;
0109 struct virtio_gpu_device *vgdev = dev->dev_private;
0110 struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);
0111 int ret = 0;
0112 bool blob = bo->host3d_blob || bo->guest_blob;
0113 DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
0114
0115 if (!blob) {
0116 if (vgdev->has_resource_assign_uuid) {
0117 ret = virtio_gpu_resource_assign_uuid(vgdev, bo);
0118 if (ret)
0119 return ERR_PTR(ret);
0120
0121 virtio_gpu_notify(vgdev);
0122 } else {
0123 bo->uuid_state = STATE_ERR;
0124 }
0125 } else if (!(bo->blob_flags & VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE)) {
0126 bo->uuid_state = STATE_ERR;
0127 }
0128
0129 exp_info.ops = &virtgpu_dmabuf_ops.ops;
0130 exp_info.size = obj->size;
0131 exp_info.flags = flags;
0132 exp_info.priv = obj;
0133 exp_info.resv = obj->resv;
0134
0135 buf = virtio_dma_buf_export(&exp_info);
0136 if (IS_ERR(buf))
0137 return buf;
0138
0139 drm_dev_get(dev);
0140 drm_gem_object_get(obj);
0141
0142 return buf;
0143 }
0144
0145 struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev,
0146 struct dma_buf *buf)
0147 {
0148 struct drm_gem_object *obj;
0149
0150 if (buf->ops == &virtgpu_dmabuf_ops.ops) {
0151 obj = buf->priv;
0152 if (obj->dev == dev) {
0153
0154
0155
0156
0157 drm_gem_object_get(obj);
0158 return obj;
0159 }
0160 }
0161
0162 return drm_gem_prime_import(dev, buf);
0163 }
0164
0165 struct drm_gem_object *virtgpu_gem_prime_import_sg_table(
0166 struct drm_device *dev, struct dma_buf_attachment *attach,
0167 struct sg_table *table)
0168 {
0169 return ERR_PTR(-ENODEV);
0170 }