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 #ifndef VHOST_SHADOW_VIRTQUEUE_H 11 #define VHOST_SHADOW_VIRTQUEUE_H 12 13 #include "qemu/event_notifier.h" 14 #include "hw/virtio/virtio.h" 15 #include "standard-headers/linux/vhost_types.h" 16 #include "hw/virtio/vhost-iova-tree.h" 17 18 /* Shadow virtqueue to relay notifications */ 19 typedef struct VhostShadowVirtqueue { 20 /* Shadow vring */ 21 struct vring vring; 22 23 /* Shadow kick notifier, sent to vhost */ 24 EventNotifier hdev_kick; 25 /* Shadow call notifier, sent to vhost */ 26 EventNotifier hdev_call; 27 28 /* 29 * Borrowed virtqueue's guest to host notifier. To borrow it in this event 30 * notifier allows to recover the VhostShadowVirtqueue from the event loop 31 * easily. If we use the VirtQueue's one, we don't have an easy way to 32 * retrieve VhostShadowVirtqueue. 33 * 34 * So shadow virtqueue must not clean it, or we would lose VirtQueue one. 35 */ 36 EventNotifier svq_kick; 37 38 /* Guest's call notifier, where the SVQ calls guest. */ 39 EventNotifier svq_call; 40 41 /* Virtio queue shadowing */ 42 VirtQueue *vq; 43 44 /* Virtio device */ 45 VirtIODevice *vdev; 46 47 /* IOVA mapping */ 48 VhostIOVATree *iova_tree; 49 50 /* Map for use the guest's descriptors */ 51 VirtQueueElement **ring_id_maps; 52 53 /* Next VirtQueue element that guest made available */ 54 VirtQueueElement *next_guest_avail_elem; 55 56 /* Next head to expose to the device */ 57 uint16_t shadow_avail_idx; 58 59 /* Next free descriptor */ 60 uint16_t free_head; 61 62 /* Last seen used idx */ 63 uint16_t shadow_used_idx; 64 65 /* Next head to consume from the device */ 66 uint16_t last_used_idx; 67 } VhostShadowVirtqueue; 68 69 bool vhost_svq_valid_features(uint64_t features, Error **errp); 70 71 void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd); 72 void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd); 73 void vhost_svq_get_vring_addr(const VhostShadowVirtqueue *svq, 74 struct vhost_vring_addr *addr); 75 size_t vhost_svq_driver_area_size(const VhostShadowVirtqueue *svq); 76 size_t vhost_svq_device_area_size(const VhostShadowVirtqueue *svq); 77 78 void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev, 79 VirtQueue *vq); 80 void vhost_svq_stop(VhostShadowVirtqueue *svq); 81 82 VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree); 83 84 void vhost_svq_free(gpointer vq); 85 G_DEFINE_AUTOPTR_CLEANUP_FUNC(VhostShadowVirtqueue, vhost_svq_free); 86 87 #endif 88