Patchwork [21/41] virtio: port to vmstate

login
register
mail settings
Submitter Juan Quintela
Date Dec. 2, 2009, 12:04 p.m.
Message ID <e450dccaf2d8f5e32e7eaaa59bfe7d5e4f7a4c02.1259754427.git.quintela@redhat.com>
Download mbox | patch
Permalink /patch/40024/
State New
Headers show

Comments

Juan Quintela - Dec. 2, 2009, 12:04 p.m.
We need to do the virt queue msix and not msix version because we know
if there is msix at virtio level, not at queue element level

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 hw/hw.h     |   10 +++++
 hw/virtio.c |  121 ++++++++++++++++++++++++++++++++---------------------------
 hw/virtio.h |    5 ++
 3 files changed, 81 insertions(+), 55 deletions(-)
Michael S. Tsirkin - Dec. 2, 2009, 6:22 p.m.
On Wed, Dec 02, 2009 at 01:04:19PM +0100, Juan Quintela wrote:
> We need to do the virt queue msix and not msix version because we know
> if there is msix at virtio level, not at queue element level
> 
> Signed-off-by: Juan Quintela <quintela@redhat.com>
> ---
>  hw/hw.h     |   10 +++++
>  hw/virtio.c |  121 ++++++++++++++++++++++++++++++++---------------------------
>  hw/virtio.h |    5 ++
>  3 files changed, 81 insertions(+), 55 deletions(-)
> 
> diff --git a/hw/hw.h b/hw/hw.h
> index 5f34991..747a311 100644
> --- a/hw/hw.h
> +++ b/hw/hw.h
> @@ -476,6 +476,16 @@ extern const VMStateInfo vmstate_info_unused_buffer;
>      .offset     = vmstate_offset_array(_state, _field, _type, _num), \
>  }
> 
> +#define VMSTATE_VARRAY_STRUCT_INT32(_field, _state, _field_num, _test, _vmsd, _type) {\

line too long

> +    .name         = (stringify(_field)),                             \
> +    .field_exists = (_test),                                         \
> +    .num_offset   = vmstate_offset_value(_state, _field_num, int32_t), \
> +    .vmsd         = &(_vmsd),                                        \
> +    .size         = sizeof(_type),                                   \
> +    .flags        = VMS_VARRAY_INT32|VMS_POINTER|VMS_STRUCT,         \
> +    .offset       = vmstate_offset_pointer(_state, _field, _type),   \
> +}
> +
>  #define VMSTATE_STATIC_BUFFER(_field, _state, _version, _test, _start, _size) { \

line too long

>      .name         = (stringify(_field)),                             \
>      .version_id   = (_version),                                      \
> diff --git a/hw/virtio.c b/hw/virtio.c
> index 5497716..73dae7c 100644
> --- a/hw/virtio.c
> +++ b/hw/virtio.c
> @@ -625,10 +625,19 @@ static bool is_virtio_pci(void *opaque, int version_id)
>  static bool is_virtio_msix(void *opaque, int version_id)
>  {
>      VirtIODevice *vdev = opaque;
> +
>      return (vdev->type == VIRTIO_PCI) &&
>          virtio_pci_msix_present(vdev->binding_opaque);
>  }
> 
> +static bool is_virtio_not_msix(void *opaque, int version_id)
> +{
> +    VirtIODevice *vdev = opaque;
> +
> +    return !((vdev->type == VIRTIO_PCI) &&
> +             virtio_pci_msix_present(vdev->binding_opaque));
> +}
> +

previous comment about using pci in virtio.c applies here
as well.

>  static void virtio_pre_save(void *opaque)
>  {
>      VirtIODevice *vdev = opaque;
> @@ -641,34 +650,6 @@ static void virtio_pre_save(void *opaque)
>      vdev->num_pci_queues = i;
>  }
> 
> -void virtio_save(VirtIODevice *vdev, QEMUFile *f)
> -{
> -    int i;
> -
> -    virtio_pre_save(vdev);
> -
> -    if (is_virtio_pci(vdev, 1))
> -        vmstate_save_state(f, &vmstate_virtio_pci_config, vdev->binding_opaque);
> -
> -    qemu_put_8s(f, &vdev->status);
> -    qemu_put_8s(f, &vdev->isr);
> -    qemu_put_be16s(f, &vdev->queue_sel);
> -    qemu_put_be32s(f, &vdev->features);
> -    qemu_put_sbe32s(f, &vdev->config_len);
> -    qemu_put_buffer(f, vdev->config, vdev->config_len);
> -
> -    qemu_put_sbe32s(f, &vdev->num_pci_queues);
> -
> -    for (i = 0; i < vdev->num_pci_queues; i++) {
> -        qemu_put_be32s(f, &vdev->vq[i].vring.num);
> -        qemu_put_be64s(f, &vdev->vq[i].pa);
> -        qemu_put_be16s(f, &vdev->vq[i].last_avail_idx);
> -        if (is_virtio_msix(vdev, 1)) {
> -            qemu_put_be16s(f, &vdev->vq[i].vector);
> -        }
> -    }
> -}
> -
>  static int virtio_post_load(void *opaque, int version_id)
>  {
>      VirtIODevice *vdev = opaque;
> @@ -695,38 +676,68 @@ static int virtio_post_load(void *opaque, int version_id)
>      return 0;
>  }
> 
> -
> -int virtio_load(VirtIODevice *vdev, QEMUFile *f)
> -{
> -    int i, ret;
> -
> -    if (is_virtio_pci(vdev, 1)) {
> -        ret = vmstate_load_state(f, &vmstate_virtio_pci_config, vdev->binding_opaque,
> -                                 vmstate_virtio_pci_config.version_id);
> -        if (ret)
> -            return ret;
> +static const VMStateDescription vmstate_virtio_pci_queue = {
> +    .name = "virtio_pci_queue",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .minimum_version_id_old = 1,
> +    .fields      = (VMStateField []) {
> +        VMSTATE_UINT32(vring.num, VirtQueue),
> +        VMSTATE_UINT64(pa, VirtQueue),
> +        VMSTATE_UINT16(last_avail_idx, VirtQueue),
> +        VMSTATE_END_OF_LIST()
>      }
> +};
> 
> -    qemu_get_8s(f, &vdev->status);
> -    qemu_get_8s(f, &vdev->isr);
> -    qemu_get_be16s(f, &vdev->queue_sel);
> -    qemu_get_be32s(f, &vdev->features);
> -    qemu_get_sbe32s(f, &vdev->config_len);
> -    qemu_get_buffer(f, vdev->config, vdev->config_len);
> +static const VMStateDescription vmstate_virtio_pci_queue_msix = {
> +    .name = "virtio_pci_queue_msix",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .minimum_version_id_old = 1,
> +    .fields      = (VMStateField []) {
> +        VMSTATE_UINT32(vring.num, VirtQueue),
> +        VMSTATE_UINT64(pa, VirtQueue),
> +        VMSTATE_UINT16(last_avail_idx, VirtQueue),
> +        VMSTATE_UINT16(vector, VirtQueue),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> 
> -    qemu_get_sbe32s(f, &vdev->num_pci_queues);
> +const VMStateDescription vmstate_virtio = {
> +     .name = "virtio",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .minimum_version_id_old = 1,
> +    .post_load = virtio_post_load,
> +    .pre_save = virtio_pre_save,
> +    .fields      = (VMStateField []) {
> +        VMSTATE_STRUCT_POINTER_TEST(binding_opaque, VirtIODevice, is_virtio_pci,
> +                                    vmstate_virtio_pci_config, void *),
> +        VMSTATE_UINT8(status, VirtIODevice),
> +        VMSTATE_UINT8(isr, VirtIODevice),
> +        VMSTATE_UINT16(queue_sel, VirtIODevice),
> +        VMSTATE_UINT32(features, VirtIODevice),
> +        VMSTATE_INT32(config_len, VirtIODevice),
> +        VMSTATE_PARTIAL_VBUFFER(config, VirtIODevice, config_len),
> +        VMSTATE_INT32(num_pci_queues, VirtIODevice),
> +        VMSTATE_VARRAY_STRUCT_INT32(vq, VirtIODevice, num_pci_queues,
> +                                    is_virtio_msix,
> +                                    vmstate_virtio_pci_queue_msix, VirtQueue),
> +        VMSTATE_VARRAY_STRUCT_INT32(vq, VirtIODevice, num_pci_queues,
> +                                    is_virtio_not_msix,
> +                                    vmstate_virtio_pci_queue, VirtQueue),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> 
> -    for (i = 0; i < vdev->num_pci_queues; i++) {
> -        qemu_get_be32s(f, &vdev->vq[i].vring.num);
> -        qemu_get_be64s(f, &vdev->vq[i].pa);
> -        qemu_get_be16s(f, &vdev->vq[i].last_avail_idx);
> +void virtio_save(VirtIODevice *vdev, QEMUFile *f)
> +{
> +    vmstate_save_state(f, &vmstate_virtio, vdev);
> +}
> 
> -        if (is_virtio_msix(vdev, 1)) {
> -            qemu_get_be16s(f, &vdev->vq[i].vector);
> -        }
> -    }
> -    virtio_post_load(vdev, 1);
> -    return 0;
> +int virtio_load(VirtIODevice *vdev, QEMUFile *f)
> +{
> +    return vmstate_load_state(f, &vmstate_virtio, vdev, vmstate_virtio.version_id);
>  }
> 
>  void virtio_cleanup(VirtIODevice *vdev)
> diff --git a/hw/virtio.h b/hw/virtio.h
> index f56f672..ac7b8eb 100644
> --- a/hw/virtio.h
> +++ b/hw/virtio.h
> @@ -130,6 +130,11 @@ int virtqueue_avail_bytes(VirtQueue *vq, int in_bytes, int out_bytes);
> 
>  void virtio_notify(VirtIODevice *vdev, VirtQueue *vq);
> 
> +extern const VMStateDescription vmstate_virtio;
> +
> +#define VMSTATE_VIRTIO(_field, _state)                                         \
> +    VMSTATE_STRUCT_TEST(_field, _state, NULL, 0, vmstate_virtio, VirtIODevice)
> +
>  void virtio_save(VirtIODevice *vdev, QEMUFile *f);
> 
>  int virtio_load(VirtIODevice *vdev, QEMUFile *f);
> -- 
> 1.6.5.2

Patch

diff --git a/hw/hw.h b/hw/hw.h
index 5f34991..747a311 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -476,6 +476,16 @@  extern const VMStateInfo vmstate_info_unused_buffer;
     .offset     = vmstate_offset_array(_state, _field, _type, _num), \
 }

+#define VMSTATE_VARRAY_STRUCT_INT32(_field, _state, _field_num, _test, _vmsd, _type) {\
+    .name         = (stringify(_field)),                             \
+    .field_exists = (_test),                                         \
+    .num_offset   = vmstate_offset_value(_state, _field_num, int32_t), \
+    .vmsd         = &(_vmsd),                                        \
+    .size         = sizeof(_type),                                   \
+    .flags        = VMS_VARRAY_INT32|VMS_POINTER|VMS_STRUCT,         \
+    .offset       = vmstate_offset_pointer(_state, _field, _type),   \
+}
+
 #define VMSTATE_STATIC_BUFFER(_field, _state, _version, _test, _start, _size) { \
     .name         = (stringify(_field)),                             \
     .version_id   = (_version),                                      \
diff --git a/hw/virtio.c b/hw/virtio.c
index 5497716..73dae7c 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -625,10 +625,19 @@  static bool is_virtio_pci(void *opaque, int version_id)
 static bool is_virtio_msix(void *opaque, int version_id)
 {
     VirtIODevice *vdev = opaque;
+
     return (vdev->type == VIRTIO_PCI) &&
         virtio_pci_msix_present(vdev->binding_opaque);
 }

+static bool is_virtio_not_msix(void *opaque, int version_id)
+{
+    VirtIODevice *vdev = opaque;
+
+    return !((vdev->type == VIRTIO_PCI) &&
+             virtio_pci_msix_present(vdev->binding_opaque));
+}
+
 static void virtio_pre_save(void *opaque)
 {
     VirtIODevice *vdev = opaque;
@@ -641,34 +650,6 @@  static void virtio_pre_save(void *opaque)
     vdev->num_pci_queues = i;
 }

-void virtio_save(VirtIODevice *vdev, QEMUFile *f)
-{
-    int i;
-
-    virtio_pre_save(vdev);
-
-    if (is_virtio_pci(vdev, 1))
-        vmstate_save_state(f, &vmstate_virtio_pci_config, vdev->binding_opaque);
-
-    qemu_put_8s(f, &vdev->status);
-    qemu_put_8s(f, &vdev->isr);
-    qemu_put_be16s(f, &vdev->queue_sel);
-    qemu_put_be32s(f, &vdev->features);
-    qemu_put_sbe32s(f, &vdev->config_len);
-    qemu_put_buffer(f, vdev->config, vdev->config_len);
-
-    qemu_put_sbe32s(f, &vdev->num_pci_queues);
-
-    for (i = 0; i < vdev->num_pci_queues; i++) {
-        qemu_put_be32s(f, &vdev->vq[i].vring.num);
-        qemu_put_be64s(f, &vdev->vq[i].pa);
-        qemu_put_be16s(f, &vdev->vq[i].last_avail_idx);
-        if (is_virtio_msix(vdev, 1)) {
-            qemu_put_be16s(f, &vdev->vq[i].vector);
-        }
-    }
-}
-
 static int virtio_post_load(void *opaque, int version_id)
 {
     VirtIODevice *vdev = opaque;
@@ -695,38 +676,68 @@  static int virtio_post_load(void *opaque, int version_id)
     return 0;
 }

-
-int virtio_load(VirtIODevice *vdev, QEMUFile *f)
-{
-    int i, ret;
-
-    if (is_virtio_pci(vdev, 1)) {
-        ret = vmstate_load_state(f, &vmstate_virtio_pci_config, vdev->binding_opaque,
-                                 vmstate_virtio_pci_config.version_id);
-        if (ret)
-            return ret;
+static const VMStateDescription vmstate_virtio_pci_queue = {
+    .name = "virtio_pci_queue",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField []) {
+        VMSTATE_UINT32(vring.num, VirtQueue),
+        VMSTATE_UINT64(pa, VirtQueue),
+        VMSTATE_UINT16(last_avail_idx, VirtQueue),
+        VMSTATE_END_OF_LIST()
     }
+};

-    qemu_get_8s(f, &vdev->status);
-    qemu_get_8s(f, &vdev->isr);
-    qemu_get_be16s(f, &vdev->queue_sel);
-    qemu_get_be32s(f, &vdev->features);
-    qemu_get_sbe32s(f, &vdev->config_len);
-    qemu_get_buffer(f, vdev->config, vdev->config_len);
+static const VMStateDescription vmstate_virtio_pci_queue_msix = {
+    .name = "virtio_pci_queue_msix",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField []) {
+        VMSTATE_UINT32(vring.num, VirtQueue),
+        VMSTATE_UINT64(pa, VirtQueue),
+        VMSTATE_UINT16(last_avail_idx, VirtQueue),
+        VMSTATE_UINT16(vector, VirtQueue),
+        VMSTATE_END_OF_LIST()
+    }
+};

-    qemu_get_sbe32s(f, &vdev->num_pci_queues);
+const VMStateDescription vmstate_virtio = {
+     .name = "virtio",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .post_load = virtio_post_load,
+    .pre_save = virtio_pre_save,
+    .fields      = (VMStateField []) {
+        VMSTATE_STRUCT_POINTER_TEST(binding_opaque, VirtIODevice, is_virtio_pci,
+                                    vmstate_virtio_pci_config, void *),
+        VMSTATE_UINT8(status, VirtIODevice),
+        VMSTATE_UINT8(isr, VirtIODevice),
+        VMSTATE_UINT16(queue_sel, VirtIODevice),
+        VMSTATE_UINT32(features, VirtIODevice),
+        VMSTATE_INT32(config_len, VirtIODevice),
+        VMSTATE_PARTIAL_VBUFFER(config, VirtIODevice, config_len),
+        VMSTATE_INT32(num_pci_queues, VirtIODevice),
+        VMSTATE_VARRAY_STRUCT_INT32(vq, VirtIODevice, num_pci_queues,
+                                    is_virtio_msix,
+                                    vmstate_virtio_pci_queue_msix, VirtQueue),
+        VMSTATE_VARRAY_STRUCT_INT32(vq, VirtIODevice, num_pci_queues,
+                                    is_virtio_not_msix,
+                                    vmstate_virtio_pci_queue, VirtQueue),
+        VMSTATE_END_OF_LIST()
+    }
+};

-    for (i = 0; i < vdev->num_pci_queues; i++) {
-        qemu_get_be32s(f, &vdev->vq[i].vring.num);
-        qemu_get_be64s(f, &vdev->vq[i].pa);
-        qemu_get_be16s(f, &vdev->vq[i].last_avail_idx);
+void virtio_save(VirtIODevice *vdev, QEMUFile *f)
+{
+    vmstate_save_state(f, &vmstate_virtio, vdev);
+}

-        if (is_virtio_msix(vdev, 1)) {
-            qemu_get_be16s(f, &vdev->vq[i].vector);
-        }
-    }
-    virtio_post_load(vdev, 1);
-    return 0;
+int virtio_load(VirtIODevice *vdev, QEMUFile *f)
+{
+    return vmstate_load_state(f, &vmstate_virtio, vdev, vmstate_virtio.version_id);
 }

 void virtio_cleanup(VirtIODevice *vdev)
diff --git a/hw/virtio.h b/hw/virtio.h
index f56f672..ac7b8eb 100644
--- a/hw/virtio.h
+++ b/hw/virtio.h
@@ -130,6 +130,11 @@  int virtqueue_avail_bytes(VirtQueue *vq, int in_bytes, int out_bytes);

 void virtio_notify(VirtIODevice *vdev, VirtQueue *vq);

+extern const VMStateDescription vmstate_virtio;
+
+#define VMSTATE_VIRTIO(_field, _state)                                         \
+    VMSTATE_STRUCT_TEST(_field, _state, NULL, 0, vmstate_virtio, VirtIODevice)
+
 void virtio_save(VirtIODevice *vdev, QEMUFile *f);

 int virtio_load(VirtIODevice *vdev, QEMUFile *f);