This series enable shadow virtqueue (SVQ) for vhost-vdpa devices. This is intended as a new method of tracking the memory the devices touch during a migration process: Instead of relay on vhost device's dirty logging capability, SVQ intercepts the VQ dataplane forwarding the descriptors between VM and device. This way qemu is the effective writer of guests memory, like in qemu's virtio device operation.
When SVQ is enabled qemu offers a new vring to the device to read and write into, and also intercepts kicks and calls between the device and the guest. Used buffers relay would cause dirty memory being tracked, but at this RFC SVQ is not enabled on migration automatically. It is based on the ideas of DPDK SW assisted LM, in the series of DPDK's https://patchwork.dpdk.org/cover/48370/ . However, these does not map the shadow vq in guest's VA, but in qemu's. For qemu to use shadow virtqueues the guest virtio driver must not use features like event_idx or indirect descriptors. These limitations will be addressed in later series, but they are left out for simplicity at the moment. SVQ needs to be enabled with QMP command: { "execute": "x-vhost-enable-shadow-vq", "arguments": { "name": "dev0", "enable": true } } This series includes some patches to delete in the final version that helps with its testing. The first two of the series freely implements the feature to stop the device and be able to retrieve its status. It's intended to be used with vp_vpda driver in a nested environment. This driver also need modifications to forward the new status bit. Patches 2-8 prepares the SVQ and QMP command to support guest to host notifications forwarding. If the SVQ is enabled with these ones applied and the device supports it, that part can be tested in isolation (for example, with networking), hopping through SVQ. Same thing is true with patches 9-13, but with device to guest notifications. The rest of the patches implements the actual buffer forwarding. Comments are welcome. TODO: * Event, indirect, packed, and others features of virtio - Waiting for confirmation of the big picture. * Use already available iova tree to track mappings. * To sepparate buffers forwarding in its own AIO context, so we can throw more threads to that task and we don't need to stop the main event loop. * unmap iommu memory. Now the tree can only grow from SVQ enable, but it should be fine as long as not a lot of memory is added to the guest. * Rebase on top of latest qemu (and, hopefully, on top of multiqueue vdpa). * Some assertions need to be appropiate error handling paths. * Proper documentation. Changes from v3 RFC: * Move everything to vhost-vdpa backend. A big change, this allowed some cleanup but more code has been added in other places. * More use of glib utilities, especially to manage memory. v3 link: https://lists.nongnu.org/archive/html/qemu-devel/2021-05/msg06032.html Changes from v2 RFC: * Adding vhost-vdpa devices support * Fixed some memory leaks pointed by different comments v2 link: https://lists.nongnu.org/archive/html/qemu-devel/2021-03/msg05600.html Changes from v1 RFC: * Use QMP instead of migration to start SVQ mode. * Only accepting IOMMU devices, closer behavior with target devices (vDPA) * Fix invalid masking/unmasking of vhost call fd. * Use of proper methods for synchronization. * No need to modify VirtIO device code, all of the changes are contained in vhost code. * Delete superfluous code. * An intermediate RFC was sent with only the notifications forwarding changes. It can be seen in https://patchew.org/QEMU/20210129205415.876290-1-epere...@redhat.com/ v1 link: https://lists.gnu.org/archive/html/qemu-devel/2020-11/msg05372.html Eugenio Pérez (20): virtio: Add VIRTIO_F_QUEUE_STATE virtio-net: Honor VIRTIO_CONFIG_S_DEVICE_STOPPED virtio: Add virtio_queue_is_host_notifier_enabled vhost: Make vhost_virtqueue_{start,stop} public vhost: Add x-vhost-enable-shadow-vq qmp vhost: Add VhostShadowVirtqueue vdpa: Register vdpa devices in a list vhost: Route guest->host notification through shadow virtqueue Add vhost_svq_get_svq_call_notifier Add vhost_svq_set_guest_call_notifier vdpa: Save call_fd in vhost-vdpa vhost-vdpa: Take into account SVQ in vhost_vdpa_set_vring_call vhost: Route host->guest notification through shadow virtqueue virtio: Add vhost_shadow_vq_get_vring_addr vdpa: Save host and guest features vhost: Add vhost_svq_valid_device_features to shadow vq vhost: Shadow virtqueue buffers forwarding vhost: Add VhostIOVATree vhost: Use a tree to store memory mappings vdpa: Add custom IOTLB translations to SVQ Eugenio Pérez (20): virtio: Add VIRTIO_F_QUEUE_STATE virtio-net: Honor VIRTIO_CONFIG_S_DEVICE_STOPPED virtio: Add virtio_queue_is_host_notifier_enabled vhost: Make vhost_virtqueue_{start,stop} public vhost: Add x-vhost-enable-shadow-vq qmp vhost: Add VhostShadowVirtqueue vdpa: Register vdpa devices in a list vhost: Route guest->host notification through shadow virtqueue vdpa: Save call_fd in vhost-vdpa vhost-vdpa: Take into account SVQ in vhost_vdpa_set_vring_call vhost: Route host->guest notification through shadow virtqueue virtio: Add vhost_shadow_vq_get_vring_addr vdpa: Save host and guest features vhost: Add vhost_svq_valid_device_features to shadow vq vhost: Shadow virtqueue buffers forwarding vhost: Check for device VRING_USED_F_NO_NOTIFY at shadow virtqueue kick vhost: Use VRING_AVAIL_F_NO_INTERRUPT at device call on shadow virtqueue vhost: Add VhostIOVATree vhost: Use a tree to store memory mappings vdpa: Add custom IOTLB translations to SVQ qapi/net.json | 23 + hw/virtio/vhost-iova-tree.h | 40 ++ hw/virtio/vhost-shadow-virtqueue.h | 37 ++ hw/virtio/virtio-pci.h | 1 + include/hw/virtio/vhost-vdpa.h | 13 + include/hw/virtio/vhost.h | 4 + include/hw/virtio/virtio.h | 5 +- .../standard-headers/linux/virtio_config.h | 5 + include/standard-headers/linux/virtio_pci.h | 2 + hw/net/virtio-net.c | 6 +- hw/virtio/vhost-iova-tree.c | 230 +++++++ hw/virtio/vhost-shadow-virtqueue.c | 619 ++++++++++++++++++ hw/virtio/vhost-vdpa.c | 412 +++++++++++- hw/virtio/vhost.c | 12 +- hw/virtio/virtio-pci.c | 16 +- hw/virtio/virtio.c | 5 + hw/virtio/meson.build | 2 +- hw/virtio/trace-events | 1 + 18 files changed, 1413 insertions(+), 20 deletions(-) create mode 100644 hw/virtio/vhost-iova-tree.h create mode 100644 hw/virtio/vhost-shadow-virtqueue.h create mode 100644 hw/virtio/vhost-iova-tree.c create mode 100644 hw/virtio/vhost-shadow-virtqueue.c -- 2.27.0