virtgpu_prime.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * Copyright 2014 Canonical
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. * OTHER DEALINGS IN THE SOFTWARE.
  21. *
  22. * Authors: Andreas Pokorny
  23. */
  24. #include <drm/drm_prime.h>
  25. #include <linux/virtio_dma_buf.h>
  26. #include "virtgpu_drv.h"
  27. static int virtgpu_virtio_get_uuid(struct dma_buf *buf,
  28. uuid_t *uuid)
  29. {
  30. struct drm_gem_object *obj = buf->priv;
  31. struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);
  32. struct virtio_gpu_device *vgdev = obj->dev->dev_private;
  33. wait_event(vgdev->resp_wq, bo->uuid_state != STATE_INITIALIZING);
  34. if (bo->uuid_state != STATE_OK)
  35. return -ENODEV;
  36. uuid_copy(uuid, &bo->uuid);
  37. return 0;
  38. }
  39. static struct sg_table *
  40. virtgpu_gem_map_dma_buf(struct dma_buf_attachment *attach,
  41. enum dma_data_direction dir)
  42. {
  43. struct drm_gem_object *obj = attach->dmabuf->priv;
  44. struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);
  45. if (virtio_gpu_is_vram(bo))
  46. return virtio_gpu_vram_map_dma_buf(bo, attach->dev, dir);
  47. return drm_gem_map_dma_buf(attach, dir);
  48. }
  49. static void virtgpu_gem_unmap_dma_buf(struct dma_buf_attachment *attach,
  50. struct sg_table *sgt,
  51. enum dma_data_direction dir)
  52. {
  53. struct drm_gem_object *obj = attach->dmabuf->priv;
  54. struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);
  55. if (virtio_gpu_is_vram(bo)) {
  56. virtio_gpu_vram_unmap_dma_buf(attach->dev, sgt, dir);
  57. return;
  58. }
  59. drm_gem_unmap_dma_buf(attach, sgt, dir);
  60. }
  61. static const struct virtio_dma_buf_ops virtgpu_dmabuf_ops = {
  62. .ops = {
  63. .cache_sgt_mapping = true,
  64. .attach = virtio_dma_buf_attach,
  65. .detach = drm_gem_map_detach,
  66. .map_dma_buf = virtgpu_gem_map_dma_buf,
  67. .unmap_dma_buf = virtgpu_gem_unmap_dma_buf,
  68. .release = drm_gem_dmabuf_release,
  69. .mmap = drm_gem_dmabuf_mmap,
  70. .vmap = drm_gem_dmabuf_vmap,
  71. .vunmap = drm_gem_dmabuf_vunmap,
  72. },
  73. .device_attach = drm_gem_map_attach,
  74. .get_uuid = virtgpu_virtio_get_uuid,
  75. };
  76. int virtio_gpu_resource_assign_uuid(struct virtio_gpu_device *vgdev,
  77. struct virtio_gpu_object *bo)
  78. {
  79. struct virtio_gpu_object_array *objs;
  80. objs = virtio_gpu_array_alloc(1);
  81. if (!objs)
  82. return -ENOMEM;
  83. virtio_gpu_array_add_obj(objs, &bo->base.base);
  84. return virtio_gpu_cmd_resource_assign_uuid(vgdev, objs);
  85. }
  86. struct dma_buf *virtgpu_gem_prime_export(struct drm_gem_object *obj,
  87. int flags)
  88. {
  89. struct dma_buf *buf;
  90. struct drm_device *dev = obj->dev;
  91. struct virtio_gpu_device *vgdev = dev->dev_private;
  92. struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);
  93. int ret = 0;
  94. bool blob = bo->host3d_blob || bo->guest_blob;
  95. DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
  96. if (!blob) {
  97. if (vgdev->has_resource_assign_uuid) {
  98. ret = virtio_gpu_resource_assign_uuid(vgdev, bo);
  99. if (ret)
  100. return ERR_PTR(ret);
  101. virtio_gpu_notify(vgdev);
  102. } else {
  103. bo->uuid_state = STATE_ERR;
  104. }
  105. } else if (!(bo->blob_flags & VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE)) {
  106. bo->uuid_state = STATE_ERR;
  107. }
  108. exp_info.ops = &virtgpu_dmabuf_ops.ops;
  109. exp_info.size = obj->size;
  110. exp_info.flags = flags;
  111. exp_info.priv = obj;
  112. exp_info.resv = obj->resv;
  113. buf = virtio_dma_buf_export(&exp_info);
  114. if (IS_ERR(buf))
  115. return buf;
  116. drm_dev_get(dev);
  117. drm_gem_object_get(obj);
  118. return buf;
  119. }
  120. struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev,
  121. struct dma_buf *buf)
  122. {
  123. struct drm_gem_object *obj;
  124. if (buf->ops == &virtgpu_dmabuf_ops.ops) {
  125. obj = buf->priv;
  126. if (obj->dev == dev) {
  127. /*
  128. * Importing dmabuf exported from our own gem increases
  129. * refcount on gem itself instead of f_count of dmabuf.
  130. */
  131. drm_gem_object_get(obj);
  132. return obj;
  133. }
  134. }
  135. return drm_gem_prime_import(dev, buf);
  136. }
  137. struct drm_gem_object *virtgpu_gem_prime_import_sg_table(
  138. struct drm_device *dev, struct dma_buf_attachment *attach,
  139. struct sg_table *table)
  140. {
  141. return ERR_PTR(-ENODEV);
  142. }