Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
virtio fix for 2.4
Fixes migration in virtio 1 mode.
We still have a known bug with memory hotplug, it doesn't
look like we can fix that in time for 2.4.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
# gpg: Signature made Wed 05 Aug 2015 15:57:39 BST using RSA key ID D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg: aka "Michael S. Tsirkin <mst@redhat.com>"
* remotes/mst/tags/for_upstream:
virtio: fix 1.0 virtqueue migration
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index ee4e07c..788b556 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -1049,6 +1049,61 @@
return (vdev->host_features >> 32) != 0;
}
+static bool virtio_virtqueue_needed(void *opaque)
+{
+ VirtIODevice *vdev = opaque;
+
+ return virtio_host_has_feature(vdev, VIRTIO_F_VERSION_1);
+}
+
+static void put_virtqueue_state(QEMUFile *f, void *pv, size_t size)
+{
+ VirtIODevice *vdev = pv;
+ int i;
+
+ for (i = 0; i < VIRTIO_QUEUE_MAX; i++) {
+ qemu_put_be64(f, vdev->vq[i].vring.avail);
+ qemu_put_be64(f, vdev->vq[i].vring.used);
+ }
+}
+
+static int get_virtqueue_state(QEMUFile *f, void *pv, size_t size)
+{
+ VirtIODevice *vdev = pv;
+ int i;
+
+ for (i = 0; i < VIRTIO_QUEUE_MAX; i++) {
+ vdev->vq[i].vring.avail = qemu_get_be64(f);
+ vdev->vq[i].vring.used = qemu_get_be64(f);
+ }
+ return 0;
+}
+
+static VMStateInfo vmstate_info_virtqueue = {
+ .name = "virtqueue_state",
+ .get = get_virtqueue_state,
+ .put = put_virtqueue_state,
+};
+
+static const VMStateDescription vmstate_virtio_virtqueues = {
+ .name = "virtio/virtqueues",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = &virtio_virtqueue_needed,
+ .fields = (VMStateField[]) {
+ {
+ .name = "virtqueues",
+ .version_id = 0,
+ .field_exists = NULL,
+ .size = 0,
+ .info = &vmstate_info_virtqueue,
+ .flags = VMS_SINGLE,
+ .offset = 0,
+ },
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static const VMStateDescription vmstate_virtio_device_endian = {
.name = "virtio/device_endian",
.version_id = 1,
@@ -1082,6 +1137,7 @@
.subsections = (const VMStateDescription*[]) {
&vmstate_virtio_device_endian,
&vmstate_virtio_64bit_features,
+ &vmstate_virtio_virtqueues,
NULL
}
};
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 59f0763..cccae89 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -272,6 +272,12 @@
return __virtio_has_feature(vdev->guest_features, fbit);
}
+static inline bool virtio_host_has_feature(VirtIODevice *vdev,
+ unsigned int fbit)
+{
+ return __virtio_has_feature(vdev->host_features, fbit);
+}
+
static inline bool virtio_is_big_endian(VirtIODevice *vdev)
{
if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {