xref: /qemu/hw/vfio-user/container.c (revision aec6836c73403cffa56b9a4c5556451ee16071fe)
1 /*
2  * Container for vfio-user IOMMU type: rather than communicating with the kernel
3  * vfio driver, we communicate over a socket to a server using the vfio-user
4  * protocol.
5  *
6  * SPDX-License-Identifier: GPL-2.0-or-later
7  */
8 
9 #include <sys/ioctl.h>
10 #include <linux/vfio.h>
11 #include "qemu/osdep.h"
12 
13 #include "hw/vfio-user/container.h"
14 #include "hw/vfio-user/device.h"
15 #include "hw/vfio-user/trace.h"
16 #include "hw/vfio/vfio-cpr.h"
17 #include "hw/vfio/vfio-device.h"
18 #include "hw/vfio/vfio-listener.h"
19 #include "qapi/error.h"
20 
21 /*
22  * When DMA space is the physical address space, the region add/del listeners
23  * will fire during memory update transactions.  These depend on BQL being held,
24  * so do any resulting map/demap ops async while keeping BQL.
25  */
26 static void vfio_user_listener_begin(VFIOContainerBase *bcontainer)
27 {
28     VFIOUserContainer *container = container_of(bcontainer, VFIOUserContainer,
29                                                  bcontainer);
30 
31     container->proxy->async_ops = true;
32 }
33 
34 static void vfio_user_listener_commit(VFIOContainerBase *bcontainer)
35 {
36     VFIOUserContainer *container = container_of(bcontainer, VFIOUserContainer,
37                                             bcontainer);
38 
39     /* wait here for any async requests sent during the transaction */
40     container->proxy->async_ops = false;
41     vfio_user_wait_reqs(container->proxy);
42 }
43 
44 static int vfio_user_dma_unmap(const VFIOContainerBase *bcontainer,
45                                hwaddr iova, ram_addr_t size,
46                                IOMMUTLBEntry *iotlb, bool unmap_all)
47 {
48     VFIOUserContainer *container = container_of(bcontainer, VFIOUserContainer,
49                                             bcontainer);
50     Error *local_err = NULL;
51     int ret = 0;
52 
53     VFIOUserDMAUnmap *msgp = g_malloc(sizeof(*msgp));
54 
55     vfio_user_request_msg(&msgp->hdr, VFIO_USER_DMA_UNMAP, sizeof(*msgp), 0);
56     msgp->argsz = sizeof(struct vfio_iommu_type1_dma_unmap);
57     msgp->flags = unmap_all ? VFIO_DMA_UNMAP_FLAG_ALL : 0;
58     msgp->iova = iova;
59     msgp->size = size;
60     trace_vfio_user_dma_unmap(msgp->iova, msgp->size, msgp->flags,
61                               container->proxy->async_ops);
62 
63     if (container->proxy->async_ops) {
64         if (!vfio_user_send_nowait(container->proxy, &msgp->hdr, NULL,
65                               0, &local_err)) {
66             error_report_err(local_err);
67             ret = -EFAULT;
68         } else {
69             ret = 0;
70         }
71     } else {
72         if (!vfio_user_send_wait(container->proxy, &msgp->hdr, NULL,
73                                  0, &local_err)) {
74                 error_report_err(local_err);
75                 ret = -EFAULT;
76         }
77 
78         if (msgp->hdr.flags & VFIO_USER_ERROR) {
79             ret = -msgp->hdr.error_reply;
80         }
81 
82         g_free(msgp);
83     }
84 
85     return ret;
86 }
87 
88 static int vfio_user_dma_map(const VFIOContainerBase *bcontainer, hwaddr iova,
89                              ram_addr_t size, void *vaddr, bool readonly,
90                              MemoryRegion *mrp)
91 {
92     VFIOUserContainer *container = container_of(bcontainer, VFIOUserContainer,
93                                                 bcontainer);
94     int fd = memory_region_get_fd(mrp);
95     Error *local_err = NULL;
96     int ret;
97 
98     VFIOUserFDs *fds = NULL;
99     VFIOUserDMAMap *msgp = g_malloc0(sizeof(*msgp));
100 
101     vfio_user_request_msg(&msgp->hdr, VFIO_USER_DMA_MAP, sizeof(*msgp), 0);
102     msgp->argsz = sizeof(struct vfio_iommu_type1_dma_map);
103     msgp->flags = VFIO_DMA_MAP_FLAG_READ;
104     msgp->offset = 0;
105     msgp->iova = iova;
106     msgp->size = size;
107 
108     /*
109      * vaddr enters as a QEMU process address; make it either a file offset
110      * for mapped areas or leave as 0.
111      */
112     if (fd != -1) {
113         msgp->offset = qemu_ram_block_host_offset(mrp->ram_block, vaddr);
114     }
115 
116     if (!readonly) {
117         msgp->flags |= VFIO_DMA_MAP_FLAG_WRITE;
118     }
119 
120     trace_vfio_user_dma_map(msgp->iova, msgp->size, msgp->offset, msgp->flags,
121                             container->proxy->async_ops);
122 
123     /*
124      * The async_ops case sends without blocking. They're later waited for in
125      * vfio_send_wait_reqs.
126      */
127     if (container->proxy->async_ops) {
128         /* can't use auto variable since we don't block */
129         if (fd != -1) {
130             fds = vfio_user_getfds(1);
131             fds->send_fds = 1;
132             fds->fds[0] = fd;
133         }
134 
135         if (!vfio_user_send_nowait(container->proxy, &msgp->hdr, fds,
136                               0, &local_err)) {
137             error_report_err(local_err);
138             ret = -EFAULT;
139         } else {
140             ret = 0;
141         }
142     } else {
143         VFIOUserFDs local_fds = { 1, 0, &fd };
144 
145         fds = fd != -1 ? &local_fds : NULL;
146 
147         if (!vfio_user_send_wait(container->proxy, &msgp->hdr, fds,
148                                  0, &local_err)) {
149                 error_report_err(local_err);
150                 ret = -EFAULT;
151         }
152 
153         if (msgp->hdr.flags & VFIO_USER_ERROR) {
154             ret = -msgp->hdr.error_reply;
155         }
156 
157         g_free(msgp);
158     }
159 
160     return ret;
161 }
162 
163 static int
164 vfio_user_set_dirty_page_tracking(const VFIOContainerBase *bcontainer,
165                                     bool start, Error **errp)
166 {
167     error_setg_errno(errp, ENOTSUP, "Not supported");
168     return -ENOTSUP;
169 }
170 
171 static int vfio_user_query_dirty_bitmap(const VFIOContainerBase *bcontainer,
172                                          VFIOBitmap *vbmap, hwaddr iova,
173                                          hwaddr size, Error **errp)
174 {
175     error_setg_errno(errp, ENOTSUP, "Not supported");
176     return -ENOTSUP;
177 }
178 
179 static bool vfio_user_setup(VFIOContainerBase *bcontainer, Error **errp)
180 {
181     VFIOUserContainer *container = container_of(bcontainer, VFIOUserContainer,
182                                                 bcontainer);
183 
184     assert(container->proxy->dma_pgsizes != 0);
185     bcontainer->pgsizes = container->proxy->dma_pgsizes;
186     bcontainer->dma_max_mappings = container->proxy->max_dma;
187 
188     /* No live migration support yet. */
189     bcontainer->dirty_pages_supported = false;
190     bcontainer->max_dirty_bitmap_size = container->proxy->max_bitmap;
191     bcontainer->dirty_pgsizes = container->proxy->migr_pgsize;
192 
193     return true;
194 }
195 
196 static VFIOUserContainer *vfio_user_create_container(VFIODevice *vbasedev,
197                                                      Error **errp)
198 {
199     VFIOUserContainer *container;
200 
201     container = VFIO_IOMMU_USER(object_new(TYPE_VFIO_IOMMU_USER));
202     container->proxy = vbasedev->proxy;
203     return container;
204 }
205 
206 /*
207  * Try to mirror vfio_container_connect() as much as possible.
208  */
209 static VFIOUserContainer *
210 vfio_user_container_connect(AddressSpace *as, VFIODevice *vbasedev,
211                             Error **errp)
212 {
213     VFIOContainerBase *bcontainer;
214     VFIOUserContainer *container;
215     VFIOAddressSpace *space;
216     VFIOIOMMUClass *vioc;
217     int ret;
218 
219     space = vfio_address_space_get(as);
220 
221     container = vfio_user_create_container(vbasedev, errp);
222     if (!container) {
223         goto put_space_exit;
224     }
225 
226     bcontainer = &container->bcontainer;
227 
228     if (!vfio_cpr_register_container(bcontainer, errp)) {
229         goto free_container_exit;
230     }
231 
232     ret = ram_block_uncoordinated_discard_disable(true);
233     if (ret) {
234         error_setg_errno(errp, -ret, "Cannot set discarding of RAM broken");
235         goto unregister_container_exit;
236     }
237 
238     vioc = VFIO_IOMMU_GET_CLASS(bcontainer);
239     assert(vioc->setup);
240 
241     if (!vioc->setup(bcontainer, errp)) {
242         goto enable_discards_exit;
243     }
244 
245     vfio_address_space_insert(space, bcontainer);
246 
247     if (!vfio_listener_register(bcontainer, errp)) {
248         goto listener_release_exit;
249     }
250 
251     bcontainer->initialized = true;
252 
253     return container;
254 
255 listener_release_exit:
256     vfio_listener_unregister(bcontainer);
257     if (vioc->release) {
258         vioc->release(bcontainer);
259     }
260 
261 enable_discards_exit:
262     ram_block_uncoordinated_discard_disable(false);
263 
264 unregister_container_exit:
265     vfio_cpr_unregister_container(bcontainer);
266 
267 free_container_exit:
268     object_unref(container);
269 
270 put_space_exit:
271     vfio_address_space_put(space);
272 
273     return NULL;
274 }
275 
276 static void vfio_user_container_disconnect(VFIOUserContainer *container)
277 {
278     VFIOContainerBase *bcontainer = &container->bcontainer;
279     VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer);
280     VFIOAddressSpace *space = bcontainer->space;
281 
282     ram_block_uncoordinated_discard_disable(false);
283 
284     vfio_listener_unregister(bcontainer);
285     if (vioc->release) {
286         vioc->release(bcontainer);
287     }
288 
289     vfio_cpr_unregister_container(bcontainer);
290     object_unref(container);
291 
292     vfio_address_space_put(space);
293 }
294 
295 static bool vfio_user_device_get(VFIOUserContainer *container,
296                                  VFIODevice *vbasedev, Error **errp)
297 {
298     struct vfio_device_info info = { .argsz = sizeof(info) };
299 
300 
301     if (!vfio_user_get_device_info(vbasedev->proxy, &info, errp)) {
302         return false;
303     }
304 
305     vbasedev->fd = -1;
306 
307     vfio_device_prepare(vbasedev, &container->bcontainer, &info);
308 
309     return true;
310 }
311 
312 /*
313  * vfio_user_device_attach: attach a device to a new container.
314  */
315 static bool vfio_user_device_attach(const char *name, VFIODevice *vbasedev,
316                                     AddressSpace *as, Error **errp)
317 {
318     VFIOUserContainer *container;
319 
320     container = vfio_user_container_connect(as, vbasedev, errp);
321     if (container == NULL) {
322         error_prepend(errp, "failed to connect proxy");
323         return false;
324     }
325 
326     return vfio_user_device_get(container, vbasedev, errp);
327 }
328 
329 static void vfio_user_device_detach(VFIODevice *vbasedev)
330 {
331     VFIOUserContainer *container = container_of(vbasedev->bcontainer,
332                                                 VFIOUserContainer, bcontainer);
333 
334     vfio_device_unprepare(vbasedev);
335 
336     vfio_user_container_disconnect(container);
337 }
338 
339 static int vfio_user_pci_hot_reset(VFIODevice *vbasedev, bool single)
340 {
341     /* ->needs_reset is always false for vfio-user. */
342     return 0;
343 }
344 
345 static void vfio_iommu_user_class_init(ObjectClass *klass, const void *data)
346 {
347     VFIOIOMMUClass *vioc = VFIO_IOMMU_CLASS(klass);
348 
349     vioc->setup = vfio_user_setup;
350     vioc->listener_begin = vfio_user_listener_begin,
351     vioc->listener_commit = vfio_user_listener_commit,
352     vioc->dma_map = vfio_user_dma_map;
353     vioc->dma_unmap = vfio_user_dma_unmap;
354     vioc->attach_device = vfio_user_device_attach;
355     vioc->detach_device = vfio_user_device_detach;
356     vioc->set_dirty_page_tracking = vfio_user_set_dirty_page_tracking;
357     vioc->query_dirty_bitmap = vfio_user_query_dirty_bitmap;
358     vioc->pci_hot_reset = vfio_user_pci_hot_reset;
359 };
360 
361 static const TypeInfo types[] = {
362     {
363         .name = TYPE_VFIO_IOMMU_USER,
364         .parent = TYPE_VFIO_IOMMU,
365         .instance_size = sizeof(VFIOUserContainer),
366         .class_init = vfio_iommu_user_class_init,
367     },
368 };
369 
370 DEFINE_TYPES(types)
371