All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/13] Convert slirp/ivshmem/virtio save/load to Visitors
@ 2011-10-27 18:17 Michael Roth
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 01/13] slirp: convert save/load function to visitor interface Michael Roth
                   ` (12 more replies)
  0 siblings, 13 replies; 14+ messages in thread
From: Michael Roth @ 2011-10-27 18:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: aliguori, mdroth, quintela

These patches apply on top of version 2 of:

"do savevm/migration save/load via Visitor interface"

and can also be obtained from:

git://repo.or.cz/qemu/mdroth.git migration-visitor-conversions-set1-v1

OVERVIEW

These patches are the first conversions beyond the catch-all vmstate
conversion in the initial visitor-based save/load series. They were chosen
since they were users of common save/load interfaces in msix.c, pci.c, and
virtio.c which have been converted to accepting a Visitor in place of
QEMUFile as part of this series.

The slirp conversion is a carry-over from the initial RFC with some fix-ups.

The conversions are not pretty in a lot of cases, but the goal is to decouple
save/load from QEMUFile so we can rework things in the context of Visitors and
a new migration protocol.

There are roughly 19 qemufile-based save/load users remaining, 5 of which
are for CPUState serialization, which Juan is already porting to vmstate.

I plan to follow up shortly with the remaining x86-relevant users like apic
and i8254, which will put us about halfway there, with the remainder being:

hw/arm_gic.c
hw/tsc210x.c
hw/ssd0323.c
hw/stellaris_enet.c
hw/sun4u.c
hw/syborg_interrupt.c
hw/pxa2xx_mmci.c
hw/syborg_fb.c
hw/ssi-sd.c
hw/tsc2005.c
hw/pxa2xx.c
hw/rc4030.c

Testing will probably be the gating factor for these.

TESTING

There's a lot of churn here, but the conversions are fairly trivial for the
most part, and have been tested using a mostly-automated test framework that
involves tracing all visitor-based and qemufile-based serialization and
checking for symmetry between pre-converted/post-converted qemu instances.
Test code and procedure is documented at:

http://wiki.qemu.org/Features/Migration/Visitor#Testing

Michael Roth (13):
  slirp: convert save/load function to visitor interface
  ivshmem: convert save/load to visitor
  virtio-pci: convert save/load to visitors
  msix: convert save/load to visitors (including interfaces)
  openpic: convert save/load to visitors
  i440fx: convert save/load to visitors
  pci: convert pci_device_(save|load) interfaces to accept Visitors
  virtio: convert common virtio save/load to visitors
  virtio-balloon: convert save/load to visitors
  virtio-blk: convert save/load to visitors
  virtio-net: convert save/load to visitors
  virtio-serial: convert save/load to visitors
  virtio: convert virtio_save/virtio_load interfaces to accept Visitors

 hw/ivshmem.c           |   52 +++++--
 hw/msix.c              |   37 ++++--
 hw/msix.h              |    4 +-
 hw/openpic.c           |  192 +++++++++++++++++--------
 hw/pci.c               |    9 +-
 hw/pci.h               |    6 +-
 hw/piix_pci.c          |   27 +++-
 hw/virtio-balloon.c    |   36 ++++-
 hw/virtio-blk.c        |   80 +++++++++--
 hw/virtio-net.c        |  166 ++++++++++++++++-------
 hw/virtio-pci.c        |   75 ++++++++---
 hw/virtio-serial-bus.c |  130 ++++++++++++-----
 hw/virtio.c            |  145 ++++++++++++++------
 hw/virtio.h            |   14 +-
 slirp/slirp.c          |  366 ++++++++++++++++++++++++++++--------------------
 15 files changed, 918 insertions(+), 421 deletions(-)

-- 
1.7.4.1

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 01/13] slirp: convert save/load function to visitor interface
  2011-10-27 18:17 [Qemu-devel] [PATCH 00/13] Convert slirp/ivshmem/virtio save/load to Visitors Michael Roth
@ 2011-10-27 18:17 ` Michael Roth
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 02/13] ivshmem: convert save/load to visitor Michael Roth
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2011-10-27 18:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: aliguori, mdroth, quintela

Where possible common routines are used for both input and output, thus
save on lines of code, theoretically. The added lines here are mostly
due to extra logic for each save/load routine to manipulate strings into
a unique field name for each saved field, and in some cases a few extra
Visitor calls to due list/struct i/o. With some reworking we can
probably optimize all of these to reduce the amount of added code.

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 slirp/slirp.c |  366 +++++++++++++++++++++++++++++++++------------------------
 1 files changed, 213 insertions(+), 153 deletions(-)

diff --git a/slirp/slirp.c b/slirp/slirp.c
index 19d69eb..9631890 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -26,6 +26,9 @@
 #include "qemu-char.h"
 #include "slirp.h"
 #include "hw/hw.h"
+#include "qemu-error.h"
+
+#define SLIRP_DELIMITER 42 /* used to separate slirp instances in save/load */
 
 /* host loopback address */
 struct in_addr loopback_addr;
@@ -871,98 +874,147 @@ void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port,
         tcp_output(sototcpcb(so));
 }
 
-static void slirp_tcp_save(QEMUFile *f, struct tcpcb *tp)
+static void slirp_tcp_visit(Visitor *v, struct tcpcb *tp, Error *err)
 {
     int i;
+    int16_t *ptr;
+
+    visit_type_int16(v, &tp->t_state, "t_state", &err);
+    ptr = tp->t_timer;
+    visit_start_array(v, (void **)&ptr, "t_timer", TCPT_NTIMERS, sizeof(*ptr), &err);
+    for (i = 0; i < TCPT_NTIMERS; ++i) {
+        visit_type_int16(v, &ptr[i], NULL, &err);
+    }
+    visit_end_array(v, &err);
+    visit_type_int16(v, &tp->t_rxtshift, "t_rxtshift", &err);
+    visit_type_int16(v, &tp->t_rxtcur, "t_rxtcur", &err);
+    visit_type_int16(v, &tp->t_dupacks, "t_dupacks", &err);
+    visit_type_uint16(v, &tp->t_maxseg, "t_maxseg", &err);
+    visit_type_uint8(v, (uint8_t *)&tp->t_force, "t_force", &err);
+    visit_type_uint16(v, &tp->t_flags, "t_flags", &err);
+    visit_type_uint32(v, &tp->snd_una, "snd_una", &err);
+    visit_type_uint32(v, &tp->snd_nxt, "snd_nxt", &err);
+    visit_type_uint32(v, &tp->snd_up, "snd_up", &err);
+    visit_type_uint32(v, &tp->snd_wl1, "snd_wl1", &err);
+    visit_type_uint32(v, &tp->snd_wl2, "snd_wl2", &err);
+    visit_type_uint32(v, &tp->iss, "iss", &err);
+    visit_type_uint32(v, &tp->snd_wnd, "snd_wnd", &err);
+    visit_type_uint32(v, &tp->rcv_wnd, "rcv_wnd", &err);
+    visit_type_uint32(v, &tp->rcv_nxt, "rcv_nxt", &err);
+    visit_type_uint32(v, &tp->rcv_up, "rcv_up", &err);
+    visit_type_uint32(v, &tp->irs, "irs", &err);
+    visit_type_uint32(v, &tp->rcv_adv, "rcv_adv", &err);
+    visit_type_uint32(v, &tp->snd_max, "snd_max", &err);
+    visit_type_uint32(v, &tp->snd_cwnd, "snd_cwnd", &err);
+    visit_type_uint32(v, &tp->snd_ssthresh, "snd_ssthresh", &err);
+    visit_type_int16(v, &tp->t_idle, "t_idle", &err);
+    visit_type_int16(v, &tp->t_rtt, "t_rtt", &err);
+    visit_type_uint32(v, &tp->t_rtseq, "t_rtseq", &err);
+    visit_type_int16(v, &tp->t_srtt, "t_srtt", &err);
+    visit_type_int16(v, &tp->t_rttvar, "t_rttvar", &err);
+    visit_type_uint16(v, &tp->t_rttmin, "t_rttmin", &err);
+    visit_type_uint32(v, &tp->max_sndwnd, "max_sndwnd", &err);
+    visit_type_uint8(v, (uint8_t *)&tp->t_oobflags, "t_oobflags", &err);
+    visit_type_uint8(v, (uint8_t *)&tp->t_iobc, "t_iobc", &err);
+    visit_type_int16(v, &tp->t_softerror, "t_softerror", &err);
+    visit_type_uint8(v, &tp->snd_scale, "snd_scale", &err);
+    visit_type_uint8(v, &tp->rcv_scale, "rcv_scale", &err);
+    visit_type_uint8(v, &tp->request_r_scale, "request_r_scale", &err);
+    visit_type_uint8(v, &tp->requested_s_scale, "requested_s_scale", &err);
+    visit_type_uint32(v, &tp->ts_recent, "ts_recent", &err);
+    visit_type_uint32(v, &tp->ts_recent_age, "ts_recent_age", &err);
+    visit_type_uint32(v, &tp->last_ack_sent, "last_ack_sent", &err);
+}
 
-    qemu_put_sbe16(f, tp->t_state);
-    for (i = 0; i < TCPT_NTIMERS; i++)
-        qemu_put_sbe16(f, tp->t_timer[i]);
-    qemu_put_sbe16(f, tp->t_rxtshift);
-    qemu_put_sbe16(f, tp->t_rxtcur);
-    qemu_put_sbe16(f, tp->t_dupacks);
-    qemu_put_be16(f, tp->t_maxseg);
-    qemu_put_sbyte(f, tp->t_force);
-    qemu_put_be16(f, tp->t_flags);
-    qemu_put_be32(f, tp->snd_una);
-    qemu_put_be32(f, tp->snd_nxt);
-    qemu_put_be32(f, tp->snd_up);
-    qemu_put_be32(f, tp->snd_wl1);
-    qemu_put_be32(f, tp->snd_wl2);
-    qemu_put_be32(f, tp->iss);
-    qemu_put_be32(f, tp->snd_wnd);
-    qemu_put_be32(f, tp->rcv_wnd);
-    qemu_put_be32(f, tp->rcv_nxt);
-    qemu_put_be32(f, tp->rcv_up);
-    qemu_put_be32(f, tp->irs);
-    qemu_put_be32(f, tp->rcv_adv);
-    qemu_put_be32(f, tp->snd_max);
-    qemu_put_be32(f, tp->snd_cwnd);
-    qemu_put_be32(f, tp->snd_ssthresh);
-    qemu_put_sbe16(f, tp->t_idle);
-    qemu_put_sbe16(f, tp->t_rtt);
-    qemu_put_be32(f, tp->t_rtseq);
-    qemu_put_sbe16(f, tp->t_srtt);
-    qemu_put_sbe16(f, tp->t_rttvar);
-    qemu_put_be16(f, tp->t_rttmin);
-    qemu_put_be32(f, tp->max_sndwnd);
-    qemu_put_byte(f, tp->t_oobflags);
-    qemu_put_byte(f, tp->t_iobc);
-    qemu_put_sbe16(f, tp->t_softerror);
-    qemu_put_byte(f, tp->snd_scale);
-    qemu_put_byte(f, tp->rcv_scale);
-    qemu_put_byte(f, tp->request_r_scale);
-    qemu_put_byte(f, tp->requested_s_scale);
-    qemu_put_be32(f, tp->ts_recent);
-    qemu_put_be32(f, tp->ts_recent_age);
-    qemu_put_be32(f, tp->last_ack_sent);
+static void slirp_tcp_save(Visitor *v, struct tcpcb *tp, Error *err)
+{
+    slirp_tcp_visit(v, tp, err);
 }
 
-static void slirp_sbuf_save(QEMUFile *f, struct sbuf *sbuf)
+static void slirp_sbuf_save(Visitor *v, struct sbuf *sbuf, Error *err)
 {
-    uint32_t off;
+    int32_t off;
+    int i;
 
-    qemu_put_be32(f, sbuf->sb_cc);
-    qemu_put_be32(f, sbuf->sb_datalen);
+    visit_type_uint32(v, &sbuf->sb_cc, "sb_cc", &err);
+    visit_type_uint32(v, &sbuf->sb_datalen, "sb_datalen", &err);
     off = (uint32_t)(sbuf->sb_wptr - sbuf->sb_data);
-    qemu_put_sbe32(f, off);
+    visit_type_int32(v, &off, "sb_wptr_off", &err);
     off = (uint32_t)(sbuf->sb_rptr - sbuf->sb_data);
-    qemu_put_sbe32(f, off);
-    qemu_put_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
+    visit_type_int32(v, &off, "sb_rptr_off", &err);
+
+    visit_start_array(v, (void **)&sbuf->sb_data, "sb_data",
+                      sbuf->sb_datalen, sizeof(*sbuf->sb_data), &err);
+    for (i = 0; i < sbuf->sb_datalen; i++) {
+        visit_type_uint8(v, (uint8_t *)&sbuf->sb_data[i], NULL, &err);
+    }
+    visit_end_array(v, &err);
 }
 
-static void slirp_socket_save(QEMUFile *f, struct socket *so)
+static void slirp_socket_visit(Visitor *v, struct socket *so, Error *err)
 {
-    qemu_put_be32(f, so->so_urgc);
-    qemu_put_be32(f, so->so_faddr.s_addr);
-    qemu_put_be32(f, so->so_laddr.s_addr);
-    qemu_put_be16(f, so->so_fport);
-    qemu_put_be16(f, so->so_lport);
-    qemu_put_byte(f, so->so_iptos);
-    qemu_put_byte(f, so->so_emu);
-    qemu_put_byte(f, so->so_type);
-    qemu_put_be32(f, so->so_state);
-    slirp_sbuf_save(f, &so->so_rcv);
-    slirp_sbuf_save(f, &so->so_snd);
-    slirp_tcp_save(f, so->so_tcpcb);
+    visit_type_int32(v, &so->so_urgc, "so_urgc", &err);
+    /* TODO: use a nested struct for these guys */
+    visit_type_uint32(v, &so->so_faddr.s_addr, "so_faddr.s_addr", &err);
+    visit_type_uint32(v, &so->so_laddr.s_addr, "so_laddr.so_urgc", &err);
+    visit_type_uint16(v, &so->so_fport, "so_fport", &err);
+    visit_type_uint16(v, &so->so_lport, "so_lport", &err);
+    visit_type_uint8(v, &so->so_iptos, "so_iptos", &err);
+    visit_type_uint8(v, &so->so_emu, "so_emu", &err);
+    visit_type_uint8(v, &so->so_type, "so_type", &err);
+    visit_type_int32(v, &so->so_state, "so_state", &err);
 }
 
-static void slirp_bootp_save(QEMUFile *f, Slirp *slirp)
+static void slirp_socket_save(Visitor *v, struct socket *so, Error *err)
 {
-    int i;
+    slirp_socket_visit(v, so, err);
+
+    visit_start_struct(v, NULL, NULL, "so_rcv", 0, &err);
+    slirp_sbuf_save(v, &so->so_rcv, err);
+    visit_end_struct(v, &err);
+
+    visit_start_struct(v, NULL, NULL, "so_snd", 0, &err);
+    slirp_sbuf_save(v, &so->so_snd, err);
+    visit_end_struct(v, &err);
+
+    visit_start_struct(v, NULL, NULL, "so_tcpcb", 0, &err);
+    slirp_tcp_save(v, so->so_tcpcb, err);
+    visit_end_struct(v, &err);
+}
 
+static void slirp_bootp_visit(Visitor *v, Slirp *slirp, Error *err)
+{
+    int i, j;
+    BOOTPClient *bootp_clients = slirp->bootp_clients;
+    uint8_t *macaddr;
+    visit_start_array(v, (void **)&bootp_clients, "bootp_clients",
+                      NB_BOOTP_CLIENTS, sizeof(BOOTPClient), &err);
     for (i = 0; i < NB_BOOTP_CLIENTS; i++) {
-        qemu_put_be16(f, slirp->bootp_clients[i].allocated);
-        qemu_put_buffer(f, slirp->bootp_clients[i].macaddr, 6);
+        visit_start_struct(v, NULL, NULL, NULL, 0, &err);
+        visit_type_uint16(v, &bootp_clients[i].allocated, "allocated", &err);
+        macaddr = slirp->bootp_clients[i].macaddr;
+        visit_start_array(v, (void **)&macaddr, "macaddr", 6, 1, &err);
+        for (j = 0; j < 6; j++) {
+            visit_type_uint8(v, &macaddr[j], NULL, &err);
+        }
+        visit_end_array(v, &err);
+        visit_end_struct(v, &err);
     }
+    visit_end_array(v, &err);
 }
 
 static void slirp_state_save(QEMUFile *f, void *opaque)
 {
     Slirp *slirp = opaque;
     struct ex_list *ex_ptr;
+    uint8_t padding = SLIRP_DELIMITER;
+    Visitor *v = qemu_file_get_visitor(f);
+    Error *err = NULL;
 
-    for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
+    visit_start_struct(v, NULL, NULL, "slirp", 0, &err);
+
+    visit_start_list(v, "sockets", &err);
+    for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
         if (ex_ptr->ex_pty == 3) {
             struct socket *so;
             so = slirp_find_ctl_socket(slirp, ex_ptr->ex_addr,
@@ -970,70 +1022,47 @@ static void slirp_state_save(QEMUFile *f, void *opaque)
             if (!so)
                 continue;
 
-            qemu_put_byte(f, 42);
-            slirp_socket_save(f, so);
+            visit_start_struct(v, NULL, NULL, NULL, 0, &err);
+            visit_type_uint8(v, &padding, "padding", &err);
+            slirp_socket_save(v, so, err);
+            visit_end_struct(v, &err);
         }
-    qemu_put_byte(f, 0);
+    }
+    padding = 0;
+    visit_start_struct(v, NULL, NULL, NULL, 0, &err);
+    visit_type_uint8(v, &padding, "padding", &err);
+    visit_end_struct(v, &err);
+    visit_end_list(v, &err); /* slirp sockets */
+
 
-    qemu_put_be16(f, slirp->ip_id);
+    visit_type_uint16(v, &slirp->ip_id, "ip_id", &err);
 
-    slirp_bootp_save(f, slirp);
+    visit_start_struct(v, NULL, NULL, "bootp", 0, &err);
+    slirp_bootp_visit(v, slirp, err);
+    visit_end_struct(v, &err);
+
+    if (err) {
+        error_report("error saving slirp state: %s", error_get_pretty(err));
+        error_free(err);
+    }
+
+    visit_end_struct(v, &err); /* slirp state object */
 }
 
-static void slirp_tcp_load(QEMUFile *f, struct tcpcb *tp)
+static void slirp_tcp_load(Visitor *v, struct tcpcb *tp, Error *err)
 {
-    int i;
+    slirp_tcp_visit(v, tp, err);
 
-    tp->t_state = qemu_get_sbe16(f);
-    for (i = 0; i < TCPT_NTIMERS; i++)
-        tp->t_timer[i] = qemu_get_sbe16(f);
-    tp->t_rxtshift = qemu_get_sbe16(f);
-    tp->t_rxtcur = qemu_get_sbe16(f);
-    tp->t_dupacks = qemu_get_sbe16(f);
-    tp->t_maxseg = qemu_get_be16(f);
-    tp->t_force = qemu_get_sbyte(f);
-    tp->t_flags = qemu_get_be16(f);
-    tp->snd_una = qemu_get_be32(f);
-    tp->snd_nxt = qemu_get_be32(f);
-    tp->snd_up = qemu_get_be32(f);
-    tp->snd_wl1 = qemu_get_be32(f);
-    tp->snd_wl2 = qemu_get_be32(f);
-    tp->iss = qemu_get_be32(f);
-    tp->snd_wnd = qemu_get_be32(f);
-    tp->rcv_wnd = qemu_get_be32(f);
-    tp->rcv_nxt = qemu_get_be32(f);
-    tp->rcv_up = qemu_get_be32(f);
-    tp->irs = qemu_get_be32(f);
-    tp->rcv_adv = qemu_get_be32(f);
-    tp->snd_max = qemu_get_be32(f);
-    tp->snd_cwnd = qemu_get_be32(f);
-    tp->snd_ssthresh = qemu_get_be32(f);
-    tp->t_idle = qemu_get_sbe16(f);
-    tp->t_rtt = qemu_get_sbe16(f);
-    tp->t_rtseq = qemu_get_be32(f);
-    tp->t_srtt = qemu_get_sbe16(f);
-    tp->t_rttvar = qemu_get_sbe16(f);
-    tp->t_rttmin = qemu_get_be16(f);
-    tp->max_sndwnd = qemu_get_be32(f);
-    tp->t_oobflags = qemu_get_byte(f);
-    tp->t_iobc = qemu_get_byte(f);
-    tp->t_softerror = qemu_get_sbe16(f);
-    tp->snd_scale = qemu_get_byte(f);
-    tp->rcv_scale = qemu_get_byte(f);
-    tp->request_r_scale = qemu_get_byte(f);
-    tp->requested_s_scale = qemu_get_byte(f);
-    tp->ts_recent = qemu_get_be32(f);
-    tp->ts_recent_age = qemu_get_be32(f);
-    tp->last_ack_sent = qemu_get_be32(f);
     tcp_template(tp);
 }
 
-static int slirp_sbuf_load(QEMUFile *f, struct sbuf *sbuf)
+static int slirp_sbuf_load(Visitor *v, struct sbuf *sbuf, Error *err)
 {
     uint32_t off, sb_cc, sb_datalen;
+    int i;
 
-    sb_cc = qemu_get_be32(f);
-    sb_datalen = qemu_get_be32(f);
+    visit_type_uint32(v, &sb_cc, "sb_cc", &err);
+    visit_type_uint32(v, &sb_datalen, "sb_datalen", &err);
 
     sbreserve(sbuf, sb_datalen);
 
@@ -1042,64 +1071,82 @@ static int slirp_sbuf_load(QEMUFile *f, struct sbuf *sbuf)
 
     sbuf->sb_cc = sb_cc;
 
-    off = qemu_get_sbe32(f);
+    visit_type_uint32(v, &off, "sb_wptr_off", &err);
     sbuf->sb_wptr = sbuf->sb_data + off;
-    off = qemu_get_sbe32(f);
+    visit_type_uint32(v, &off, "sb_rptr_off", &err);
     sbuf->sb_rptr = sbuf->sb_data + off;
-    qemu_get_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
+
+    visit_start_array(v, (void **)&sbuf->sb_data, "sb_data",
+                      sbuf->sb_datalen, sizeof(*sbuf->sb_data), &err);
+    for (i = 0; i < sbuf->sb_datalen; i++) {
+        visit_type_uint8(v, (uint8_t *)&sbuf->sb_data[i], NULL, &err);
+    }
+    visit_end_array(v, &err);
 
     return 0;
 }
 
-static int slirp_socket_load(QEMUFile *f, struct socket *so)
+static int slirp_socket_load(Visitor *v, struct socket *so, Error *err)
 {
+    assert(v);
     if (tcp_attach(so) < 0)
         return -ENOMEM;
 
-    so->so_urgc = qemu_get_be32(f);
-    so->so_faddr.s_addr = qemu_get_be32(f);
-    so->so_laddr.s_addr = qemu_get_be32(f);
-    so->so_fport = qemu_get_be16(f);
-    so->so_lport = qemu_get_be16(f);
-    so->so_iptos = qemu_get_byte(f);
-    so->so_emu = qemu_get_byte(f);
-    so->so_type = qemu_get_byte(f);
-    so->so_state = qemu_get_be32(f);
-    if (slirp_sbuf_load(f, &so->so_rcv) < 0)
-        return -ENOMEM;
-    if (slirp_sbuf_load(f, &so->so_snd) < 0)
+    slirp_socket_visit(v, so, err);
+
+    visit_start_struct(v, NULL, NULL, "so_rcv", 0, &err);
+    if (slirp_sbuf_load(v, &so->so_rcv, err) < 0) {
         return -ENOMEM;
-    slirp_tcp_load(f, so->so_tcpcb);
+    }
+    visit_end_struct(v, &err);
 
-    return 0;
-}
+    visit_start_struct(v, NULL, NULL, "so_snd", 0, &err);
+    if (slirp_sbuf_load(v, &so->so_snd, err) < 0) {
+        return -ENOMEM;
+    }
+    visit_end_struct(v, &err);
 
-static void slirp_bootp_load(QEMUFile *f, Slirp *slirp)
-{
-    int i;
+    visit_start_struct(v, NULL, NULL, "so_tcpcb", 0, &err);
+    slirp_tcp_load(v, so->so_tcpcb, err);
+    visit_end_struct(v, &err);
 
-    for (i = 0; i < NB_BOOTP_CLIENTS; i++) {
-        slirp->bootp_clients[i].allocated = qemu_get_be16(f);
-        qemu_get_buffer(f, slirp->bootp_clients[i].macaddr, 6);
-    }
+    return 0;
 }
 
 static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
 {
     Slirp *slirp = opaque;
     struct ex_list *ex_ptr;
+    Visitor *v = qemu_file_get_visitor(f);
+    Error *err = NULL;
+    uint8_t padding;
+
+    visit_start_struct(v, NULL, NULL, "slirp", 0, &err);
 
-    while (qemu_get_byte(f)) {
+    visit_start_list(v, "sockets", &err);
+    while (1) {
         int ret;
-        struct socket *so = socreate(slirp);
+        struct socket *so;
+
+        visit_start_struct(v, NULL, NULL, NULL, 0, &err);
 
-        if (!so)
+        visit_type_uint8(v, &padding, "padding", &err);
+        if (padding != SLIRP_DELIMITER) {
+            visit_end_struct(v, &err);
+            break;
+        }
+
+        so = socreate(slirp);
+        if (!so) {
             return -ENOMEM;
+        }
 
-        ret = slirp_socket_load(f, so);
+        ret = slirp_socket_load(v, so, err);
+        visit_end_struct(v, &err);
 
-        if (ret < 0)
+        if (ret < 0) {
             return ret;
+        }
 
         if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) !=
             slirp->vnetwork_addr.s_addr) {
@@ -1112,19 +1159,32 @@ static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
                 break;
             }
         }
-        if (!ex_ptr)
+        if (!ex_ptr) {
             return -EINVAL;
+        }
 
         so->extra = (void *)ex_ptr->ex_exec;
-    }
+        visit_type_uint8(v, &padding, "padding", &err);
+    };
+    visit_end_list(v, &err); /* slirp sockets */
 
     if (version_id >= 2) {
-        slirp->ip_id = qemu_get_be16(f);
+        visit_type_uint16(v, &slirp->ip_id, "ip_id", &err);
     }
 
     if (version_id >= 3) {
-        slirp_bootp_load(f, slirp);
+        visit_start_struct(v, NULL, NULL, "bootp", 0, &err);
+        slirp_bootp_visit(v, slirp, err);
+        visit_end_struct(v, &err);
     }
 
+    if (err) {
+        error_report("error loading slirp state: %s", error_get_pretty(err));
+        error_free(err);
+        return -EINVAL;
+    }
+
+    visit_end_struct(v, &err); /* slirp state object */
+
     return 0;
 }
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 02/13] ivshmem: convert save/load to visitor
  2011-10-27 18:17 [Qemu-devel] [PATCH 00/13] Convert slirp/ivshmem/virtio save/load to Visitors Michael Roth
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 01/13] slirp: convert save/load function to visitor interface Michael Roth
@ 2011-10-27 18:17 ` Michael Roth
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 03/13] virtio-pci: convert save/load to visitors Michael Roth
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2011-10-27 18:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: aliguori, mdroth, quintela


Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 hw/ivshmem.c |   44 ++++++++++++++++++++++++++++++++++----------
 1 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index 242fbea..48e27f5 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -563,38 +563,55 @@ static void ivshmem_setup_msi(IVShmemState * s) {
 static void ivshmem_save(QEMUFile* f, void *opaque)
 {
     IVShmemState *proxy = opaque;
+    Visitor *v = qemu_file_get_visitor(f);
+    Error *err = NULL;
 
     IVSHMEM_DPRINTF("ivshmem_save\n");
+
+    visit_start_struct(v, NULL, NULL, "ivshmem", 0, &err);
+
     pci_device_save(&proxy->dev, f);
 
     if (ivshmem_has_feature(proxy, IVSHMEM_MSI)) {
         msix_save(&proxy->dev, f);
     } else {
-        qemu_put_be32(f, proxy->intrstatus);
-        qemu_put_be32(f, proxy->intrmask);
+        visit_type_uint32(v, &proxy->intrstatus, "proxy.intrstatus", &err);
+        visit_type_uint32(v, &proxy->intrmask, "proxy.intrmask", &err);
     }
 
+    visit_end_struct(v, &err);
+
+    if (err) {
+        error_report("error saving ivshmem state: %s", error_get_pretty(err));
+        error_free(err);
+    }
 }
 
 static int ivshmem_load(QEMUFile* f, void *opaque, int version_id)
 {
-    IVSHMEM_DPRINTF("ivshmem_load\n");
-
     IVShmemState *proxy = opaque;
     int ret, i;
+    Visitor *v = qemu_file_get_visitor(f);
+    Error *err = NULL;
+
+    IVSHMEM_DPRINTF("ivshmem_load\n");
+
+    visit_start_struct(v, NULL, NULL, "ivshmem", 0, &err);
 
     if (version_id > 0) {
-        return -EINVAL;
+        ret = -EINVAL;
+        goto out;
     }
 
     if (proxy->role_val == IVSHMEM_PEER) {
         fprintf(stderr, "ivshmem: 'peer' devices are not migratable\n");
-        return -EINVAL;
+        ret = -EINVAL;
+        goto out;
     }
 
     ret = pci_device_load(&proxy->dev, f);
     if (ret) {
-        return ret;
+        goto out;
     }
 
     if (ivshmem_has_feature(proxy, IVSHMEM_MSI)) {
@@ -603,11 +620,18 @@ static int ivshmem_load(QEMUFile* f, void *opaque, int version_id)
             msix_vector_use(&proxy->dev, i);
         }
     } else {
-        proxy->intrstatus = qemu_get_be32(f);
-        proxy->intrmask = qemu_get_be32(f);
+        visit_type_uint32(v, &proxy->intrstatus, "proxy.intrstatus", &err);
+        visit_type_uint32(v, &proxy->intrmask, "proxy.intrmask", &err);
     }
 
-    return 0;
+    visit_end_struct(v, &err);
+
+out:
+    if (err) {
+        error_report("error loading ivshmem state: %s", error_get_pretty(err));
+        error_free(err);
+    }
+    return ret;
 }
 
 static int pci_ivshmem_init(PCIDevice *dev)
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 03/13] virtio-pci: convert save/load to visitors
  2011-10-27 18:17 [Qemu-devel] [PATCH 00/13] Convert slirp/ivshmem/virtio save/load to Visitors Michael Roth
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 01/13] slirp: convert save/load function to visitor interface Michael Roth
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 02/13] ivshmem: convert save/load to visitor Michael Roth
@ 2011-10-27 18:17 ` Michael Roth
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 04/13] msix: convert save/load to visitors (including interfaces) Michael Roth
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2011-10-27 18:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: aliguori, mdroth, quintela


Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 hw/virtio-pci.c |   63 +++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 52 insertions(+), 11 deletions(-)

diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index ca5923c..9092c02 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -103,53 +103,94 @@ static void virtio_pci_notify(void *opaque, uint16_t vector)
 static void virtio_pci_save_config(void * opaque, QEMUFile *f)
 {
     VirtIOPCIProxy *proxy = opaque;
+    Visitor *v = qemu_file_get_visitor(f);
+    Error *err = NULL;
+
     pci_device_save(&proxy->pci_dev, f);
     msix_save(&proxy->pci_dev, f);
-    if (msix_present(&proxy->pci_dev))
-        qemu_put_be16(f, proxy->vdev->config_vector);
+    if (msix_present(&proxy->pci_dev)) {
+        visit_type_uint16(v, &proxy->vdev->config_vector,
+                          "proxy.vdev.config_vector", &err);
+    }
+    if (err) {
+        error_report("error saving virtio-pci config: %s",
+                     error_get_pretty(err));
+        error_free(err);
+    }
 }
 
 static void virtio_pci_save_queue(void * opaque, int n, QEMUFile *f)
 {
     VirtIOPCIProxy *proxy = opaque;
-    if (msix_present(&proxy->pci_dev))
-        qemu_put_be16(f, virtio_queue_vector(proxy->vdev, n));
+    Visitor *v = qemu_file_get_visitor(f);
+    Error *err = NULL;
+    uint16_t vector;
+
+    if (msix_present(&proxy->pci_dev)) {
+        vector = virtio_queue_vector(proxy->vdev, n);
+        visit_type_uint16(v, &vector, "vector", &err);
+    }
+    if (err) {
+        error_report("error saving virtio-pci queue: %s",
+                     error_get_pretty(err));
+        error_free(err);
+    }
 }
 
 static int virtio_pci_load_config(void * opaque, QEMUFile *f)
 {
     VirtIOPCIProxy *proxy = opaque;
+    Visitor *v = qemu_file_get_visitor(f);
+    Error *err = NULL;
     int ret;
+
     ret = pci_device_load(&proxy->pci_dev, f);
     if (ret) {
-        return ret;
+        goto out;
     }
     msix_load(&proxy->pci_dev, f);
     if (msix_present(&proxy->pci_dev)) {
-        qemu_get_be16s(f, &proxy->vdev->config_vector);
+        visit_type_uint16(v, &proxy->vdev->config_vector,
+                          "proxy.vdev.config_vector", &err);
     } else {
         proxy->vdev->config_vector = VIRTIO_NO_VECTOR;
     }
     if (proxy->vdev->config_vector != VIRTIO_NO_VECTOR) {
-        return msix_vector_use(&proxy->pci_dev, proxy->vdev->config_vector);
+        ret = msix_vector_use(&proxy->pci_dev, proxy->vdev->config_vector);
     }
-    return 0;
+out:
+    if (err) {
+        error_report("error loading virtio-pci config: %s",
+                     error_get_pretty(err));
+        error_free(err);
+    }
+    return ret;
 }
 
 static int virtio_pci_load_queue(void * opaque, int n, QEMUFile *f)
 {
     VirtIOPCIProxy *proxy = opaque;
+    Visitor *v = qemu_file_get_visitor(f);
+    Error *err = NULL;
     uint16_t vector;
+    int ret = 0;
     if (msix_present(&proxy->pci_dev)) {
-        qemu_get_be16s(f, &vector);
+        visit_type_uint16(v, &vector, "vector", &err);
     } else {
         vector = VIRTIO_NO_VECTOR;
     }
     virtio_queue_set_vector(proxy->vdev, n, vector);
     if (vector != VIRTIO_NO_VECTOR) {
-        return msix_vector_use(&proxy->pci_dev, vector);
+        ret = msix_vector_use(&proxy->pci_dev, vector);
+        goto out;
     }
-    return 0;
+out:
+    if (err) {
+        error_report("error loading virtio-pci config: %s",
+                     error_get_pretty(err));
+        error_free(err);
+    }
+    return ret;
 }
 
 static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy,
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 04/13] msix: convert save/load to visitors (including interfaces)
  2011-10-27 18:17 [Qemu-devel] [PATCH 00/13] Convert slirp/ivshmem/virtio save/load to Visitors Michael Roth
                   ` (2 preceding siblings ...)
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 03/13] virtio-pci: convert save/load to visitors Michael Roth
@ 2011-10-27 18:17 ` Michael Roth
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 05/13] openpic: convert save/load to visitors Michael Roth
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2011-10-27 18:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: aliguori, mdroth, quintela

Use visitors for serialization.

Also, with the only 2 direct users, virtio-pci and ivshmem, converted
to visitors, we can change msix save/load function to take a Visitor
directly, along with an Error object.

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 hw/ivshmem.c    |    4 ++--
 hw/msix.c       |   37 ++++++++++++++++++++++++++++---------
 hw/msix.h       |    4 ++--
 hw/virtio-pci.c |    4 ++--
 4 files changed, 34 insertions(+), 15 deletions(-)

diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index 48e27f5..8d0607d 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -573,7 +573,7 @@ static void ivshmem_save(QEMUFile* f, void *opaque)
     pci_device_save(&proxy->dev, f);
 
     if (ivshmem_has_feature(proxy, IVSHMEM_MSI)) {
-        msix_save(&proxy->dev, f);
+        msix_save(&proxy->dev, v, &err);
     } else {
         visit_type_uint32(v, &proxy->intrstatus, "proxy.intrstatus", &err);
         visit_type_uint32(v, &proxy->intrmask, "proxy.intrmask", &err);
@@ -615,7 +615,7 @@ static int ivshmem_load(QEMUFile* f, void *opaque, int version_id)
     }
 
     if (ivshmem_has_feature(proxy, IVSHMEM_MSI)) {
-        msix_load(&proxy->dev, f);
+        msix_load(&proxy->dev, v, &err);
         for (i = 0; i < proxy->vectors; i++) {
             msix_vector_use(&proxy->dev, i);
         }
diff --git a/hw/msix.c b/hw/msix.c
index b15bafc..c62eeaa 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -276,30 +276,49 @@ int msix_uninit(PCIDevice *dev, MemoryRegion *bar)
     return 0;
 }
 
-void msix_save(PCIDevice *dev, QEMUFile *f)
+static void msix_visit(Visitor *v, PCIDevice *dev, Error **errp)
 {
     unsigned n = dev->msix_entries_nr;
+    int i;
+    Error *err = NULL;
 
+    visit_start_struct(v, NULL, NULL, "msix", 0, &err);
+
+    visit_start_array(v, NULL, "msix_table_page", n * PCI_MSIX_ENTRY_SIZE, 1,
+                      &err);
+    for (i = 0; i < n * PCI_MSIX_ENTRY_SIZE; i++) {
+        visit_type_uint8(v, &dev->msix_table_page[i], NULL, &err);
+    }
+    visit_end_array(v, &err);
+
+    visit_start_array(v, NULL, "msix_table_page_pending", (n + 7) / 8, 1, &err);
+    for (i = 0; i < (n + 7) / 8; i++) {
+        visit_type_uint8(v, &dev->msix_table_page[i + MSIX_PAGE_PENDING],
+                         NULL, &err);
+    }
+    visit_end_array(v, &err);
+
+    visit_end_struct(v, &err);
+    error_propagate(errp, err);
+}
+
+void msix_save(PCIDevice *dev, Visitor *v, Error **errp)
+{
     if (!(dev->cap_present & QEMU_PCI_CAP_MSIX)) {
         return;
     }
-
-    qemu_put_buffer(f, dev->msix_table_page, n * PCI_MSIX_ENTRY_SIZE);
-    qemu_put_buffer(f, dev->msix_table_page + MSIX_PAGE_PENDING, (n + 7) / 8);
+    msix_visit(v, dev, errp);
 }
 
 /* Should be called after restoring the config space. */
-void msix_load(PCIDevice *dev, QEMUFile *f)
+void msix_load(PCIDevice *dev, Visitor *v, Error **errp)
 {
-    unsigned n = dev->msix_entries_nr;
-
     if (!(dev->cap_present & QEMU_PCI_CAP_MSIX)) {
         return;
     }
 
     msix_free_irq_entries(dev);
-    qemu_get_buffer(f, dev->msix_table_page, n * PCI_MSIX_ENTRY_SIZE);
-    qemu_get_buffer(f, dev->msix_table_page + MSIX_PAGE_PENDING, (n + 7) / 8);
+    msix_visit(v, dev, errp);
 }
 
 /* Does device support MSI-X? */
diff --git a/hw/msix.h b/hw/msix.h
index 7e04336..e60ab10 100644
--- a/hw/msix.h
+++ b/hw/msix.h
@@ -13,8 +13,8 @@ void msix_write_config(PCIDevice *pci_dev, uint32_t address,
 
 int msix_uninit(PCIDevice *d, MemoryRegion *bar);
 
-void msix_save(PCIDevice *dev, QEMUFile *f);
-void msix_load(PCIDevice *dev, QEMUFile *f);
+void msix_save(PCIDevice *dev, Visitor *v, Error **errp);
+void msix_load(PCIDevice *dev, Visitor *v, Error **errp);
 
 int msix_enabled(PCIDevice *dev);
 int msix_present(PCIDevice *dev);
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 9092c02..ca9cabc 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -107,7 +107,7 @@ static void virtio_pci_save_config(void * opaque, QEMUFile *f)
     Error *err = NULL;
 
     pci_device_save(&proxy->pci_dev, f);
-    msix_save(&proxy->pci_dev, f);
+    msix_save(&proxy->pci_dev, v, &err);
     if (msix_present(&proxy->pci_dev)) {
         visit_type_uint16(v, &proxy->vdev->config_vector,
                           "proxy.vdev.config_vector", &err);
@@ -148,7 +148,7 @@ static int virtio_pci_load_config(void * opaque, QEMUFile *f)
     if (ret) {
         goto out;
     }
-    msix_load(&proxy->pci_dev, f);
+    msix_load(&proxy->pci_dev, v, &err);
     if (msix_present(&proxy->pci_dev)) {
         visit_type_uint16(v, &proxy->vdev->config_vector,
                           "proxy.vdev.config_vector", &err);
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 05/13] openpic: convert save/load to visitors
  2011-10-27 18:17 [Qemu-devel] [PATCH 00/13] Convert slirp/ivshmem/virtio save/load to Visitors Michael Roth
                   ` (3 preceding siblings ...)
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 04/13] msix: convert save/load to visitors (including interfaces) Michael Roth
@ 2011-10-27 18:17 ` Michael Roth
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 06/13] i440fx: " Michael Roth
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2011-10-27 18:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: aliguori, mdroth, quintela


Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 hw/openpic.c |  190 +++++++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 128 insertions(+), 62 deletions(-)

diff --git a/hw/openpic.c b/hw/openpic.c
index 22fc275..6e8c3a3 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -1045,134 +1045,200 @@ static const MemoryRegionOps openpic_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static void openpic_save_IRQ_queue(QEMUFile* f, IRQ_queue_t *q)
+static void openpic_visit_IRQ_queue(Visitor* v, IRQ_queue_t *q, Error **errp)
 {
     unsigned int i;
+    Error *err = NULL;
 
-    for (i = 0; i < BF_WIDTH(MAX_IRQ); i++)
-        qemu_put_be32s(f, &q->queue[i]);
+    visit_start_array(v, NULL, "queue", BF_WIDTH(MAX_IRQ), 4, &err);
+    for (i = 0; i < BF_WIDTH(MAX_IRQ); i++) {
+        visit_type_uint32(v, &q->queue[i], NULL, &err);
+    }
+    visit_end_array(v, &err);
+
+    visit_type_int32(v, &q->next, "next", &err);
+    visit_type_int32(v, &q->priority, "priority", &err);
 
-    qemu_put_sbe32s(f, &q->next);
-    qemu_put_sbe32s(f, &q->priority);
+    if (err) {
+        error_report("error loading openpic state: %s", error_get_pretty(err));
+        error_propagate(errp, err);
+    }
 }
 
 static void openpic_save(QEMUFile* f, void *opaque)
 {
     openpic_t *opp = (openpic_t *)opaque;
     unsigned int i;
+    Visitor *v = qemu_file_get_visitor(f);
+    Error *err = NULL;
 
-    qemu_put_be32s(f, &opp->frep);
-    qemu_put_be32s(f, &opp->glbc);
-    qemu_put_be32s(f, &opp->micr);
-    qemu_put_be32s(f, &opp->veni);
-    qemu_put_be32s(f, &opp->pint);
-    qemu_put_be32s(f, &opp->spve);
-    qemu_put_be32s(f, &opp->tifr);
+    visit_start_struct(v, NULL, NULL, "openpic", 0, &err);
 
+    visit_type_uint32(v, &opp->frep, "frep", &err);
+    visit_type_uint32(v, &opp->glbc, "glbc", &err);
+    visit_type_uint32(v, &opp->micr, "micr", &err);
+    visit_type_uint32(v, &opp->veni, "veni", &err);
+    visit_type_uint32(v, &opp->pint, "pint", &err);
+    visit_type_uint32(v, &opp->spve, "spve", &err);
+    visit_type_uint32(v, &opp->tifr, "tifr", &err);
+
+    visit_start_array(v, NULL, "src", opp->max_irq, sizeof(IRQ_src_t), &err);
     for (i = 0; i < opp->max_irq; i++) {
-        qemu_put_be32s(f, &opp->src[i].ipvp);
-        qemu_put_be32s(f, &opp->src[i].ide);
-        qemu_put_sbe32s(f, &opp->src[i].type);
-        qemu_put_sbe32s(f, &opp->src[i].last_cpu);
-        qemu_put_sbe32s(f, &opp->src[i].pending);
+        visit_start_struct(v, NULL, NULL, NULL, 0, &err);
+        visit_type_uint32(v, &opp->src[i].ipvp, "ipvp", &err);
+        visit_type_uint32(v, &opp->src[i].ide, "ide", &err);
+        visit_type_int32(v, &opp->src[i].type, "type", &err);
+        visit_type_int32(v, &opp->src[i].last_cpu, "last_cpu", &err);
+        visit_type_int32(v, &opp->src[i].pending, "pending", &err);
+        visit_end_struct(v, &err);
     }
+    visit_end_array(v, &err);
 
-    qemu_put_sbe32s(f, &opp->nb_cpus);
+    visit_type_int32(v, &opp->nb_cpus, "nb_cpus", &err);
 
+    visit_start_array(v, NULL, "dst", opp->nb_cpus, sizeof(IRQ_dst_t), &err);
     for (i = 0; i < opp->nb_cpus; i++) {
-        qemu_put_be32s(f, &opp->dst[i].tfrr);
-        qemu_put_be32s(f, &opp->dst[i].pctp);
-        qemu_put_be32s(f, &opp->dst[i].pcsr);
-        openpic_save_IRQ_queue(f, &opp->dst[i].raised);
-        openpic_save_IRQ_queue(f, &opp->dst[i].servicing);
-    }
-
+        visit_start_struct(v, NULL, NULL, NULL, 0, &err);
+        visit_type_uint32(v, &opp->dst[i].tfrr, "tfrr", &err);
+        visit_type_uint32(v, &opp->dst[i].pctp, "pctp", &err);
+        visit_type_uint32(v, &opp->dst[i].pcsr, "pcsr", &err);
+        visit_start_struct(v, NULL, NULL, "raised", 0, &err);
+        openpic_visit_IRQ_queue(v, &opp->dst[i].raised, &err);
+        visit_end_struct(v, &err);
+        visit_start_struct(v, NULL, NULL, "servicing", 0, &err);
+        openpic_visit_IRQ_queue(v, &opp->dst[i].servicing, &err);
+        visit_end_struct(v, &err);
+        visit_end_struct(v, &err);
+    }
+    visit_end_array(v, &err);
+
+    visit_start_array(v, NULL, "timers", MAX_TMR, 8, &err);
     for (i = 0; i < MAX_TMR; i++) {
-        qemu_put_be32s(f, &opp->timers[i].ticc);
-        qemu_put_be32s(f, &opp->timers[i].tibc);
+        visit_start_struct(v, NULL, NULL, NULL, 0, &err);
+        visit_type_uint32(v, &opp->timers[i].ticc, "ticc", &err);
+        visit_type_uint32(v, &opp->timers[i].tibc, "tibc", &err);
+        visit_end_struct(v, &err);
     }
+    visit_end_array(v, &err);
 
 #if MAX_DBL > 0
-    qemu_put_be32s(f, &opp->dar);
+    visit_type_uint32(v, &opp->dar, "dar", &err);
 
+    visit_start_array(v, NULL, "doorbells", MAX_DBL, 4, &err);
     for (i = 0; i < MAX_DBL; i++) {
-        qemu_put_be32s(f, &opp->doorbells[i].dmr);
+        visit_start_struct(v, NULL, NULL, NULL, 0, &err);
+        visit_type_uint32(v, &opp->doorbells[i].dmr, "dmr", &err);
+        visit_end_struct(v, &err);
     }
+    visit_end_array(v, &err);
 #endif
 
 #if MAX_MBX > 0
+    visit_start_array(v, NULL, "mailboxes", MAX_DBL, 4, &err);
     for (i = 0; i < MAX_MAILBOXES; i++) {
-        qemu_put_be32s(f, &opp->mailboxes[i].mbr);
+        visit_start_struct(v, NULL, NULL, NULL, 0, &err);
+        visit_type_uint32(v, &opp->mailboxes[i].mbr, "mbr", &err);
+        visit_end_struct(v, &err);
     }
+    visit_end_array(v, &err);
 #endif
 
-    pci_device_save(&opp->pci_dev, f);
-}
+    visit_end_struct(v, &err);
 
-static void openpic_load_IRQ_queue(QEMUFile* f, IRQ_queue_t *q)
-{
-    unsigned int i;
-
-    for (i = 0; i < BF_WIDTH(MAX_IRQ); i++)
-        qemu_get_be32s(f, &q->queue[i]);
-
-    qemu_get_sbe32s(f, &q->next);
-    qemu_get_sbe32s(f, &q->priority);
+    if (err) {
+        error_report("error saving openpic state: %s", error_get_pretty(err));
+        error_free(err);
+    }
+    pci_device_save(&opp->pci_dev, f);
 }
 
 static int openpic_load(QEMUFile* f, void *opaque, int version_id)
 {
     openpic_t *opp = (openpic_t *)opaque;
     unsigned int i;
+    Visitor *v = qemu_file_get_visitor(f);
+    Error *err = NULL;
 
     if (version_id != 1)
         return -EINVAL;
 
-    qemu_get_be32s(f, &opp->frep);
-    qemu_get_be32s(f, &opp->glbc);
-    qemu_get_be32s(f, &opp->micr);
-    qemu_get_be32s(f, &opp->veni);
-    qemu_get_be32s(f, &opp->pint);
-    qemu_get_be32s(f, &opp->spve);
-    qemu_get_be32s(f, &opp->tifr);
+    visit_start_struct(v, NULL, NULL, "openpic", 0, &err);
+
+    visit_type_uint32(v, &opp->frep, "frep", &err);
+    visit_type_uint32(v, &opp->glbc, "glbc", &err);
+    visit_type_uint32(v, &opp->micr, "micr", &err);
+    visit_type_uint32(v, &opp->veni, "veni", &err);
+    visit_type_uint32(v, &opp->pint, "pint", &err);
+    visit_type_uint32(v, &opp->spve, "spve", &err);
+    visit_type_uint32(v, &opp->tifr, "tifr", &err);
 
+    visit_start_array(v, NULL, "src", opp->max_irq, sizeof(IRQ_src_t), &err);
     for (i = 0; i < opp->max_irq; i++) {
-        qemu_get_be32s(f, &opp->src[i].ipvp);
-        qemu_get_be32s(f, &opp->src[i].ide);
-        qemu_get_sbe32s(f, &opp->src[i].type);
-        qemu_get_sbe32s(f, &opp->src[i].last_cpu);
-        qemu_get_sbe32s(f, &opp->src[i].pending);
+        visit_start_struct(v, NULL, NULL, NULL, 0, &err);
+        visit_type_uint32(v, &opp->src[i].ipvp, "ipvp", &err);
+        visit_type_uint32(v, &opp->src[i].ide, "ide", &err);
+        visit_type_int32(v, &opp->src[i].type, "type", &err);
+        visit_type_int32(v, &opp->src[i].last_cpu, "last_cpu", &err);
+        visit_type_int32(v, &opp->src[i].pending, "pending", &err);
+        visit_end_struct(v, &err);
     }
+    visit_end_array(v, &err);
 
-    qemu_get_sbe32s(f, &opp->nb_cpus);
+    visit_type_int32(v, &opp->nb_cpus, "nb_cpus", &err);
 
+    visit_start_array(v, NULL, "dst", opp->nb_cpus, sizeof(IRQ_dst_t), &err);
     for (i = 0; i < opp->nb_cpus; i++) {
-        qemu_get_be32s(f, &opp->dst[i].tfrr);
-        qemu_get_be32s(f, &opp->dst[i].pctp);
-        qemu_get_be32s(f, &opp->dst[i].pcsr);
-        openpic_load_IRQ_queue(f, &opp->dst[i].raised);
-        openpic_load_IRQ_queue(f, &opp->dst[i].servicing);
-    }
-
+        visit_start_struct(v, NULL, NULL, NULL, 0, &err);
+        visit_type_uint32(v, &opp->dst[i].tfrr, "tfrr", &err);
+        visit_type_uint32(v, &opp->dst[i].pctp, "pctp", &err);
+        visit_type_uint32(v, &opp->dst[i].pcsr, "pcsr", &err);
+        visit_start_struct(v, NULL, NULL, "raised", 0, &err);
+        openpic_visit_IRQ_queue(v, &opp->dst[i].raised, &err);
+        visit_end_struct(v, &err);
+        visit_start_struct(v, NULL, NULL, "servicing", 0, &err);
+        openpic_visit_IRQ_queue(v, &opp->dst[i].servicing, &err);
+        visit_end_struct(v, &err);
+        visit_end_struct(v, &err);
+    }
+    visit_end_array(v, &err);
+
+    visit_start_array(v, NULL, "timers", MAX_TMR, 8, &err);
     for (i = 0; i < MAX_TMR; i++) {
-        qemu_get_be32s(f, &opp->timers[i].ticc);
-        qemu_get_be32s(f, &opp->timers[i].tibc);
+        visit_start_struct(v, NULL, NULL, NULL, 0, &err);
+        visit_type_uint32(v, &opp->timers[i].ticc, "ticc", &err);
+        visit_type_uint32(v, &opp->timers[i].tibc, "tibc", &err);
+        visit_end_struct(v, &err);
     }
+    visit_end_array(v, &err);
 
 #if MAX_DBL > 0
-    qemu_get_be32s(f, &opp->dar);
+    visit_type_uint32(v, &opp->dar, "dar", &err);
 
+    visit_start_array(v, NULL, "doorbells", MAX_DBL, 4, &err);
     for (i = 0; i < MAX_DBL; i++) {
-        qemu_get_be32s(f, &opp->doorbells[i].dmr);
+        visit_start_struct(v, NULL, NULL, NULL, 0, &err);
+        visit_type_uint32(v, &opp->doorbells[i].dmr, "dmr", &err);
+        visit_end_struct(v, &err);
     }
+    visit_end_array(v, &err);
 #endif
 
 #if MAX_MBX > 0
+    visit_start_array(v, NULL, "mailboxes", MAX_DBL, 4, &err);
     for (i = 0; i < MAX_MAILBOXES; i++) {
-        qemu_get_be32s(f, &opp->mailboxes[i].mbr);
+        visit_start_struct(v, NULL, NULL, NULL, 0, &err);
+        visit_type_uint32(v, &opp->mailboxes[i].mbr, "mbr", &err);
+        visit_end_struct(v, &err);
     }
+    visit_end_array(v, &err);
 #endif
 
+    visit_end_struct(v, &err);
+
+    if (err) {
+        error_report("error loading openpic state: %s", error_get_pretty(err));
+        error_free(err);
+    }
     return pci_device_load(&opp->pci_dev, f);
 }
 
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 06/13] i440fx: convert save/load to visitors
  2011-10-27 18:17 [Qemu-devel] [PATCH 00/13] Convert slirp/ivshmem/virtio save/load to Visitors Michael Roth
                   ` (4 preceding siblings ...)
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 05/13] openpic: convert save/load to visitors Michael Roth
@ 2011-10-27 18:17 ` Michael Roth
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 07/13] pci: convert pci_device_(save|load) interfaces to accept Visitors Michael Roth
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2011-10-27 18:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: aliguori, mdroth, quintela


Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 hw/piix_pci.c |   25 ++++++++++++++++++++-----
 1 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index d183443..0e405f3 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -195,20 +195,35 @@ static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id)
 {
     PCII440FXState *d = opaque;
     int ret, i;
+    uint32_t dummy;
+    Visitor *v = qemu_file_get_visitor(f);
+    Error *err = NULL;
+
+    visit_start_struct(v, NULL, NULL, "i440fx", 0, &err);
 
     ret = pci_device_load(&d->dev, f);
-    if (ret < 0)
-        return ret;
+    if (ret < 0) {
+        goto out;
+    }
     i440fx_update_memory_mappings(d);
-    qemu_get_8s(f, &d->smm_enabled);
+    visit_type_uint8(v, &d->smm_enabled, "smm_enabled", &err);
 
     if (version_id == 2) {
+        visit_start_array(v, NULL, "dummy_irqs", PIIX_NUM_PIRQS, 4, &err);
         for (i = 0; i < PIIX_NUM_PIRQS; i++) {
-            qemu_get_be32(f); /* dummy load for compatibility */
+            visit_type_uint32(v, &dummy, NULL, &err); /* dummy load for compatibility */
         }
+        visit_end_array(v, &err);
     }
 
-    return 0;
+    visit_end_struct(v, &err);
+
+out:
+    if (err) {
+        error_report("error loading i440fx state: %s", error_get_pretty(err));
+        error_free(err);
+    }
+    return ret;
 }
 
 static int i440fx_post_load(void *opaque, int version_id)
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 07/13] pci: convert pci_device_(save|load) interfaces to accept Visitors
  2011-10-27 18:17 [Qemu-devel] [PATCH 00/13] Convert slirp/ivshmem/virtio save/load to Visitors Michael Roth
                   ` (5 preceding siblings ...)
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 06/13] i440fx: " Michael Roth
@ 2011-10-27 18:17 ` Michael Roth
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 08/13] virtio: convert common virtio save/load to visitors Michael Roth
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2011-10-27 18:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: aliguori, mdroth, quintela

With all callers converted to Visitors, we can change the
interface to accept a Visitor directly, along with an Error** for error
propagation.

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 hw/ivshmem.c    |    4 ++--
 hw/openpic.c    |    4 ++--
 hw/pci.c        |    9 +++++----
 hw/pci.h        |    6 ++++--
 hw/piix_pci.c   |    2 +-
 hw/virtio-pci.c |    4 ++--
 6 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index 8d0607d..264970e 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -570,7 +570,7 @@ static void ivshmem_save(QEMUFile* f, void *opaque)
 
     visit_start_struct(v, NULL, NULL, "ivshmem", 0, &err);
 
-    pci_device_save(&proxy->dev, f);
+    pci_device_save(&proxy->dev, v, &err);
 
     if (ivshmem_has_feature(proxy, IVSHMEM_MSI)) {
         msix_save(&proxy->dev, v, &err);
@@ -609,7 +609,7 @@ static int ivshmem_load(QEMUFile* f, void *opaque, int version_id)
         goto out;
     }
 
-    ret = pci_device_load(&proxy->dev, f);
+    ret = pci_device_load(&proxy->dev, v, &err);
     if (ret) {
         goto out;
     }
diff --git a/hw/openpic.c b/hw/openpic.c
index 6e8c3a3..d666bb3 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -1149,7 +1149,7 @@ static void openpic_save(QEMUFile* f, void *opaque)
         error_report("error saving openpic state: %s", error_get_pretty(err));
         error_free(err);
     }
-    pci_device_save(&opp->pci_dev, f);
+    pci_device_save(&opp->pci_dev, v, &err);
 }
 
 static int openpic_load(QEMUFile* f, void *opaque, int version_id)
@@ -1239,7 +1239,7 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id)
         error_report("error loading openpic state: %s", error_get_pretty(err));
         error_free(err);
     }
-    return pci_device_load(&opp->pci_dev, f);
+    return pci_device_load(&opp->pci_dev, v, &err);
 }
 
 static void openpic_irq_raise(openpic_t *opp, int n_CPU, IRQ_src_t *src)
diff --git a/hw/pci.c b/hw/pci.c
index a0ab0e0..70b1eb8 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -465,22 +465,23 @@ static inline const VMStateDescription *pci_get_vmstate(PCIDevice *s)
     return pci_is_express(s) ? &vmstate_pcie_device : &vmstate_pci_device;
 }
 
-void pci_device_save(PCIDevice *s, QEMUFile *f)
+void pci_device_save(PCIDevice *s, Visitor *v, Error **errp)
 {
     /* Clear interrupt status bit: it is implicit
      * in irq_state which we are saving.
      * This makes us compatible with old devices
      * which never set or clear this bit. */
     s->config[PCI_STATUS] &= ~PCI_STATUS_INTERRUPT;
-    vmstate_save_state(f, pci_get_vmstate(s), s);
+    vmstate_process(v, pci_get_vmstate(s), s, 0, VMS_SAVE, errp);
     /* Restore the interrupt status bit. */
     pci_update_irq_status(s);
 }
 
-int pci_device_load(PCIDevice *s, QEMUFile *f)
+int pci_device_load(PCIDevice *s, Visitor *v, Error **errp)
 {
     int ret;
-    ret = vmstate_load_state(f, pci_get_vmstate(s), s, s->version_id);
+    ret = vmstate_process(v, pci_get_vmstate(s), s, s->version_id, VMS_LOAD,
+                          errp);
     /* Restore the interrupt status bit. */
     pci_update_irq_status(s);
     return ret;
diff --git a/hw/pci.h b/hw/pci.h
index 86a81c8..a3809d3 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -11,6 +11,8 @@
 #include "isa.h"
 
 #include "pcie.h"
+#include "qapi/qapi-visit-core.h"
+#include "error.h"
 
 /* PCI bus */
 
@@ -215,8 +217,8 @@ uint32_t pci_default_read_config(PCIDevice *d,
                                  uint32_t address, int len);
 void pci_default_write_config(PCIDevice *d,
                               uint32_t address, uint32_t val, int len);
-void pci_device_save(PCIDevice *s, QEMUFile *f);
-int pci_device_load(PCIDevice *s, QEMUFile *f);
+void pci_device_save(PCIDevice *s, Visitor *v, Error **errp);
+int pci_device_load(PCIDevice *s, Visitor *v, Error **errp);
 MemoryRegion *pci_address_space(PCIDevice *dev);
 MemoryRegion *pci_address_space_io(PCIDevice *dev);
 
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 0e405f3..79506f6 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -201,7 +201,7 @@ static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id)
 
     visit_start_struct(v, NULL, NULL, "i440fx", 0, &err);
 
-    ret = pci_device_load(&d->dev, f);
+    ret = pci_device_load(&d->dev, v, &err);
     if (ret < 0) {
         goto out;
     }
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index ca9cabc..cede802 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -106,7 +106,7 @@ static void virtio_pci_save_config(void * opaque, QEMUFile *f)
     Visitor *v = qemu_file_get_visitor(f);
     Error *err = NULL;
 
-    pci_device_save(&proxy->pci_dev, f);
+    pci_device_save(&proxy->pci_dev, v, &err);
     msix_save(&proxy->pci_dev, v, &err);
     if (msix_present(&proxy->pci_dev)) {
         visit_type_uint16(v, &proxy->vdev->config_vector,
@@ -144,7 +144,7 @@ static int virtio_pci_load_config(void * opaque, QEMUFile *f)
     Error *err = NULL;
     int ret;
 
-    ret = pci_device_load(&proxy->pci_dev, f);
+    ret = pci_device_load(&proxy->pci_dev, v, &err);
     if (ret) {
         goto out;
     }
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 08/13] virtio: convert common virtio save/load to visitors
  2011-10-27 18:17 [Qemu-devel] [PATCH 00/13] Convert slirp/ivshmem/virtio save/load to Visitors Michael Roth
                   ` (6 preceding siblings ...)
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 07/13] pci: convert pci_device_(save|load) interfaces to accept Visitors Michael Roth
@ 2011-10-27 18:17 ` Michael Roth
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 09/13] virtio-balloon: convert " Michael Roth
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2011-10-27 18:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: aliguori, mdroth, quintela


Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 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

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 09/13] virtio-balloon: convert save/load to visitors
  2011-10-27 18:17 [Qemu-devel] [PATCH 00/13] Convert slirp/ivshmem/virtio save/load to Visitors Michael Roth
                   ` (7 preceding siblings ...)
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 08/13] virtio: convert common virtio save/load to visitors Michael Roth
@ 2011-10-27 18:17 ` Michael Roth
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 10/13] virtio-blk: " Michael Roth
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2011-10-27 18:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: aliguori, mdroth, quintela


Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 hw/virtio-balloon.c |   32 ++++++++++++++++++++++++++++----
 1 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/hw/virtio-balloon.c b/hw/virtio-balloon.c
index 5f8f4bd..242c58d 100644
--- a/hw/virtio-balloon.c
+++ b/hw/virtio-balloon.c
@@ -246,24 +246,48 @@ static void virtio_balloon_to_target(void *opaque, ram_addr_t target)
 static void virtio_balloon_save(QEMUFile *f, void *opaque)
 {
     VirtIOBalloon *s = opaque;
+    Visitor *v = qemu_file_get_visitor(f);
+    Error *err = NULL;
+
+    visit_start_struct(v, NULL, NULL, "virtio_balloon", 0, &err);
 
     virtio_save(&s->vdev, f);
 
-    qemu_put_be32(f, s->num_pages);
-    qemu_put_be32(f, s->actual);
+    visit_type_uint32(v, &s->num_pages, "num_pages", &err);
+    visit_type_uint32(v, &s->actual, "actual", &err);
+
+    visit_end_struct(v, &err);
+
+    if (err) {
+        error_report("error saving virtio-balloon state: %s", error_get_pretty(err));
+        error_free(err);
+    }
 }
 
 static int virtio_balloon_load(QEMUFile *f, void *opaque, int version_id)
 {
     VirtIOBalloon *s = opaque;
+    Visitor *v = qemu_file_get_visitor(f);
+    Error *err = NULL;
 
     if (version_id != 1)
         return -EINVAL;
 
+    visit_start_struct(v, NULL, NULL, "virtio_balloon", 0, &err);
+
     virtio_load(&s->vdev, f);
 
-    s->num_pages = qemu_get_be32(f);
-    s->actual = qemu_get_be32(f);
+    visit_type_uint32(v, &s->num_pages, "num_pages", &err);
+    visit_type_uint32(v, &s->actual, "actual", &err);
+
+    visit_end_struct(v, &err);
+
+    if (err) {
+        error_report("error loading virtio-balloon state: %s", error_get_pretty(err));
+        error_free(err);
+        return -EINVAL;
+    }
+
     return 0;
 }
 
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 10/13] virtio-blk: convert save/load to visitors
  2011-10-27 18:17 [Qemu-devel] [PATCH 00/13] Convert slirp/ivshmem/virtio save/load to Visitors Michael Roth
                   ` (8 preceding siblings ...)
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 09/13] virtio-balloon: convert " Michael Roth
@ 2011-10-27 18:17 ` Michael Roth
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 11/13] virtio-net: " Michael Roth
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2011-10-27 18:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: aliguori, mdroth, quintela


Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 hw/virtio-blk.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 68 insertions(+), 8 deletions(-)

diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index 2a5d1a9..2ddcc1e 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -511,37 +511,97 @@ static void virtio_blk_save(QEMUFile *f, void *opaque)
 {
     VirtIOBlock *s = opaque;
     VirtIOBlockReq *req = s->rq;
+    Visitor *v = qemu_file_get_visitor(f);
+    Error *err = NULL;
+    uint8_t *buf, marker;
+    int i;
+
+    visit_start_struct(v, NULL, NULL, "virtio_blk", 0, &err);
 
     virtio_save(&s->vdev, f);
     
+    visit_start_list(v, "requests", &err);
     while (req) {
-        qemu_put_sbyte(f, 1);
-        qemu_put_buffer(f, (unsigned char*)&req->elem, sizeof(req->elem));
+        visit_start_struct(v, NULL, NULL, NULL, 0, &err);
+
+        marker = 1;
+        visit_type_uint8(v, &marker, "marker", &err);
+        visit_start_array(v, NULL, "elem", sizeof(req->elem), 1, &err);
+        buf = (uint8_t *)&req->elem;
+        for (i = 0; i < sizeof(req->elem); i++) {
+            visit_type_uint8(v, &buf[i], NULL, &err);
+        }
+        visit_end_array(v, &err);
+
+        visit_end_struct(v, &err);
         req = req->next;
     }
-    qemu_put_sbyte(f, 0);
+    visit_start_struct(v, NULL, NULL, NULL, 0, &err);
+    marker = 0;
+    visit_type_uint8(v, &marker, "marker", &err);
+    visit_end_struct(v, &err);
+    visit_end_list(v, &err);
+
+    visit_end_struct(v, &err);
+
+    if (err) {
+        error_report("error saving virtio-blk state: %s", error_get_pretty(err));
+        error_free(err);
+    }
 }
 
 static int virtio_blk_load(QEMUFile *f, void *opaque, int version_id)
 {
     VirtIOBlock *s = opaque;
+    Visitor *v = qemu_file_get_visitor(f);
+    Error *err = NULL;
+    uint8_t marker, *buf;
+    int i;
 
-    if (version_id != 2)
+    if (version_id != 2) {
         return -EINVAL;
+    }
+
+    visit_start_struct(v, NULL, NULL, "virtio_blk", 0, &err);
 
     virtio_load(&s->vdev, f);
-    while (qemu_get_sbyte(f)) {
+
+    visit_start_list(v, "requests", &err);
+    while (1) {
+        visit_start_struct(v, NULL, NULL, NULL, 0, &err);
+
+        visit_type_uint8(v, &marker, "marker", &err);
+        if (!marker) {
+            visit_end_struct(v, &err);
+            break;
+        }
         VirtIOBlockReq *req = virtio_blk_alloc_request(s);
-        qemu_get_buffer(f, (unsigned char*)&req->elem, sizeof(req->elem));
+        visit_start_array(v, NULL, "elem", sizeof(req->elem), 1, &err);
+        buf = (uint8_t *)&req->elem;
+        for (i = 0; i < sizeof(req->elem); i++) {
+            visit_type_uint8(v, &buf[i], NULL, &err);
+        }
+        visit_end_array(v, &err);
+
+        visit_end_struct(v, &err);
+
         req->next = s->rq;
         s->rq = req;
 
         virtqueue_map_sg(req->elem.in_sg, req->elem.in_addr,
-            req->elem.in_num, 1);
+                         req->elem.in_num, 1);
         virtqueue_map_sg(req->elem.out_sg, req->elem.out_addr,
-            req->elem.out_num, 0);
+                         req->elem.out_num, 0);
     }
+    visit_end_list(v, &err);
 
+    visit_end_struct(v, &err);
+
+    if (err) {
+        error_report("error loading virtio-blk state: %s", error_get_pretty(err));
+        error_free(err);
+        return -1;
+    }
     return 0;
 }
 
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 11/13] virtio-net: convert save/load to visitors
  2011-10-27 18:17 [Qemu-devel] [PATCH 00/13] Convert slirp/ivshmem/virtio save/load to Visitors Michael Roth
                   ` (9 preceding siblings ...)
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 10/13] virtio-blk: " Michael Roth
@ 2011-10-27 18:17 ` Michael Roth
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 12/13] virtio-serial: " Michael Roth
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 13/13] virtio: convert virtio_save/virtio_load interfaces to accept Visitors Michael Roth
  12 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2011-10-27 18:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: aliguori, mdroth, quintela


Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 hw/virtio-net.c |  160 +++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 115 insertions(+), 45 deletions(-)

diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 8c2f460..974af5c 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -862,78 +862,138 @@ static void virtio_net_tx_bh(void *opaque)
 static void virtio_net_save(QEMUFile *f, void *opaque)
 {
     VirtIONet *n = opaque;
+    Visitor *v = qemu_file_get_visitor(f);
+    Error *err = NULL;
+    uint8_t *buf;
+    int i;
 
     /* At this point, backend must be stopped, otherwise
      * it might keep writing to memory. */
     assert(!n->vhost_started);
+
+    visit_start_struct(v, NULL, NULL, "virtio_net", 0, &err);
+
     virtio_save(&n->vdev, f);
 
-    qemu_put_buffer(f, n->mac, ETH_ALEN);
-    qemu_put_be32(f, n->tx_waiting);
-    qemu_put_be32(f, n->mergeable_rx_bufs);
-    qemu_put_be16(f, n->status);
-    qemu_put_byte(f, n->promisc);
-    qemu_put_byte(f, n->allmulti);
-    qemu_put_be32(f, n->mac_table.in_use);
-    qemu_put_buffer(f, n->mac_table.macs, n->mac_table.in_use * ETH_ALEN);
-    qemu_put_buffer(f, (uint8_t *)n->vlans, MAX_VLAN >> 3);
-    qemu_put_be32(f, n->has_vnet_hdr);
-    qemu_put_byte(f, n->mac_table.multi_overflow);
-    qemu_put_byte(f, n->mac_table.uni_overflow);
-    qemu_put_byte(f, n->alluni);
-    qemu_put_byte(f, n->nomulti);
-    qemu_put_byte(f, n->nouni);
-    qemu_put_byte(f, n->nobcast);
-    qemu_put_byte(f, n->has_ufo);
+    visit_start_array(v, NULL, "mac", ETH_ALEN, 1, &err);
+    for (i = 0; i < ETH_ALEN; i++) {
+        visit_type_uint8(v, &n->mac[i], NULL, &err);
+    }
+    visit_end_array(v, &err);
+    visit_type_int32(v, &n->tx_waiting, "tx_waiting", &err);
+    visit_type_int32(v, &n->mergeable_rx_bufs, "mergeable_rx_bufs", &err);
+    visit_type_uint16(v, &n->status, "status", &err);
+    visit_type_uint8(v, &n->promisc, "promisc", &err);
+    visit_type_uint8(v, &n->allmulti, "allmulti", &err);
+    visit_type_int32(v, &n->mac_table.in_use, "mac_table", &err);
+    visit_start_array(v, NULL, "mac_tables.macs",
+                      n->mac_table.in_use * ETH_ALEN, 1, &err);
+    for (i = 0; i < n->mac_table.in_use * ETH_ALEN; i++) {
+        visit_type_uint8(v, &n->mac_table.macs[i], NULL, &err);
+    }
+    visit_end_array(v, &err);
+    visit_start_array(v, NULL, "vlans", MAX_VLAN >> 3, 1, &err);
+    buf = (uint8_t *)n->vlans;
+    for (i = 0; i < MAX_VLAN >> 3; i++) {
+        visit_type_uint8(v, &buf[i], NULL, &err);
+    }
+    visit_end_array(v, &err);
+    visit_type_uint32(v, &n->has_vnet_hdr, "has_vnet_hdr", &err);
+    visit_type_uint8(v, &n->mac_table.multi_overflow,
+                     "mac_table.multi_overflow", &err);
+    visit_type_uint8(v, &n->mac_table.uni_overflow,
+                      "mac_table.uni_overflow", &err);
+    visit_type_uint8(v, &n->alluni, "alluni", &err);
+    visit_type_uint8(v, &n->nomulti, "nomulti", &err);
+    visit_type_uint8(v, &n->nouni, "nouni", &err);
+    visit_type_uint8(v, &n->nobcast, "nobcast", &err);
+    visit_type_uint8(v, &n->has_ufo, "has_ufo", &err);
+
+    visit_end_struct(v, &err);
+    if (err) {
+        error_report("error loading virtio-net state: %s", error_get_pretty(err));
+        error_free(err);
+    }
 }
 
 static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
 {
     VirtIONet *n = opaque;
-    int i;
+    Visitor *v = qemu_file_get_visitor(f);
+    Error *err = NULL;
+    uint8_t *buf, tmp, has_ufo;
+    uint32_t has_vnet_hdr;
+    int i, ret = 0;
+
+    if (version_id < 2 || version_id > VIRTIO_NET_VM_VERSION) {
+        ret = -EINVAL;
+        goto out;
+    }
 
-    if (version_id < 2 || version_id > VIRTIO_NET_VM_VERSION)
-        return -EINVAL;
+    visit_start_struct(v, NULL, NULL, "virtio_net", 0, &err);
 
     virtio_load(&n->vdev, f);
 
-    qemu_get_buffer(f, n->mac, ETH_ALEN);
-    n->tx_waiting = qemu_get_be32(f);
-    n->mergeable_rx_bufs = qemu_get_be32(f);
+    visit_start_array(v, NULL, "mac", ETH_ALEN, 1, &err);
+    for (i = 0; i < ETH_ALEN; i++) {
+        visit_type_uint8(v, &n->mac[i], NULL, &err);
+    }
+    visit_end_array(v, &err);
+    visit_type_int32(v, &n->tx_waiting, "tx_waiting", &err);
+    visit_type_int32(v, &n->mergeable_rx_bufs, "mergeable_rx_bufs", &err);
 
-    if (version_id >= 3)
-        n->status = qemu_get_be16(f);
+    if (version_id >= 3) {
+        visit_type_uint16(v, &n->status, "status", &err);
+    }
 
     if (version_id >= 4) {
         if (version_id < 8) {
-            n->promisc = qemu_get_be32(f);
-            n->allmulti = qemu_get_be32(f);
+            visit_type_uint32(v, (uint32_t *)&n->promisc, "promisc", &err);
+            visit_type_uint32(v, (uint32_t *)&n->allmulti, "allmulti", &err);
         } else {
-            n->promisc = qemu_get_byte(f);
-            n->allmulti = qemu_get_byte(f);
+            visit_type_uint8(v, (uint8_t *)&n->promisc, "promisc", &err);
+            visit_type_uint8(v, (uint8_t *)&n->allmulti, "allmulti", &err);
         }
     }
 
     if (version_id >= 5) {
-        n->mac_table.in_use = qemu_get_be32(f);
+        visit_type_int32(v, &n->mac_table.in_use, "mac_table", &err);
         /* MAC_TABLE_ENTRIES may be different from the saved image */
         if (n->mac_table.in_use <= MAC_TABLE_ENTRIES) {
-            qemu_get_buffer(f, n->mac_table.macs,
-                            n->mac_table.in_use * ETH_ALEN);
+            visit_start_array(v, NULL, "mac_tables.macs",
+                              n->mac_table.in_use * ETH_ALEN, 1, &err);
+            for (i = 0; i < n->mac_table.in_use * ETH_ALEN; i++) {
+                visit_type_uint8(v, &n->mac_table.macs[i], NULL, &err);
+            }
+            visit_end_array(v, &err);
         } else if (n->mac_table.in_use) {
-            qemu_fseek(f, n->mac_table.in_use * ETH_ALEN, SEEK_CUR);
+            /* dummy load */
+            visit_start_array(v, NULL, "mac_tables.macs",
+                              n->mac_table.in_use * ETH_ALEN, 1, &err);
+            for (i = 0; i < n->mac_table.in_use * ETH_ALEN; i++) {
+                visit_type_uint8(v, &tmp, NULL, &err);
+            }
+            visit_end_array(v, &err);
             n->mac_table.multi_overflow = n->mac_table.uni_overflow = 1;
             n->mac_table.in_use = 0;
         }
     }
  
-    if (version_id >= 6)
-        qemu_get_buffer(f, (uint8_t *)n->vlans, MAX_VLAN >> 3);
+    if (version_id >= 6) {
+        visit_start_array(v, NULL, "vlans", MAX_VLAN >> 3, 1, &err);
+        buf = (uint8_t *)n->vlans;
+        for (i = 0; i < MAX_VLAN >> 3; i++) {
+            visit_type_uint8(v, &buf[i], NULL, &err);
+        }
+        visit_end_array(v, &err);
+    }
 
     if (version_id >= 7) {
-        if (qemu_get_be32(f) && !peer_has_vnet_hdr(n)) {
+        visit_type_uint32(v, &has_vnet_hdr, "has_vnet_hdr", &err);
+        if (has_vnet_hdr && !peer_has_vnet_hdr(n)) {
             error_report("virtio-net: saved image requires vnet_hdr=on");
-            return -1;
+            ret = -1;
+            goto out;
         }
 
         if (n->has_vnet_hdr) {
@@ -948,24 +1008,27 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
     }
 
     if (version_id >= 9) {
-        n->mac_table.multi_overflow = qemu_get_byte(f);
-        n->mac_table.uni_overflow = qemu_get_byte(f);
+        visit_type_uint8(v, &n->mac_table.multi_overflow, "mac_table.multi_overflow", &err);
+        visit_type_uint8(v, &n->mac_table.uni_overflow, "mac_table.uni_overflow", &err);
     }
 
     if (version_id >= 10) {
-        n->alluni = qemu_get_byte(f);
-        n->nomulti = qemu_get_byte(f);
-        n->nouni = qemu_get_byte(f);
-        n->nobcast = qemu_get_byte(f);
+        visit_type_uint8(v, &n->alluni, "alluni", &err);
+        visit_type_uint8(v, &n->nomulti, "nomulti", &err);
+        visit_type_uint8(v, &n->nouni, "nouni", &err);
+        visit_type_uint8(v, &n->nobcast, "nobcast", &err);
     }
 
     if (version_id >= 11) {
-        if (qemu_get_byte(f) && !peer_has_ufo(n)) {
+        visit_type_uint8(v, &has_ufo, "has_ufo", &err);
+        if (has_ufo && !peer_has_ufo(n)) {
             error_report("virtio-net: saved image requires TUN_F_UFO support");
             return -1;
         }
     }
 
+    visit_end_struct(v, &err);
+
     /* Find the first multicast entry in the saved MAC filter */
     for (i = 0; i < n->mac_table.in_use; i++) {
         if (n->mac_table.macs[i * ETH_ALEN] & 1) {
@@ -973,7 +1036,14 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
         }
     }
     n->mac_table.first_multi = i;
-    return 0;
+
+    if (err) {
+        error_report("error loading virtio-net state: %s", error_get_pretty(err));
+        ret = -EINVAL;
+    }
+out:
+    error_free(err);
+    return ret;
 }
 
 static void virtio_net_cleanup(VLANClientState *nc)
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 12/13] virtio-serial: convert save/load to visitors
  2011-10-27 18:17 [Qemu-devel] [PATCH 00/13] Convert slirp/ivshmem/virtio save/load to Visitors Michael Roth
                   ` (10 preceding siblings ...)
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 11/13] virtio-net: " Michael Roth
@ 2011-10-27 18:17 ` Michael Roth
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 13/13] virtio: convert virtio_save/virtio_load interfaces to accept Visitors Michael Roth
  12 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2011-10-27 18:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: aliguori, mdroth, quintela


Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 hw/virtio-serial-bus.c |  126 ++++++++++++++++++++++++++++++++++-------------
 1 files changed, 91 insertions(+), 35 deletions(-)

diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index a4825b9..78cd643 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -521,21 +521,28 @@ static void virtio_serial_save(QEMUFile *f, void *opaque)
     VirtIOSerialPort *port;
     uint32_t nr_active_ports;
     unsigned int i, max_nr_ports;
+    uint8_t *buf;
+    Visitor *v = qemu_file_get_visitor(f);
+    Error *err = NULL;
+
+    visit_start_struct(v, NULL, NULL, "virtio_serial", 0, &err);
 
     /* The virtio device */
     virtio_save(&s->vdev, f);
 
     /* The config space */
-    qemu_put_be16s(f, &s->config.cols);
-    qemu_put_be16s(f, &s->config.rows);
+    visit_type_uint16(v, &s->config.cols, "config.cols", &err);
+    visit_type_uint16(v, &s->config.rows, "config.rows", &err);
 
-    qemu_put_be32s(f, &s->config.max_nr_ports);
+    visit_type_uint32(v, &s->config.max_nr_ports, "config.max_nr_ports", &err);
 
     /* The ports map */
     max_nr_ports = tswap32(s->config.max_nr_ports);
+    visit_start_array(v, NULL, "ports_map", (max_nr_ports + 31) / 32, 4, &err);
     for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
-        qemu_put_be32s(f, &s->ports_map[i]);
+        visit_type_uint32(v, &s->ports_map[i], NULL, &err);
     }
+    visit_end_array(v, &err);
 
     /* Ports */
 
@@ -544,31 +551,46 @@ static void virtio_serial_save(QEMUFile *f, void *opaque)
         nr_active_ports++;
     }
 
-    qemu_put_be32s(f, &nr_active_ports);
+    visit_type_uint32(v, &nr_active_ports, "nr_active_ports", &err);
 
     /*
      * Items in struct VirtIOSerialPort.
      */
+    visit_start_list(v, "ports", &err);
     QTAILQ_FOREACH(port, &s->ports, next) {
         uint32_t elem_popped;
 
-        qemu_put_be32s(f, &port->id);
-        qemu_put_byte(f, port->guest_connected);
-        qemu_put_byte(f, port->host_connected);
+        visit_start_struct(v, NULL, NULL, NULL, 0, &err);
+
+        visit_type_uint32(v, &port->id, "id", &err);
+        visit_type_uint8(v, (uint8_t *)&port->guest_connected,
+                         "guest_connected", &err);
+        visit_type_uint8(v, (uint8_t *)&port->host_connected,
+                         "host_connected", &err);
 
-	elem_popped = 0;
+        elem_popped = 0;
         if (port->elem.out_num) {
             elem_popped = 1;
         }
-        qemu_put_be32s(f, &elem_popped);
+        visit_type_uint32(v, &elem_popped, "elem_popped", &err);
         if (elem_popped) {
-            qemu_put_be32s(f, &port->iov_idx);
-            qemu_put_be64s(f, &port->iov_offset);
-
-            qemu_put_buffer(f, (unsigned char *)&port->elem,
-                            sizeof(port->elem));
+            visit_type_uint32(v, &port->iov_idx, "iov_idx", &err);
+            visit_type_uint64(v, &port->iov_offset, "iov_offset", &err);
+
+            /* FIXME: migration badness, serializing structs as blobs */
+            visit_start_array(v, NULL, "elem", sizeof(port->elem), 1, &err);
+            buf = (uint8_t *)&port->elem;
+            for (i = 0; i < sizeof(port->elem); i++) {
+                visit_type_uint8(v, &buf[i], NULL, &err);
+            }
+            visit_end_array(v, &err);
         }
+
+        visit_end_struct(v, &err);
     }
+    visit_end_list(v, &err);
+
+    visit_end_struct(v, &err);
 }
 
 static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
@@ -577,56 +599,73 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
     VirtIOSerialPort *port;
     uint32_t max_nr_ports, nr_active_ports, ports_map;
     unsigned int i;
+    int ret = 0;
+    Visitor *v = qemu_file_get_visitor(f);
+    Error *err = NULL;
+    uint8_t *buf;
 
     if (version_id > 3) {
-        return -EINVAL;
+        ret = -EINVAL;
+        goto out;
     }
 
+    visit_start_struct(v, NULL, NULL, "virtio_serial", 0, &err);
+
     /* The virtio device */
     virtio_load(&s->vdev, f);
 
     if (version_id < 2) {
-        return 0;
+        goto out;
     }
 
     /* The config space */
-    qemu_get_be16s(f, &s->config.cols);
-    qemu_get_be16s(f, &s->config.rows);
+    visit_type_uint16(v, &s->config.cols, "config.cols", &err);
+    visit_type_uint16(v, &s->config.rows, "config.rows", &err);
 
-    qemu_get_be32s(f, &max_nr_ports);
+    visit_type_uint32(v, &max_nr_ports, "config.max_nr_ports", &err);
     tswap32s(&max_nr_ports);
     if (max_nr_ports > tswap32(s->config.max_nr_ports)) {
         /* Source could have had more ports than us. Fail migration. */
-        return -EINVAL;
+        ret = -EINVAL;
+        goto out;
     }
 
+    visit_start_array(v, NULL, "ports_map", (max_nr_ports + 31) / 32, 4, &err);
     for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
-        qemu_get_be32s(f, &ports_map);
+        visit_type_uint32(v, &ports_map, NULL, &err);
 
         if (ports_map != s->ports_map[i]) {
             /*
              * Ports active on source and destination don't
              * match. Fail migration.
              */
-            return -EINVAL;
+            ret = -EINVAL;
+            goto out;
         }
     }
+    visit_end_array(v, &err);
 
-    qemu_get_be32s(f, &nr_active_ports);
+    visit_type_uint32(v, &nr_active_ports, "nr_active_ports", &err);
 
     /* Items in struct VirtIOSerialPort */
+    visit_start_list(v, "ports", &err);
     for (i = 0; i < nr_active_ports; i++) {
         uint32_t id;
-        bool host_connected;
+        uint8_t host_connected;
+
+        visit_start_struct(v, NULL, NULL, NULL, 0, &err);
 
-        id = qemu_get_be32(f);
+        visit_type_uint32(v, &id, "id", &err);
         port = find_port_by_id(s, id);
         if (!port) {
-            return -EINVAL;
+            ret = -EINVAL;
+            goto out;
         }
 
-        port->guest_connected = qemu_get_byte(f);
-        host_connected = qemu_get_byte(f);
+        visit_type_uint8(v, (uint8_t *)&port->guest_connected,
+                         "guest_connected", &err);
+        visit_type_uint8(v, (uint8_t *)&host_connected,
+                         "host_connected", &err);
         if (host_connected != port->host_connected) {
             /*
              * We have to let the guest know of the host connection
@@ -639,13 +678,19 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
         if (version_id > 2) {
             uint32_t elem_popped;
 
-            qemu_get_be32s(f, &elem_popped);
+            visit_type_uint32(v, &elem_popped, "elem_popped", &err);
             if (elem_popped) {
-                qemu_get_be32s(f, &port->iov_idx);
-                qemu_get_be64s(f, &port->iov_offset);
+                visit_type_uint32(v, &port->iov_idx, "iov_idx", &err);
+                visit_type_uint64(v, &port->iov_offset, "iov_offset", &err);
+
+                /* FIXME: migration badness, serializing structs as blobs */
+                visit_start_array(v, NULL, "elem", sizeof(port->elem), 1, &err);
+                buf = (uint8_t *)&port->elem;
+                for (i = 0; i < sizeof(port->elem); i++) {
+                    visit_type_uint8(v, &buf[i], NULL, &err);
+                }
+                visit_end_array(v, &err);
 
-                qemu_get_buffer(f, (unsigned char *)&port->elem,
-                                sizeof(port->elem));
                 virtqueue_map_sg(port->elem.in_sg, port->elem.in_addr,
                                  port->elem.in_num, 1);
                 virtqueue_map_sg(port->elem.out_sg, port->elem.out_addr,
@@ -658,8 +703,19 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
                 virtio_serial_throttle_port(port, false);
             }
         }
+        visit_end_struct(v, &err);
     }
-    return 0;
+    visit_end_list(v, &err);
+
+    visit_end_struct(v, &err);
+
+    if (err) {
+        error_report("error loading virtio-net state: %s", error_get_pretty(err));
+        ret = -EINVAL;
+    }
+out:
+    error_free(err);
+    return ret;
 }
 
 static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent);
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 13/13] virtio: convert virtio_save/virtio_load interfaces to accept Visitors
  2011-10-27 18:17 [Qemu-devel] [PATCH 00/13] Convert slirp/ivshmem/virtio save/load to Visitors Michael Roth
                   ` (11 preceding siblings ...)
  2011-10-27 18:17 ` [Qemu-devel] [PATCH 12/13] virtio-serial: " Michael Roth
@ 2011-10-27 18:17 ` Michael Roth
  12 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2011-10-27 18:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: aliguori, mdroth, quintela

With all virtio_save/virtio_load users converted to visitors, modify the
interface to accept a Visitor directly, along with an Error** for error
propagation.

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 hw/virtio-balloon.c    |    4 ++--
 hw/virtio-blk.c        |    4 ++--
 hw/virtio-net.c        |    4 ++--
 hw/virtio-pci.c        |   12 ++++--------
 hw/virtio-serial-bus.c |    4 ++--
 hw/virtio.c            |   37 +++++++++++++++++++------------------
 hw/virtio.h            |   14 +++++++-------
 7 files changed, 38 insertions(+), 41 deletions(-)

diff --git a/hw/virtio-balloon.c b/hw/virtio-balloon.c
index 242c58d..2ba8c91 100644
--- a/hw/virtio-balloon.c
+++ b/hw/virtio-balloon.c
@@ -251,7 +251,7 @@ static void virtio_balloon_save(QEMUFile *f, void *opaque)
 
     visit_start_struct(v, NULL, NULL, "virtio_balloon", 0, &err);
 
-    virtio_save(&s->vdev, f);
+    virtio_save(&s->vdev, v, &err);
 
     visit_type_uint32(v, &s->num_pages, "num_pages", &err);
     visit_type_uint32(v, &s->actual, "actual", &err);
@@ -275,7 +275,7 @@ static int virtio_balloon_load(QEMUFile *f, void *opaque, int version_id)
 
     visit_start_struct(v, NULL, NULL, "virtio_balloon", 0, &err);
 
-    virtio_load(&s->vdev, f);
+    virtio_load(&s->vdev, v, &err);
 
     visit_type_uint32(v, &s->num_pages, "num_pages", &err);
     visit_type_uint32(v, &s->actual, "actual", &err);
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index 2ddcc1e..4efc70e 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -518,7 +518,7 @@ static void virtio_blk_save(QEMUFile *f, void *opaque)
 
     visit_start_struct(v, NULL, NULL, "virtio_blk", 0, &err);
 
-    virtio_save(&s->vdev, f);
+    virtio_save(&s->vdev, v, &err);
     
     visit_start_list(v, "requests", &err);
     while (req) {
@@ -564,7 +564,7 @@ static int virtio_blk_load(QEMUFile *f, void *opaque, int version_id)
 
     visit_start_struct(v, NULL, NULL, "virtio_blk", 0, &err);
 
-    virtio_load(&s->vdev, f);
+    virtio_load(&s->vdev, v, &err);
 
     visit_start_list(v, "requests", &err);
     while (1) {
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 974af5c..a4ea61e 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -873,7 +873,7 @@ static void virtio_net_save(QEMUFile *f, void *opaque)
 
     visit_start_struct(v, NULL, NULL, "virtio_net", 0, &err);
 
-    virtio_save(&n->vdev, f);
+    virtio_save(&n->vdev, v, &err);
 
     visit_start_array(v, NULL, "mac", ETH_ALEN, 1, &err);
     for (i = 0; i < ETH_ALEN; i++) {
@@ -932,7 +932,7 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
 
     visit_start_struct(v, NULL, NULL, "virtio_net", 0, &err);
 
-    virtio_load(&n->vdev, f);
+    virtio_load(&n->vdev, v, &err);
 
     visit_start_array(v, NULL, "mac", ETH_ALEN, 1, &err);
     for (i = 0; i < ETH_ALEN; i++) {
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index cede802..051bcad 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -100,10 +100,9 @@ static void virtio_pci_notify(void *opaque, uint16_t vector)
         qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1);
 }
 
-static void virtio_pci_save_config(void * opaque, QEMUFile *f)
+static void virtio_pci_save_config(void * opaque, Visitor *v, Error **errp)
 {
     VirtIOPCIProxy *proxy = opaque;
-    Visitor *v = qemu_file_get_visitor(f);
     Error *err = NULL;
 
     pci_device_save(&proxy->pci_dev, v, &err);
@@ -119,10 +118,9 @@ static void virtio_pci_save_config(void * opaque, QEMUFile *f)
     }
 }
 
-static void virtio_pci_save_queue(void * opaque, int n, QEMUFile *f)
+static void virtio_pci_save_queue(void * opaque, int n, Visitor *v, Error **errp)
 {
     VirtIOPCIProxy *proxy = opaque;
-    Visitor *v = qemu_file_get_visitor(f);
     Error *err = NULL;
     uint16_t vector;
 
@@ -137,10 +135,9 @@ static void virtio_pci_save_queue(void * opaque, int n, QEMUFile *f)
     }
 }
 
-static int virtio_pci_load_config(void * opaque, QEMUFile *f)
+static int virtio_pci_load_config(void * opaque, Visitor *v, Error **errp)
 {
     VirtIOPCIProxy *proxy = opaque;
-    Visitor *v = qemu_file_get_visitor(f);
     Error *err = NULL;
     int ret;
 
@@ -167,10 +164,9 @@ out:
     return ret;
 }
 
-static int virtio_pci_load_queue(void * opaque, int n, QEMUFile *f)
+static int virtio_pci_load_queue(void * opaque, int n, Visitor *v, Error **errp)
 {
     VirtIOPCIProxy *proxy = opaque;
-    Visitor *v = qemu_file_get_visitor(f);
     Error *err = NULL;
     uint16_t vector;
     int ret = 0;
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 78cd643..97d389f 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -528,7 +528,7 @@ static void virtio_serial_save(QEMUFile *f, void *opaque)
     visit_start_struct(v, NULL, NULL, "virtio_serial", 0, &err);
 
     /* The virtio device */
-    virtio_save(&s->vdev, f);
+    virtio_save(&s->vdev, v, &err);
 
     /* The config space */
     visit_type_uint16(v, &s->config.cols, "config.cols", &err);
@@ -612,7 +612,7 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
     visit_start_struct(v, NULL, NULL, "virtio_serial", 0, &err);
 
     /* The virtio device */
-    virtio_load(&s->vdev, f);
+    virtio_load(&s->vdev, v, &err);
 
     if (version_id < 2) {
         goto out;
diff --git a/hw/virtio.c b/hw/virtio.c
index 0471c54..1791083 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -730,10 +730,9 @@ void virtio_notify_config(VirtIODevice *vdev)
     virtio_notify_vector(vdev, vdev->config_vector);
 }
 
-void virtio_save(VirtIODevice *vdev, QEMUFile *f)
+void virtio_save(VirtIODevice *vdev, Visitor *v, Error **errp)
 {
     int i;
-    Visitor *v = qemu_file_get_visitor(f);
     Error *err = NULL;
     uint8_t *config;
     uint64_t tmp;
@@ -741,7 +740,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
     visit_start_struct(v, NULL, NULL, "vdev", 0, &err);
 
     if (vdev->binding->save_config) {
-        vdev->binding->save_config(vdev->binding_opaque, f);
+        vdev->binding->save_config(vdev->binding_opaque, v, &err);
     }
 
     visit_type_uint8(v, &vdev->status, "status", &err);
@@ -781,7 +780,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
         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);
+            vdev->binding->save_queue(vdev->binding_opaque, i, v, &err);
         }
         
         visit_end_struct(v, &err);
@@ -792,17 +791,16 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
 
     if (err) {
         error_report("error saving virtio state: %s", error_get_pretty(err));
-        error_free(err);
+        error_propagate(errp, err);
     }
 }
 
-int virtio_load(VirtIODevice *vdev, QEMUFile *f)
+int virtio_load(VirtIODevice *vdev, Visitor *v, Error **errp)
 {
     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;
@@ -810,9 +808,9 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
     visit_start_struct(v, NULL, NULL, "vdev", 0, &err);
 
     if (vdev->binding->load_config) {
-        ret = vdev->binding->load_config(vdev->binding_opaque, f);
+        ret = vdev->binding->load_config(vdev->binding_opaque, v, &err);
         if (ret) {
-            return ret;
+            goto out;
         }
     }
 
@@ -823,7 +821,8 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
     if (features & ~supported_features) {
         error_report("Features 0x%x unsupported. Allowed features: 0x%x",
                      features, supported_features);
-        return -1;
+        ret = -1;
+        goto out;
     }
     if (vdev->set_features)
         vdev->set_features(vdev, features);
@@ -862,18 +861,20 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
                              i, vdev->vq[i].vring.num,
                              vring_avail_idx(&vdev->vq[i]),
                              vdev->vq[i].last_avail_idx, nheads);
-                return -1;
+                ret = -1;
+                goto out;
             }
         } else if (vdev->vq[i].last_avail_idx) {
             error_report("VQ %d address 0x0 "
                          "inconsistent with Host index 0x%x",
                          i, vdev->vq[i].last_avail_idx);
-            return -1;
+            ret = -1;
+            goto out;
         }
         if (vdev->binding->load_queue) {
-            ret = vdev->binding->load_queue(vdev->binding_opaque, i, f);
+            ret = vdev->binding->load_queue(vdev->binding_opaque, i, v, &err);
             if (ret) {
-                return ret;
+                goto out;
             }
         }
         visit_end_struct(v, &err);
@@ -882,14 +883,14 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
 
     visit_end_struct(v, &err);
 
+    virtio_notify_vector(vdev, VIRTIO_NO_VECTOR);
+out:
     if (err) {
         error_report("error loading virtio state: %s", error_get_pretty(err));
-        error_free(err);
-        return -1;
+        error_propagate(errp, err);
     }
 
-    virtio_notify_vector(vdev, VIRTIO_NO_VECTOR);
-    return 0;
+    return ret;
 }
 
 void virtio_cleanup(VirtIODevice *vdev)
diff --git a/hw/virtio.h b/hw/virtio.h
index 2d18209..0695606 100644
--- a/hw/virtio.h
+++ b/hw/virtio.h
@@ -93,11 +93,11 @@ typedef struct VirtQueueElement
 
 typedef struct {
     void (*notify)(void * opaque, uint16_t vector);
-    void (*save_config)(void * opaque, QEMUFile *f);
-    void (*save_queue)(void * opaque, int n, QEMUFile *f);
-    int (*load_config)(void * opaque, QEMUFile *f);
-    int (*load_queue)(void * opaque, int n, QEMUFile *f);
-    int (*load_done)(void * opaque, QEMUFile *f);
+    void (*save_config)(void * opaque, Visitor *v, Error **errp);
+    void (*save_queue)(void * opaque, int n, Visitor *v, Error **errp);
+    int (*load_config)(void * opaque, Visitor *v, Error **errp);
+    int (*load_queue)(void * opaque, int n, Visitor *v, Error **errp);
+    int (*load_done)(void * opaque, Visitor *v, Error **errp);
     unsigned (*get_features)(void * opaque);
     bool (*query_guest_notifiers)(void * opaque);
     int (*set_guest_notifiers)(void * opaque, bool assigned);
@@ -152,9 +152,9 @@ int virtqueue_avail_bytes(VirtQueue *vq, int in_bytes, int out_bytes);
 
 void virtio_notify(VirtIODevice *vdev, VirtQueue *vq);
 
-void virtio_save(VirtIODevice *vdev, QEMUFile *f);
+void virtio_save(VirtIODevice *vdev, Visitor *v, Error **errp);
 
-int virtio_load(VirtIODevice *vdev, QEMUFile *f);
+int virtio_load(VirtIODevice *vdev, Visitor *v, Error **errp);
 
 void virtio_cleanup(VirtIODevice *vdev);
 
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2011-10-27 18:23 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-27 18:17 [Qemu-devel] [PATCH 00/13] Convert slirp/ivshmem/virtio save/load to Visitors Michael Roth
2011-10-27 18:17 ` [Qemu-devel] [PATCH 01/13] slirp: convert save/load function to visitor interface Michael Roth
2011-10-27 18:17 ` [Qemu-devel] [PATCH 02/13] ivshmem: convert save/load to visitor Michael Roth
2011-10-27 18:17 ` [Qemu-devel] [PATCH 03/13] virtio-pci: convert save/load to visitors Michael Roth
2011-10-27 18:17 ` [Qemu-devel] [PATCH 04/13] msix: convert save/load to visitors (including interfaces) Michael Roth
2011-10-27 18:17 ` [Qemu-devel] [PATCH 05/13] openpic: convert save/load to visitors Michael Roth
2011-10-27 18:17 ` [Qemu-devel] [PATCH 06/13] i440fx: " Michael Roth
2011-10-27 18:17 ` [Qemu-devel] [PATCH 07/13] pci: convert pci_device_(save|load) interfaces to accept Visitors Michael Roth
2011-10-27 18:17 ` [Qemu-devel] [PATCH 08/13] virtio: convert common virtio save/load to visitors Michael Roth
2011-10-27 18:17 ` [Qemu-devel] [PATCH 09/13] virtio-balloon: convert " Michael Roth
2011-10-27 18:17 ` [Qemu-devel] [PATCH 10/13] virtio-blk: " Michael Roth
2011-10-27 18:17 ` [Qemu-devel] [PATCH 11/13] virtio-net: " Michael Roth
2011-10-27 18:17 ` [Qemu-devel] [PATCH 12/13] virtio-serial: " Michael Roth
2011-10-27 18:17 ` [Qemu-devel] [PATCH 13/13] virtio: convert virtio_save/virtio_load interfaces to accept Visitors Michael Roth

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.