qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 08/13] virtio: convert common virtio save/load to vi


From: Michael Roth
Subject: [Qemu-devel] [PATCH 08/13] virtio: convert common virtio save/load to visitors
Date: Thu, 27 Oct 2011 13:17:20 -0500

Signed-off-by: Michael Roth <address@hidden>
---
 hw/virtio.c |  122 ++++++++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 92 insertions(+), 30 deletions(-)

diff --git a/hw/virtio.c b/hw/virtio.c
index 7011b5b..0471c54 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -733,53 +733,93 @@ void virtio_notify_config(VirtIODevice *vdev)
 void virtio_save(VirtIODevice *vdev, QEMUFile *f)
 {
     int i;
+    Visitor *v = qemu_file_get_visitor(f);
+    Error *err = NULL;
+    uint8_t *config;
+    uint64_t tmp;
 
-    if (vdev->binding->save_config)
+    visit_start_struct(v, NULL, NULL, "vdev", 0, &err);
+
+    if (vdev->binding->save_config) {
         vdev->binding->save_config(vdev->binding_opaque, f);
+    }
 
-    qemu_put_8s(f, &vdev->status);
-    qemu_put_8s(f, &vdev->isr);
-    qemu_put_be16s(f, &vdev->queue_sel);
-    qemu_put_be32s(f, &vdev->guest_features);
-    qemu_put_be32(f, vdev->config_len);
-    qemu_put_buffer(f, vdev->config, vdev->config_len);
+    visit_type_uint8(v, &vdev->status, "status", &err);
+    visit_type_uint8(v, &vdev->isr, "isr", &err);
+    visit_type_uint16(v, &vdev->queue_sel, "queue_sel", &err);
+    visit_type_uint32(v, &vdev->guest_features, "guest_features", &err);
+    visit_type_uint32(v, (uint32_t *)&vdev->config_len, "config_len", &err);
+    visit_start_array(v, (void**)&vdev->config, "config", vdev->config_len,
+                      sizeof(*config), &err);
+    config = vdev->config;
+    for (i = 0; i < vdev->config_len; i++) {
+        visit_type_uint8(v, &config[i], NULL, &err);
+    }
+    visit_end_array(v, &err);
 
     for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
-        if (vdev->vq[i].vring.num == 0)
+        if (vdev->vq[i].vring.num == 0) {
             break;
+        }
     }
+    visit_type_uint32(v, (uint32_t *)&i, "vq_count", &err);
 
-    qemu_put_be32(f, i);
-
+    visit_start_list(v, "vq_info", &err); 
     for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
-        if (vdev->vq[i].vring.num == 0)
+        if (vdev->vq[i].vring.num == 0) {
             break;
+        }
 
-        qemu_put_be32(f, vdev->vq[i].vring.num);
-        qemu_put_be64(f, vdev->vq[i].pa);
-        qemu_put_be16s(f, &vdev->vq[i].last_avail_idx);
-        if (vdev->binding->save_queue)
+        visit_start_struct(v, NULL, NULL, NULL, 0, &err);
+
+        visit_type_uint32(v, &vdev->vq[i].vring.num, "vring.num", &err);
+        /* pa can be 32 or 64-bit depending on target, and legacy QEMUFile
+         * protocol expects a 64-bit, so stick with this for now
+         */
+        tmp = vdev->vq[i].pa;
+        visit_type_uint64(v, &tmp, "pa", &err);
+        visit_type_uint16(v, &vdev->vq[i].last_avail_idx, "last_avail_idx",
+                          &err);
+        if (vdev->binding->save_queue) {
             vdev->binding->save_queue(vdev->binding_opaque, i, f);
+        }
+        
+        visit_end_struct(v, &err);
+    }
+    visit_end_list(v, &err);
+
+    visit_end_struct(v, &err);
+
+    if (err) {
+        error_report("error saving virtio state: %s", error_get_pretty(err));
+        error_free(err);
     }
 }
 
 int virtio_load(VirtIODevice *vdev, QEMUFile *f)
 {
-    int num, i, ret;
+    uint32_t num, i, ret;
     uint32_t features;
     uint32_t supported_features =
         vdev->binding->get_features(vdev->binding_opaque);
+    Visitor *v = qemu_file_get_visitor(f);
+    Error *err = NULL;
+    uint8_t *config;
+    uint64_t tmp;
+
+    visit_start_struct(v, NULL, NULL, "vdev", 0, &err);
 
     if (vdev->binding->load_config) {
         ret = vdev->binding->load_config(vdev->binding_opaque, f);
-        if (ret)
+        if (ret) {
             return ret;
+        }
     }
 
-    qemu_get_8s(f, &vdev->status);
-    qemu_get_8s(f, &vdev->isr);
-    qemu_get_be16s(f, &vdev->queue_sel);
-    qemu_get_be32s(f, &features);
+    visit_type_uint8(v, &vdev->status, "status", &err);
+    visit_type_uint8(v, &vdev->isr, "isr", &err);
+    visit_type_uint16(v, &vdev->queue_sel, "queue_sel", &err);
+    visit_type_uint32(v, &features, "guest_features", &err);
     if (features & ~supported_features) {
         error_report("Features 0x%x unsupported. Allowed features: 0x%x",
                      features, supported_features);
@@ -788,15 +828,26 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
     if (vdev->set_features)
         vdev->set_features(vdev, features);
     vdev->guest_features = features;
-    vdev->config_len = qemu_get_be32(f);
-    qemu_get_buffer(f, vdev->config, vdev->config_len);
+    visit_type_uint32(v, (uint32_t *)&vdev->config_len, "config_len", &err);
+    visit_start_array(v, (void **)&vdev->config, "config", vdev->config_len,
+                      sizeof(*config), &err);
+    config = vdev->config;
+    for (i = 0; i < vdev->config_len; i++) {
+        visit_type_uint8(v, &config[i], NULL, &err);
+    }
+    visit_end_array(v, &err);
 
-    num = qemu_get_be32(f);
+    visit_type_uint32(v, &num, "vq_count", &err);
 
+    visit_start_list(v, "vq_info", &err); 
     for (i = 0; i < num; i++) {
-        vdev->vq[i].vring.num = qemu_get_be32(f);
-        vdev->vq[i].pa = qemu_get_be64(f);
-        qemu_get_be16s(f, &vdev->vq[i].last_avail_idx);
+        visit_start_struct(v, NULL, NULL, NULL, 0, &err);
+
+        visit_type_uint32(v, &vdev->vq[i].vring.num, "vring.num", &err);
+        visit_type_uint64(v, &tmp, "pa", &err);
+        vdev->vq[i].pa = tmp;
+        visit_type_uint16(v, &vdev->vq[i].last_avail_idx, "last_avail_idx",
+                          &err);
         vdev->vq[i].signalled_used_valid = false;
         vdev->vq[i].notification = true;
 
@@ -817,13 +868,24 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
             error_report("VQ %d address 0x0 "
                          "inconsistent with Host index 0x%x",
                          i, vdev->vq[i].last_avail_idx);
-                return -1;
-       }
+            return -1;
+        }
         if (vdev->binding->load_queue) {
             ret = vdev->binding->load_queue(vdev->binding_opaque, i, f);
-            if (ret)
+            if (ret) {
                 return ret;
+            }
         }
+        visit_end_struct(v, &err);
+    }
+    visit_end_list(v, &err);
+
+    visit_end_struct(v, &err);
+
+    if (err) {
+        error_report("error loading virtio state: %s", error_get_pretty(err));
+        error_free(err);
+        return -1;
     }
 
     virtio_notify_vector(vdev, VIRTIO_NO_VECTOR);
-- 
1.7.4.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]