virtio-dmabuf.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*
  2. * Virtio Shared dma-buf
  3. *
  4. * Copyright Red Hat, Inc. 2023
  5. *
  6. * Authors:
  7. * Albert Esteve <aesteve@redhat.com>
  8. *
  9. * This work is licensed under the terms of the GNU GPL, version 2 or later.
  10. * See the COPYING file in the top-level directory.
  11. */
  12. #include "qemu/osdep.h"
  13. #include "hw/virtio/virtio-dmabuf.h"
  14. static GMutex lock;
  15. static GHashTable *resource_uuids;
  16. /*
  17. * uuid_equal_func: wrapper for UUID is_equal function to
  18. * satisfy g_hash_table_new expected parameters signatures.
  19. */
  20. static int uuid_equal_func(const void *lhv, const void *rhv)
  21. {
  22. return qemu_uuid_is_equal(lhv, rhv);
  23. }
  24. static bool virtio_add_resource(QemuUUID *uuid, VirtioSharedObject *value)
  25. {
  26. bool result = true;
  27. g_mutex_lock(&lock);
  28. if (resource_uuids == NULL) {
  29. resource_uuids = g_hash_table_new_full(qemu_uuid_hash,
  30. uuid_equal_func,
  31. NULL,
  32. g_free);
  33. }
  34. if (g_hash_table_lookup(resource_uuids, uuid) == NULL) {
  35. g_hash_table_insert(resource_uuids, uuid, value);
  36. } else {
  37. result = false;
  38. }
  39. g_mutex_unlock(&lock);
  40. return result;
  41. }
  42. bool virtio_add_dmabuf(QemuUUID *uuid, int udmabuf_fd)
  43. {
  44. bool result;
  45. VirtioSharedObject *vso;
  46. if (udmabuf_fd < 0) {
  47. return false;
  48. }
  49. vso = g_new(VirtioSharedObject, 1);
  50. vso->type = TYPE_DMABUF;
  51. vso->value = GINT_TO_POINTER(udmabuf_fd);
  52. result = virtio_add_resource(uuid, vso);
  53. if (!result) {
  54. g_free(vso);
  55. }
  56. return result;
  57. }
  58. bool virtio_add_vhost_device(QemuUUID *uuid, struct vhost_dev *dev)
  59. {
  60. bool result;
  61. VirtioSharedObject *vso;
  62. if (dev == NULL) {
  63. return false;
  64. }
  65. vso = g_new(VirtioSharedObject, 1);
  66. vso->type = TYPE_VHOST_DEV;
  67. vso->value = dev;
  68. result = virtio_add_resource(uuid, vso);
  69. if (!result) {
  70. g_free(vso);
  71. }
  72. return result;
  73. }
  74. bool virtio_remove_resource(const QemuUUID *uuid)
  75. {
  76. bool result;
  77. g_mutex_lock(&lock);
  78. result = g_hash_table_remove(resource_uuids, uuid);
  79. g_mutex_unlock(&lock);
  80. return result;
  81. }
  82. static VirtioSharedObject *get_shared_object(const QemuUUID *uuid)
  83. {
  84. gpointer lookup_res = NULL;
  85. g_mutex_lock(&lock);
  86. if (resource_uuids != NULL) {
  87. lookup_res = g_hash_table_lookup(resource_uuids, uuid);
  88. }
  89. g_mutex_unlock(&lock);
  90. return (VirtioSharedObject *) lookup_res;
  91. }
  92. int virtio_lookup_dmabuf(const QemuUUID *uuid)
  93. {
  94. VirtioSharedObject *vso = get_shared_object(uuid);
  95. if (vso == NULL) {
  96. return -1;
  97. }
  98. assert(vso->type == TYPE_DMABUF);
  99. return GPOINTER_TO_INT(vso->value);
  100. }
  101. struct vhost_dev *virtio_lookup_vhost_device(const QemuUUID *uuid)
  102. {
  103. VirtioSharedObject *vso = get_shared_object(uuid);
  104. if (vso == NULL) {
  105. return NULL;
  106. }
  107. assert(vso->type == TYPE_VHOST_DEV);
  108. return (struct vhost_dev *) vso->value;
  109. }
  110. SharedObjectType virtio_object_type(const QemuUUID *uuid)
  111. {
  112. VirtioSharedObject *vso = get_shared_object(uuid);
  113. if (vso == NULL) {
  114. return TYPE_INVALID;
  115. }
  116. return vso->type;
  117. }
  118. void virtio_free_resources(void)
  119. {
  120. g_mutex_lock(&lock);
  121. g_hash_table_destroy(resource_uuids);
  122. /* Reference count shall be 0 after the implicit unref on destroy */
  123. resource_uuids = NULL;
  124. g_mutex_unlock(&lock);
  125. }