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 /* 57 * Backup next field for each descriptor so we can recover securely, not 58 * needing to trust the device access. 59 */ 60 uint16_t *desc_next; 61 62 /* Next head to expose to the device */ 63 uint16_t shadow_avail_idx; 64 65 /* Next free descriptor */ 66 uint16_t free_head; 67 68 /* Last seen used idx */ 69 uint16_t shadow_used_idx; 70 71 /* Next head to consume from the device */ 72 uint16_t last_used_idx; 73 } VhostShadowVirtqueue; 74 75 bool vhost_svq_valid_features(uint64_t features, Error **errp); 76 77 void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd); 78 void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd); 79 void vhost_svq_get_vring_addr(const VhostShadowVirtqueue *svq, 80 struct vhost_vring_addr *addr); 81 size_t vhost_svq_driver_area_size(const VhostShadowVirtqueue *svq); 82 size_t vhost_svq_device_area_size(const VhostShadowVirtqueue *svq); 83 84 void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev, 85 VirtQueue *vq); 86 void vhost_svq_stop(VhostShadowVirtqueue *svq); 87 88 VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree); 89 90 void vhost_svq_free(gpointer vq); 91 G_DEFINE_AUTOPTR_CLEANUP_FUNC(VhostShadowVirtqueue, vhost_svq_free); 92 93 #endif 94