We will convert between VirtQueueElement and VirtQueueElementOld to migrate the inflight descriptors, so we need virtio-net to see these.
This will not be exported in the final version, but working with VirtQueueElementOld is way more easier than with VirtQueueElement and VMState macros. Signed-off-by: Eugenio Pérez <epere...@redhat.com> --- include/hw/virtio/virtio.h | 31 +++++++++++++++++++++++++++++++ hw/virtio/virtio.c | 27 +++++---------------------- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index acfd4df125..b4c5163fb0 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -75,6 +75,37 @@ typedef struct VirtQueueElement struct iovec *out_sg; } VirtQueueElement; +/* + * Reading and writing a structure directly to QEMUFile is *awful*, but + * it is what QEMU has always done by mistake. We can change it sooner + * or later by bumping the version number of the affected vm states. + * In the meanwhile, since the in-memory layout of VirtQueueElement + * has changed, we need to marshal to and from the layout that was + * used before the change. + */ +typedef struct VirtQueueElementOld { + uint32_t index; + uint32_t out_num; + uint32_t in_num; + hwaddr in_addr[VIRTQUEUE_MAX_SIZE]; + hwaddr out_addr[VIRTQUEUE_MAX_SIZE]; + /* Unions help to serialize the descriptor using VMStateDescription */ + union { + struct iovec in_sg[VIRTQUEUE_MAX_SIZE]; + uint64_t in_sg_64[VIRTQUEUE_MAX_SIZE * 2]; + }; + union { + struct iovec out_sg[VIRTQUEUE_MAX_SIZE]; + uint64_t out_sg_64[VIRTQUEUE_MAX_SIZE * 2]; + }; +} VirtQueueElementOld; + +void *qemu_get_virtqueue_element_from_old(VirtIODevice *vdev, + const VirtQueueElementOld *data, + size_t sz); +void qemu_put_virtqueue_element_old(const VirtQueueElement *elem, + VirtQueueElementOld *data); + #define VIRTIO_QUEUE_MAX 1024 #define VIRTIO_NO_VECTOR 0xffff diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index bc3b474065..5ddc49610c 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -2280,27 +2280,10 @@ unsigned int virtqueue_drop_all(VirtQueue *vq) } } -/* Reading and writing a structure directly to QEMUFile is *awful*, but - * it is what QEMU has always done by mistake. We can change it sooner - * or later by bumping the version number of the affected vm states. - * In the meanwhile, since the in-memory layout of VirtQueueElement - * has changed, we need to marshal to and from the layout that was - * used before the change. - */ -typedef struct VirtQueueElementOld { - uint32_t index; - uint32_t out_num; - uint32_t in_num; - hwaddr in_addr[VIRTQUEUE_MAX_SIZE]; - hwaddr out_addr[VIRTQUEUE_MAX_SIZE]; - struct iovec in_sg[VIRTQUEUE_MAX_SIZE]; - struct iovec out_sg[VIRTQUEUE_MAX_SIZE]; -} VirtQueueElementOld; - /* Convert VirtQueueElementOld to VirtQueueElement */ -static void *qemu_get_virtqueue_element_from_old(VirtIODevice *vdev, - const VirtQueueElementOld *data, - size_t sz) +void *qemu_get_virtqueue_element_from_old(VirtIODevice *vdev, + const VirtQueueElementOld *data, + size_t sz) { VirtQueueElement *elem = virtqueue_alloc_element(sz, data->out_num, data->in_num); @@ -2361,8 +2344,8 @@ void *qemu_get_virtqueue_element(VirtIODevice *vdev, QEMUFile *f, size_t sz) } /* Convert VirtQueueElement to VirtQueueElementOld */ -static void qemu_put_virtqueue_element_old(const VirtQueueElement *elem, - VirtQueueElementOld *data) +void qemu_put_virtqueue_element_old(const VirtQueueElement *elem, + VirtQueueElementOld *data) { memset(data, 0, sizeof(*data)); data->index = elem->index; -- 2.31.1