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