xref: /qemu/hw/virtio/vhost-shadow-virtqueue.c (revision 05063f55841babae7216d36105440ed8ba632938)
1 /*
2  * vhost shadow virtqueue
3  *
4  * SPDX-FileCopyrightText: Red Hat, Inc. 2021
5  * SPDX-FileContributor: Author: Eugenio Pérez <eperezma@redhat.com>
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  */
9 
10 #include "qemu/osdep.h"
11 #include "hw/virtio/vhost-shadow-virtqueue.h"
12 
13 #include "qemu/error-report.h"
14 #include "qapi/error.h"
15 #include "qemu/main-loop.h"
16 #include "qemu/log.h"
17 #include "qemu/memalign.h"
18 #include "linux-headers/linux/vhost.h"
19 
20 /**
21  * Validate the transport device features that both guests can use with the SVQ
22  * and SVQs can use with the device.
23  *
24  * @dev_features: The features
25  * @errp: Error pointer
26  */
27 bool vhost_svq_valid_features(uint64_t features, Error **errp)
28 {
29     bool ok = true;
30     uint64_t svq_features = features;
31 
32     for (uint64_t b = VIRTIO_TRANSPORT_F_START; b <= VIRTIO_TRANSPORT_F_END;
33          ++b) {
34         switch (b) {
35         case VIRTIO_F_ANY_LAYOUT:
36         case VIRTIO_RING_F_EVENT_IDX:
37             continue;
38 
39         case VIRTIO_F_ACCESS_PLATFORM:
40             /* SVQ trust in the host's IOMMU to translate addresses */
41         case VIRTIO_F_VERSION_1:
42             /* SVQ trust that the guest vring is little endian */
43             if (!(svq_features & BIT_ULL(b))) {
44                 svq_features |= BIT_ULL(b);
45                 ok = false;
46             }
47             continue;
48 
49         default:
50             if (svq_features & BIT_ULL(b)) {
51                 svq_features &= ~BIT_ULL(b);
52                 ok = false;
53             }
54         }
55     }
56 
57     if (!ok) {
58         error_setg(errp, "SVQ Invalid device feature flags, offer: 0x%"PRIx64
59                          ", ok: 0x%"PRIx64, features, svq_features);
60     }
61     return ok;
62 }
63 
64 /**
65  * Number of descriptors that the SVQ can make available from the guest.
66  *
67  * @svq: The svq
68  */
69 uint16_t vhost_svq_available_slots(const VhostShadowVirtqueue *svq)
70 {
71     return svq->num_free;
72 }
73 
74 /**
75  * Translate addresses between the qemu's virtual address and the SVQ IOVA
76  *
77  * @svq: Shadow VirtQueue
78  * @vaddr: Translated IOVA addresses
79  * @iovec: Source qemu's VA addresses
80  * @num: Length of iovec and minimum length of vaddr
81  * @gpas: Descriptors' GPAs, if backed by guest memory
82  */
83 static bool vhost_svq_translate_addr(const VhostShadowVirtqueue *svq,
84                                      hwaddr *addrs, const struct iovec *iovec,
85                                      size_t num, const hwaddr *gpas)
86 {
87     if (num == 0) {
88         return true;
89     }
90 
91     for (size_t i = 0; i < num; ++i) {
92         Int128 needle_last, map_last;
93         size_t off;
94         const DMAMap *map;
95         DMAMap needle;
96 
97         /* Check if the descriptor is backed by guest memory  */
98         if (gpas) {
99             /* Search the GPA->IOVA tree */
100             needle = (DMAMap) {
101                 .translated_addr = gpas[i],
102                 .size = iovec[i].iov_len,
103             };
104             map = vhost_iova_tree_find_gpa(svq->iova_tree, &needle);
105         } else {
106             /* Search the IOVA->HVA tree */
107             needle = (DMAMap) {
108                 .translated_addr = (hwaddr)(uintptr_t)iovec[i].iov_base,
109                 .size = iovec[i].iov_len,
110             };
111             map = vhost_iova_tree_find_iova(svq->iova_tree, &needle);
112         }
113 
114         /*
115          * Map cannot be NULL since iova map contains all guest space and
116          * qemu already has a physical address mapped
117          */
118         if (unlikely(!map)) {
119             qemu_log_mask(LOG_GUEST_ERROR,
120                           "Invalid address 0x%"HWADDR_PRIx" given by guest",
121                           needle.translated_addr);
122             return false;
123         }
124 
125         off = needle.translated_addr - map->translated_addr;
126         addrs[i] = map->iova + off;
127 
128         needle_last = int128_add(int128_make64(needle.translated_addr),
129                                  int128_makes64(iovec[i].iov_len - 1));
130         map_last = int128_make64(map->translated_addr + map->size);
131         if (unlikely(int128_gt(needle_last, map_last))) {
132             qemu_log_mask(LOG_GUEST_ERROR,
133                           "Guest buffer expands over iova range");
134             return false;
135         }
136     }
137 
138     return true;
139 }
140 
141 /**
142  * Write descriptors to SVQ vring
143  *
144  * @svq: The shadow virtqueue
145  * @sg: Cache for hwaddr
146  * @iovec: The iovec from the guest
147  * @num: iovec length
148  * @addr: Descriptors' GPAs, if backed by guest memory
149  * @more_descs: True if more descriptors come in the chain
150  * @write: True if they are writeable descriptors
151  *
152  * Return true if success, false otherwise and print error.
153  */
154 static bool vhost_svq_vring_write_descs(VhostShadowVirtqueue *svq, hwaddr *sg,
155                                         const struct iovec *iovec, size_t num,
156                                         const hwaddr *addr, bool more_descs,
157                                         bool write)
158 {
159     uint16_t i = svq->free_head, last = svq->free_head;
160     unsigned n;
161     uint16_t flags = write ? cpu_to_le16(VRING_DESC_F_WRITE) : 0;
162     vring_desc_t *descs = svq->vring.desc;
163     bool ok;
164 
165     if (num == 0) {
166         return true;
167     }
168 
169     ok = vhost_svq_translate_addr(svq, sg, iovec, num, addr);
170     if (unlikely(!ok)) {
171         return false;
172     }
173 
174     for (n = 0; n < num; n++) {
175         if (more_descs || (n + 1 < num)) {
176             descs[i].flags = flags | cpu_to_le16(VRING_DESC_F_NEXT);
177             descs[i].next = cpu_to_le16(svq->desc_next[i]);
178         } else {
179             descs[i].flags = flags;
180         }
181         descs[i].addr = cpu_to_le64(sg[n]);
182         descs[i].len = cpu_to_le32(iovec[n].iov_len);
183 
184         last = i;
185         i = cpu_to_le16(svq->desc_next[i]);
186     }
187 
188     svq->free_head = le16_to_cpu(svq->desc_next[last]);
189     return true;
190 }
191 
192 static bool vhost_svq_add_split(VhostShadowVirtqueue *svq,
193                                 const struct iovec *out_sg, size_t out_num,
194                                 const hwaddr *out_addr,
195                                 const struct iovec *in_sg, size_t in_num,
196                                 const hwaddr *in_addr, unsigned *head)
197 {
198     unsigned avail_idx;
199     vring_avail_t *avail = svq->vring.avail;
200     bool ok;
201     g_autofree hwaddr *sgs = g_new(hwaddr, MAX(out_num, in_num));
202 
203     *head = svq->free_head;
204 
205     /* We need some descriptors here */
206     if (unlikely(!out_num && !in_num)) {
207         qemu_log_mask(LOG_GUEST_ERROR,
208                       "Guest provided element with no descriptors");
209         return false;
210     }
211 
212     ok = vhost_svq_vring_write_descs(svq, sgs, out_sg, out_num, out_addr,
213                                      in_num > 0, false);
214     if (unlikely(!ok)) {
215         return false;
216     }
217 
218     ok = vhost_svq_vring_write_descs(svq, sgs, in_sg, in_num, in_addr, false,
219                                      true);
220     if (unlikely(!ok)) {
221         return false;
222     }
223 
224     /*
225      * Put the entry in the available array (but don't update avail->idx until
226      * they do sync).
227      */
228     avail_idx = svq->shadow_avail_idx & (svq->vring.num - 1);
229     avail->ring[avail_idx] = cpu_to_le16(*head);
230     svq->shadow_avail_idx++;
231 
232     /* Update the avail index after write the descriptor */
233     smp_wmb();
234     avail->idx = cpu_to_le16(svq->shadow_avail_idx);
235 
236     return true;
237 }
238 
239 static void vhost_svq_kick(VhostShadowVirtqueue *svq)
240 {
241     bool needs_kick;
242 
243     /*
244      * We need to expose the available array entries before checking the used
245      * flags
246      */
247     smp_mb();
248 
249     if (virtio_vdev_has_feature(svq->vdev, VIRTIO_RING_F_EVENT_IDX)) {
250         uint16_t avail_event = *(uint16_t *)(&svq->vring.used->ring[svq->vring.num]);
251         needs_kick = vring_need_event(avail_event, svq->shadow_avail_idx, svq->shadow_avail_idx - 1);
252     } else {
253         needs_kick = !(svq->vring.used->flags & VRING_USED_F_NO_NOTIFY);
254     }
255 
256     if (!needs_kick) {
257         return;
258     }
259 
260     event_notifier_set(&svq->hdev_kick);
261 }
262 
263 /**
264  * Add an element to a SVQ.
265  *
266  * Return -EINVAL if element is invalid, -ENOSPC if dev queue is full
267  */
268 int vhost_svq_add(VhostShadowVirtqueue *svq, const struct iovec *out_sg,
269                   size_t out_num, const hwaddr *out_addr,
270                   const struct iovec *in_sg, size_t in_num,
271                   const hwaddr *in_addr, VirtQueueElement *elem)
272 {
273     unsigned qemu_head;
274     unsigned ndescs = in_num + out_num;
275     bool ok;
276 
277     if (unlikely(ndescs > vhost_svq_available_slots(svq))) {
278         return -ENOSPC;
279     }
280 
281     ok = vhost_svq_add_split(svq, out_sg, out_num, out_addr, in_sg, in_num,
282                              in_addr, &qemu_head);
283     if (unlikely(!ok)) {
284         return -EINVAL;
285     }
286 
287     svq->num_free -= ndescs;
288     svq->desc_state[qemu_head].elem = elem;
289     svq->desc_state[qemu_head].ndescs = ndescs;
290     vhost_svq_kick(svq);
291     return 0;
292 }
293 
294 /* Convenience wrapper to add a guest's element to SVQ */
295 static int vhost_svq_add_element(VhostShadowVirtqueue *svq,
296                                  VirtQueueElement *elem)
297 {
298     return vhost_svq_add(svq, elem->out_sg, elem->out_num, elem->out_addr,
299                          elem->in_sg, elem->in_num, elem->in_addr, elem);
300 }
301 
302 /**
303  * Forward available buffers.
304  *
305  * @svq: Shadow VirtQueue
306  *
307  * Note that this function does not guarantee that all guest's available
308  * buffers are available to the device in SVQ avail ring. The guest may have
309  * exposed a GPA / GIOVA contiguous buffer, but it may not be contiguous in
310  * qemu vaddr.
311  *
312  * If that happens, guest's kick notifications will be disabled until the
313  * device uses some buffers.
314  */
315 static void vhost_handle_guest_kick(VhostShadowVirtqueue *svq)
316 {
317     /* Clear event notifier */
318     event_notifier_test_and_clear(&svq->svq_kick);
319 
320     /* Forward to the device as many available buffers as possible */
321     do {
322         virtio_queue_set_notification(svq->vq, false);
323 
324         while (true) {
325             g_autofree VirtQueueElement *elem = NULL;
326             int r;
327 
328             if (svq->next_guest_avail_elem) {
329                 elem = g_steal_pointer(&svq->next_guest_avail_elem);
330             } else {
331                 elem = virtqueue_pop(svq->vq, sizeof(*elem));
332             }
333 
334             if (!elem) {
335                 break;
336             }
337 
338             if (svq->ops) {
339                 r = svq->ops->avail_handler(svq, elem, svq->ops_opaque);
340             } else {
341                 r = vhost_svq_add_element(svq, elem);
342             }
343             if (unlikely(r != 0)) {
344                 if (r == -ENOSPC) {
345                     /*
346                      * This condition is possible since a contiguous buffer in
347                      * GPA does not imply a contiguous buffer in qemu's VA
348                      * scatter-gather segments. If that happens, the buffer
349                      * exposed to the device needs to be a chain of descriptors
350                      * at this moment.
351                      *
352                      * SVQ cannot hold more available buffers if we are here:
353                      * queue the current guest descriptor and ignore kicks
354                      * until some elements are used.
355                      */
356                     svq->next_guest_avail_elem = g_steal_pointer(&elem);
357                 }
358 
359                 /* VQ is full or broken, just return and ignore kicks */
360                 return;
361             }
362             /* elem belongs to SVQ or external caller now */
363             elem = NULL;
364         }
365 
366         virtio_queue_set_notification(svq->vq, true);
367     } while (!virtio_queue_empty(svq->vq));
368 }
369 
370 /**
371  * Handle guest's kick.
372  *
373  * @n: guest kick event notifier, the one that guest set to notify svq.
374  */
375 static void vhost_handle_guest_kick_notifier(EventNotifier *n)
376 {
377     VhostShadowVirtqueue *svq = container_of(n, VhostShadowVirtqueue, svq_kick);
378     event_notifier_test_and_clear(n);
379     vhost_handle_guest_kick(svq);
380 }
381 
382 static bool vhost_svq_more_used(VhostShadowVirtqueue *svq)
383 {
384     uint16_t *used_idx = &svq->vring.used->idx;
385     if (svq->last_used_idx != svq->shadow_used_idx) {
386         return true;
387     }
388 
389     svq->shadow_used_idx = cpu_to_le16(*(volatile uint16_t *)used_idx);
390 
391     return svq->last_used_idx != svq->shadow_used_idx;
392 }
393 
394 /**
395  * Enable vhost device calls after disable them.
396  *
397  * @svq: The svq
398  *
399  * It returns false if there are pending used buffers from the vhost device,
400  * avoiding the possible races between SVQ checking for more work and enabling
401  * callbacks. True if SVQ used vring has no more pending buffers.
402  */
403 static bool vhost_svq_enable_notification(VhostShadowVirtqueue *svq)
404 {
405     if (virtio_vdev_has_feature(svq->vdev, VIRTIO_RING_F_EVENT_IDX)) {
406         uint16_t *used_event = (uint16_t *)&svq->vring.avail->ring[svq->vring.num];
407         *used_event = svq->shadow_used_idx;
408     } else {
409         svq->vring.avail->flags &= ~cpu_to_le16(VRING_AVAIL_F_NO_INTERRUPT);
410     }
411 
412     /* Make sure the event is enabled before the read of used_idx */
413     smp_mb();
414     return !vhost_svq_more_used(svq);
415 }
416 
417 static void vhost_svq_disable_notification(VhostShadowVirtqueue *svq)
418 {
419     /*
420      * No need to disable notification in the event idx case, since used event
421      * index is already an index too far away.
422      */
423     if (!virtio_vdev_has_feature(svq->vdev, VIRTIO_RING_F_EVENT_IDX)) {
424         svq->vring.avail->flags |= cpu_to_le16(VRING_AVAIL_F_NO_INTERRUPT);
425     }
426 }
427 
428 static uint16_t vhost_svq_last_desc_of_chain(const VhostShadowVirtqueue *svq,
429                                              uint16_t num, uint16_t i)
430 {
431     for (uint16_t j = 0; j < (num - 1); ++j) {
432         i = le16_to_cpu(svq->desc_next[i]);
433     }
434 
435     return i;
436 }
437 
438 G_GNUC_WARN_UNUSED_RESULT
439 static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq,
440                                            uint32_t *len)
441 {
442     const vring_used_t *used = svq->vring.used;
443     vring_used_elem_t used_elem;
444     uint16_t last_used, last_used_chain, num;
445 
446     if (!vhost_svq_more_used(svq)) {
447         return NULL;
448     }
449 
450     /* Only get used array entries after they have been exposed by dev */
451     smp_rmb();
452     last_used = svq->last_used_idx & (svq->vring.num - 1);
453     used_elem.id = le32_to_cpu(used->ring[last_used].id);
454     used_elem.len = le32_to_cpu(used->ring[last_used].len);
455 
456     svq->last_used_idx++;
457     if (unlikely(used_elem.id >= svq->vring.num)) {
458         qemu_log_mask(LOG_GUEST_ERROR, "Device %s says index %u is used",
459                       svq->vdev->name, used_elem.id);
460         return NULL;
461     }
462 
463     if (unlikely(!svq->desc_state[used_elem.id].ndescs)) {
464         qemu_log_mask(LOG_GUEST_ERROR,
465             "Device %s says index %u is used, but it was not available",
466             svq->vdev->name, used_elem.id);
467         return NULL;
468     }
469 
470     num = svq->desc_state[used_elem.id].ndescs;
471     svq->desc_state[used_elem.id].ndescs = 0;
472     last_used_chain = vhost_svq_last_desc_of_chain(svq, num, used_elem.id);
473     svq->desc_next[last_used_chain] = svq->free_head;
474     svq->free_head = used_elem.id;
475     svq->num_free += num;
476 
477     *len = used_elem.len;
478     return g_steal_pointer(&svq->desc_state[used_elem.id].elem);
479 }
480 
481 /**
482  * Push an element to SVQ, returning it to the guest.
483  */
484 void vhost_svq_push_elem(VhostShadowVirtqueue *svq,
485                          const VirtQueueElement *elem, uint32_t len)
486 {
487     virtqueue_push(svq->vq, elem, len);
488     if (svq->next_guest_avail_elem) {
489         /*
490          * Avail ring was full when vhost_svq_flush was called, so it's a
491          * good moment to make more descriptors available if possible.
492          */
493         vhost_handle_guest_kick(svq);
494     }
495 }
496 
497 static void vhost_svq_flush(VhostShadowVirtqueue *svq,
498                             bool check_for_avail_queue)
499 {
500     VirtQueue *vq = svq->vq;
501 
502     /* Forward as many used buffers as possible. */
503     do {
504         unsigned i = 0;
505 
506         vhost_svq_disable_notification(svq);
507         while (true) {
508             uint32_t len;
509             g_autofree VirtQueueElement *elem = vhost_svq_get_buf(svq, &len);
510             if (!elem) {
511                 break;
512             }
513 
514             if (unlikely(i >= svq->vring.num)) {
515                 qemu_log_mask(LOG_GUEST_ERROR,
516                          "More than %u used buffers obtained in a %u size SVQ",
517                          i, svq->vring.num);
518                 virtqueue_fill(vq, elem, len, i);
519                 virtqueue_flush(vq, i);
520                 return;
521             }
522             virtqueue_fill(vq, elem, len, i++);
523         }
524 
525         virtqueue_flush(vq, i);
526         event_notifier_set(&svq->svq_call);
527 
528         if (check_for_avail_queue && svq->next_guest_avail_elem) {
529             /*
530              * Avail ring was full when vhost_svq_flush was called, so it's a
531              * good moment to make more descriptors available if possible.
532              */
533             vhost_handle_guest_kick(svq);
534         }
535     } while (!vhost_svq_enable_notification(svq));
536 }
537 
538 /**
539  * Poll the SVQ to wait for the device to use the specified number
540  * of elements and return the total length written by the device.
541  *
542  * This function race with main event loop SVQ polling, so extra
543  * synchronization is needed.
544  *
545  * @svq: The svq
546  * @num: The number of elements that need to be used
547  */
548 size_t vhost_svq_poll(VhostShadowVirtqueue *svq, size_t num)
549 {
550     size_t len = 0;
551 
552     while (num--) {
553         g_autofree VirtQueueElement *elem = NULL;
554         int64_t start_us = g_get_monotonic_time();
555         uint32_t r = 0;
556 
557         do {
558             if (vhost_svq_more_used(svq)) {
559                 break;
560             }
561 
562             if (unlikely(g_get_monotonic_time() - start_us > 10e6)) {
563                 return len;
564             }
565         } while (true);
566 
567         elem = vhost_svq_get_buf(svq, &r);
568         len += r;
569     }
570 
571     return len;
572 }
573 
574 /**
575  * Forward used buffers.
576  *
577  * @n: hdev call event notifier, the one that device set to notify svq.
578  *
579  * Note that we are not making any buffers available in the loop, there is no
580  * way that it runs more than virtqueue size times.
581  */
582 static void vhost_svq_handle_call(EventNotifier *n)
583 {
584     VhostShadowVirtqueue *svq = container_of(n, VhostShadowVirtqueue,
585                                              hdev_call);
586     event_notifier_test_and_clear(n);
587     vhost_svq_flush(svq, true);
588 }
589 
590 /**
591  * Set the call notifier for the SVQ to call the guest
592  *
593  * @svq: Shadow virtqueue
594  * @call_fd: call notifier
595  *
596  * Called on BQL context.
597  */
598 void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd)
599 {
600     if (call_fd == VHOST_FILE_UNBIND) {
601         /*
602          * Fail event_notifier_set if called handling device call.
603          *
604          * SVQ still needs device notifications, since it needs to keep
605          * forwarding used buffers even with the unbind.
606          */
607         memset(&svq->svq_call, 0, sizeof(svq->svq_call));
608     } else {
609         event_notifier_init_fd(&svq->svq_call, call_fd);
610     }
611 }
612 
613 /**
614  * Get the shadow vq vring address.
615  * @svq: Shadow virtqueue
616  * @addr: Destination to store address
617  */
618 void vhost_svq_get_vring_addr(const VhostShadowVirtqueue *svq,
619                               struct vhost_vring_addr *addr)
620 {
621     addr->desc_user_addr = (uint64_t)(uintptr_t)svq->vring.desc;
622     addr->avail_user_addr = (uint64_t)(uintptr_t)svq->vring.avail;
623     addr->used_user_addr = (uint64_t)(uintptr_t)svq->vring.used;
624 }
625 
626 size_t vhost_svq_driver_area_size(const VhostShadowVirtqueue *svq)
627 {
628     size_t desc_size = sizeof(vring_desc_t) * svq->vring.num;
629     size_t avail_size = offsetof(vring_avail_t, ring[svq->vring.num]) +
630                                                               sizeof(uint16_t);
631 
632     return ROUND_UP(desc_size + avail_size, qemu_real_host_page_size());
633 }
634 
635 size_t vhost_svq_device_area_size(const VhostShadowVirtqueue *svq)
636 {
637     size_t used_size = offsetof(vring_used_t, ring[svq->vring.num]) +
638                                                               sizeof(uint16_t);
639     return ROUND_UP(used_size, qemu_real_host_page_size());
640 }
641 
642 /**
643  * Set a new file descriptor for the guest to kick the SVQ and notify for avail
644  *
645  * @svq: The svq
646  * @svq_kick_fd: The svq kick fd
647  *
648  * Note that the SVQ will never close the old file descriptor.
649  */
650 void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd)
651 {
652     EventNotifier *svq_kick = &svq->svq_kick;
653     bool poll_stop = VHOST_FILE_UNBIND != event_notifier_get_fd(svq_kick);
654     bool poll_start = svq_kick_fd != VHOST_FILE_UNBIND;
655 
656     if (poll_stop) {
657         event_notifier_set_handler(svq_kick, NULL);
658     }
659 
660     event_notifier_init_fd(svq_kick, svq_kick_fd);
661     /*
662      * event_notifier_set_handler already checks for guest's notifications if
663      * they arrive at the new file descriptor in the switch, so there is no
664      * need to explicitly check for them.
665      */
666     if (poll_start) {
667         event_notifier_set(svq_kick);
668         event_notifier_set_handler(svq_kick, vhost_handle_guest_kick_notifier);
669     }
670 }
671 
672 /**
673  * Start the shadow virtqueue operation.
674  *
675  * @svq: Shadow Virtqueue
676  * @vdev: VirtIO device
677  * @vq: Virtqueue to shadow
678  * @iova_tree: Tree to perform descriptors translations
679  */
680 void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev,
681                      VirtQueue *vq, VhostIOVATree *iova_tree)
682 {
683     size_t desc_size;
684 
685     event_notifier_set_handler(&svq->hdev_call, vhost_svq_handle_call);
686     svq->next_guest_avail_elem = NULL;
687     svq->shadow_avail_idx = 0;
688     svq->shadow_used_idx = 0;
689     svq->last_used_idx = 0;
690     svq->vdev = vdev;
691     svq->vq = vq;
692     svq->iova_tree = iova_tree;
693 
694     svq->vring.num = virtio_queue_get_num(vdev, virtio_get_queue_index(vq));
695     svq->num_free = svq->vring.num;
696     svq->vring.desc = mmap(NULL, vhost_svq_driver_area_size(svq),
697                            PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,
698                            -1, 0);
699     desc_size = sizeof(vring_desc_t) * svq->vring.num;
700     svq->vring.avail = (void *)((char *)svq->vring.desc + desc_size);
701     svq->vring.used = mmap(NULL, vhost_svq_device_area_size(svq),
702                            PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,
703                            -1, 0);
704     svq->desc_state = g_new0(SVQDescState, svq->vring.num);
705     svq->desc_next = g_new0(uint16_t, svq->vring.num);
706     for (unsigned i = 0; i < svq->vring.num - 1; i++) {
707         svq->desc_next[i] = cpu_to_le16(i + 1);
708     }
709 }
710 
711 /**
712  * Stop the shadow virtqueue operation.
713  * @svq: Shadow Virtqueue
714  */
715 void vhost_svq_stop(VhostShadowVirtqueue *svq)
716 {
717     vhost_svq_set_svq_kick_fd(svq, VHOST_FILE_UNBIND);
718     g_autofree VirtQueueElement *next_avail_elem = NULL;
719 
720     if (!svq->vq) {
721         return;
722     }
723 
724     /* Send all pending used descriptors to guest */
725     vhost_svq_flush(svq, false);
726 
727     for (unsigned i = 0; i < svq->vring.num; ++i) {
728         g_autofree VirtQueueElement *elem = NULL;
729         elem = g_steal_pointer(&svq->desc_state[i].elem);
730         if (elem) {
731             /*
732              * TODO: This is ok for networking, but other kinds of devices
733              * might have problems with just unpop these.
734              */
735             virtqueue_unpop(svq->vq, elem, 0);
736         }
737     }
738 
739     next_avail_elem = g_steal_pointer(&svq->next_guest_avail_elem);
740     if (next_avail_elem) {
741         virtqueue_unpop(svq->vq, next_avail_elem, 0);
742     }
743     svq->vq = NULL;
744     g_free(svq->desc_next);
745     g_free(svq->desc_state);
746     munmap(svq->vring.desc, vhost_svq_driver_area_size(svq));
747     munmap(svq->vring.used, vhost_svq_device_area_size(svq));
748     event_notifier_set_handler(&svq->hdev_call, NULL);
749 }
750 
751 /**
752  * Creates vhost shadow virtqueue, and instructs the vhost device to use the
753  * shadow methods and file descriptors.
754  *
755  * @ops: SVQ owner callbacks
756  * @ops_opaque: ops opaque pointer
757  */
758 VhostShadowVirtqueue *vhost_svq_new(const VhostShadowVirtqueueOps *ops,
759                                     void *ops_opaque)
760 {
761     VhostShadowVirtqueue *svq = g_new0(VhostShadowVirtqueue, 1);
762 
763     event_notifier_init_fd(&svq->svq_kick, VHOST_FILE_UNBIND);
764     svq->ops = ops;
765     svq->ops_opaque = ops_opaque;
766     return svq;
767 }
768 
769 /**
770  * Free the resources of the shadow virtqueue.
771  *
772  * @pvq: gpointer to SVQ so it can be used by autofree functions.
773  */
774 void vhost_svq_free(gpointer pvq)
775 {
776     VhostShadowVirtqueue *vq = pvq;
777     vhost_svq_stop(vq);
778     g_free(vq);
779 }
780