mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 00:03:54 -06:00
vhost: Shadow virtqueue buffers forwarding
Initial version of shadow virtqueue that actually forward buffers. There is no iommu support at the moment, and that will be addressed in future patches of this series. Since all vhost-vdpa devices use forced IOMMU, this means that SVQ is not usable at this point of the series on any device. For simplicity it only supports modern devices, that expects vring in little endian, with split ring and no event idx or indirect descriptors. Support for them will not be added in this series. It reuses the VirtQueue code for the device part. The driver part is based on Linux's virtio_ring driver, but with stripped functionality and optimizations so it's easier to review. However, forwarding buffers have some particular pieces: One of the most unexpected ones is that a guest's buffer can expand through more than one descriptor in SVQ. While this is handled gracefully by qemu's emulated virtio devices, it may cause unexpected SVQ queue full. This patch also solves it by checking for this condition at both guest's kicks and device's calls. The code may be more elegant in the future if SVQ code runs in its own iocontext. Signed-off-by: Eugenio Pérez <eperezma@redhat.com> Acked-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Jason Wang <jasowang@redhat.com>
This commit is contained in:
parent
d96be4c894
commit
100890f7ca
3 changed files with 524 additions and 13 deletions
|
@ -36,6 +36,30 @@ typedef struct VhostShadowVirtqueue {
|
|||
|
||||
/* Guest's call notifier, where the SVQ calls guest. */
|
||||
EventNotifier svq_call;
|
||||
|
||||
/* Virtio queue shadowing */
|
||||
VirtQueue *vq;
|
||||
|
||||
/* Virtio device */
|
||||
VirtIODevice *vdev;
|
||||
|
||||
/* Map for use the guest's descriptors */
|
||||
VirtQueueElement **ring_id_maps;
|
||||
|
||||
/* Next VirtQueue element that guest made available */
|
||||
VirtQueueElement *next_guest_avail_elem;
|
||||
|
||||
/* Next head to expose to the device */
|
||||
uint16_t shadow_avail_idx;
|
||||
|
||||
/* Next free descriptor */
|
||||
uint16_t free_head;
|
||||
|
||||
/* Last seen used idx */
|
||||
uint16_t shadow_used_idx;
|
||||
|
||||
/* Next head to consume from the device */
|
||||
uint16_t last_used_idx;
|
||||
} VhostShadowVirtqueue;
|
||||
|
||||
bool vhost_svq_valid_features(uint64_t features, Error **errp);
|
||||
|
@ -47,6 +71,8 @@ void vhost_svq_get_vring_addr(const VhostShadowVirtqueue *svq,
|
|||
size_t vhost_svq_driver_area_size(const VhostShadowVirtqueue *svq);
|
||||
size_t vhost_svq_device_area_size(const VhostShadowVirtqueue *svq);
|
||||
|
||||
void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev,
|
||||
VirtQueue *vq);
|
||||
void vhost_svq_stop(VhostShadowVirtqueue *svq);
|
||||
|
||||
VhostShadowVirtqueue *vhost_svq_new(void);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue