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