[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 10/10] vmstate: use visitors
From: |
Michael Roth |
Subject: |
[Qemu-devel] [PATCH 10/10] vmstate: use visitors |
Date: |
Fri, 14 Oct 2011 13:20:02 -0500 |
Signed-off-by: Michael Roth <address@hidden>
---
hw/eeprom93xx.c | 12 +-
hw/fw_cfg.c | 12 +-
hw/hw.h | 4 +-
hw/pci.c | 38 +++--
hw/twl92230.c | 18 ++-
qemu-timer.c | 24 ++-
qemu-timer.h | 5 +
savevm.c | 459 ++++++++++++++++++++++++++++++------------------
target-alpha/machine.c | 13 +-
target-i386/machine.c | 49 ++++--
10 files changed, 407 insertions(+), 227 deletions(-)
diff --git a/hw/eeprom93xx.c b/hw/eeprom93xx.c
index 4c7158d..2d6cbe7 100644
--- a/hw/eeprom93xx.c
+++ b/hw/eeprom93xx.c
@@ -93,14 +93,18 @@ struct _eeprom_t {
This is a Big hack, but it is how the old state did it.
*/
-static int get_uint16_from_uint8(QEMUFile *f, void *pv, size_t size)
+static int get_uint16_from_uint8(Visitor *v, const char *name, void *pv,
+ size_t size, Error **err)
{
- uint16_t *v = pv;
- *v = qemu_get_ubyte(f);
+ uint16_t *v1 = pv;
+ uint8_t v2;
+ visit_type_uint8(v, &v2, NULL, err);
+ *v1 = v2;
return 0;
}
-static void put_unused(QEMUFile *f, void *pv, size_t size)
+static void put_unused(Visitor *v, const char *name, void *pv,
+ size_t size, Error **err)
{
fprintf(stderr, "uint16_from_uint8 is used only for backwards
compatibility.\n");
fprintf(stderr, "Never should be used to write a new state.\n");
diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index 8df265c..8a8033e 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -326,14 +326,18 @@ static void fw_cfg_reset(DeviceState *d)
Or we broke compatibility in the state, or we can't use struct tm
*/
-static int get_uint32_as_uint16(QEMUFile *f, void *pv, size_t size)
+static int get_uint32_as_uint16(Visitor *v, const char *name, void *pv,
+ size_t size, Error **err)
{
- uint32_t *v = pv;
- *v = qemu_get_be16(f);
+ uint32_t *val = pv;
+ uint16_t val2;
+ visit_type_uint16(v, &val2, name, err);
+ *val = val2;
return 0;
}
-static void put_unused(QEMUFile *f, void *pv, size_t size)
+static void put_unused(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
fprintf(stderr, "uint32_as_uint16 is only used for backward
compatibility.\n");
fprintf(stderr, "This functions shouldn't be called.\n");
diff --git a/hw/hw.h b/hw/hw.h
index e6d7c6a..f3138f2 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -303,8 +303,8 @@ typedef struct VMStateDescription VMStateDescription;
struct VMStateInfo {
const char *name;
- int (*get)(QEMUFile *f, void *pv, size_t size);
- void (*put)(QEMUFile *f, void *pv, size_t size);
+ int (*get)(Visitor *v, const char *name, void *pv, size_t size, Error
**err);
+ void (*put)(Visitor *v, const char *name, void *pv, size_t size, Error
**err);
};
enum VMStateFlags {
diff --git a/hw/pci.c b/hw/pci.c
index 749e8d8..e955281 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -334,23 +334,25 @@ int pci_bus_num(PCIBus *s)
return s->parent_dev->config[PCI_SECONDARY_BUS];
}
-static int get_pci_config_device(QEMUFile *f, void *pv, size_t size)
+static int get_pci_config_device(Visitor *v, const char *name, void *pv,
+ size_t size, Error **err)
{
PCIDevice *s = container_of(pv, PCIDevice, config);
- uint8_t *config;
+ uint8_t *config = NULL;
int i;
assert(size == pci_config_size(s));
- config = g_malloc(size);
- qemu_get_buffer(f, config, size);
+ visit_start_array(v, (void **)&config, name, size, 1, err);
for (i = 0; i < size; ++i) {
+ visit_type_uint8(v, &config[i], NULL, err);
if ((config[i] ^ s->config[i]) &
s->cmask[i] & ~s->wmask[i] & ~s->w1cmask[i]) {
g_free(config);
return -EINVAL;
}
}
+ visit_end_array(v, err);
memcpy(s->config, config, size);
pci_update_mappings(s);
@@ -360,11 +362,17 @@ static int get_pci_config_device(QEMUFile *f, void *pv,
size_t size)
}
/* just put buffer */
-static void put_pci_config_device(QEMUFile *f, void *pv, size_t size)
+static void put_pci_config_device(Visitor *v, const char *name, void *pv,
+ size_t size, Error **err)
{
- const uint8_t **v = pv;
+ uint8_t *config = *(uint8_t **)pv;
+ int i;
assert(size == pci_config_size(container_of(pv, PCIDevice, config)));
- qemu_put_buffer(f, *v, size);
+ visit_start_array(v, (void **)&config, name, size, 1, err);
+ for (i = 0; i < size; i++) {
+ visit_type_uint8(v, &config[i], NULL, err);
+ }
+ visit_end_array(v, err);
}
static VMStateInfo vmstate_info_pci_config = {
@@ -373,19 +381,22 @@ static VMStateInfo vmstate_info_pci_config = {
.put = put_pci_config_device,
};
-static int get_pci_irq_state(QEMUFile *f, void *pv, size_t size)
+static int get_pci_irq_state(Visitor *v, const char *name, void *pv,
+ size_t size, Error **err)
{
PCIDevice *s = container_of(pv, PCIDevice, irq_state);
uint32_t irq_state[PCI_NUM_PINS];
int i;
+ visit_start_array(v, NULL, name, PCI_NUM_PINS, 4, err);
for (i = 0; i < PCI_NUM_PINS; ++i) {
- irq_state[i] = qemu_get_be32(f);
+ visit_type_uint32(v, &irq_state[i], NULL, err);
if (irq_state[i] != 0x1 && irq_state[i] != 0) {
fprintf(stderr, "irq state %d: must be 0 or 1.\n",
irq_state[i]);
return -EINVAL;
}
}
+ visit_end_array(v, err);
for (i = 0; i < PCI_NUM_PINS; ++i) {
pci_set_irq_state(s, i, irq_state[i]);
@@ -394,14 +405,19 @@ static int get_pci_irq_state(QEMUFile *f, void *pv,
size_t size)
return 0;
}
-static void put_pci_irq_state(QEMUFile *f, void *pv, size_t size)
+static void put_pci_irq_state(Visitor *v, const char *name, void *pv,
+ size_t size, Error **err)
{
int i;
PCIDevice *s = container_of(pv, PCIDevice, irq_state);
+ uint32_t irq_state;
+ visit_start_array(v, NULL, name, PCI_NUM_PINS, 4, err);
for (i = 0; i < PCI_NUM_PINS; ++i) {
- qemu_put_be32(f, pci_irq_state(s, i));
+ irq_state = pci_irq_state(s, i);
+ visit_type_uint32(v, &irq_state, NULL, err);
}
+ visit_end_array(v, err);
}
static VMStateInfo vmstate_info_pci_irq_state = {
diff --git a/hw/twl92230.c b/hw/twl92230.c
index a75448f..732f2d6 100644
--- a/hw/twl92230.c
+++ b/hw/twl92230.c
@@ -742,17 +742,23 @@ static int menelaus_rx(i2c_slave *i2c)
Or we broke compatibility in the state, or we can't use struct tm
*/
-static int get_int32_as_uint16(QEMUFile *f, void *pv, size_t size)
+static int get_int32_as_uint16(Visitor *v, const char *name, void *pv,
+ size_t size, Error **err)
{
- int *v = pv;
- *v = qemu_get_be16(f);
+ uint32_t *val = pv;
+ uint16_t val2;
+ visit_type_uint16(v, &val2, name, err);
+ *val = val2;
return 0;
}
-static void put_int32_as_uint16(QEMUFile *f, void *pv, size_t size)
+static void put_int32_as_uint16(Visitor *v, const char *name, void *pv,
+ size_t size, Error **err)
{
- int *v = pv;
- qemu_put_be16(f, *v);
+ uint32_t *val = pv;
+ uint16_t val2;
+ visit_type_uint16(v, &val2, name, err);
+ *val = val2;
}
static const VMStateInfo vmstate_hack_int32_as_uint16 = {
diff --git a/qemu-timer.c b/qemu-timer.c
index ad1fc8b..ee241c3 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -629,7 +629,8 @@ void init_clocks(void)
}
/* save a timer */
-void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
+void qemu_put_timer_visitor(Visitor *v, const char *name, QEMUTimer *ts,
+ Error **err)
{
uint64_t expire_time;
@@ -638,14 +639,22 @@ void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
} else {
expire_time = -1;
}
- qemu_put_be64(f, expire_time);
+ visit_type_uint64(v, &expire_time, name, err);
}
-void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
+void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
+{
+ Visitor *v = qemu_file_get_output_visitor(f);
+ assert(v);
+ qemu_put_timer_visitor(v, "timer", ts, NULL);
+}
+
+void qemu_get_timer_visitor(Visitor *v, const char *name, QEMUTimer *ts,
+ Error **err)
{
uint64_t expire_time;
- expire_time = qemu_get_be64(f);
+ visit_type_uint64(v, &expire_time, name, err);
if (expire_time != -1) {
qemu_mod_timer_ns(ts, expire_time);
} else {
@@ -653,6 +662,13 @@ void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
}
}
+void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
+{
+ Visitor *v = qemu_file_get_input_visitor(f);
+ assert(v);
+ qemu_get_timer_visitor(v, "timer", ts, NULL);
+}
+
static const VMStateDescription vmstate_timers = {
.name = "timer",
.version_id = 2,
diff --git a/qemu-timer.h b/qemu-timer.h
index 0a43469..38e4343 100644
--- a/qemu-timer.h
+++ b/qemu-timer.h
@@ -5,6 +5,7 @@
#include "notify.h"
#include <time.h>
#include <sys/time.h>
+#include "qapi/qapi-visit-core.h"
#ifdef _WIN32
#include <windows.h>
@@ -134,7 +135,11 @@ static inline int64_t get_clock(void)
#endif
void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
+void qemu_get_timer_visitor(Visitor *v, const char *name, QEMUTimer *ts,
+ Error **err);
void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
+void qemu_put_timer_visitor(Visitor *v, const char *name, QEMUTimer *ts,
+ Error **err);
/* ptimer.c */
typedef struct ptimer_state ptimer_state;
diff --git a/savevm.c b/savevm.c
index 95135e1..d43b918 100644
--- a/savevm.c
+++ b/savevm.c
@@ -91,6 +91,8 @@
#define ARP_HTYPE_ETH 0x0001
#define ARP_PTYPE_IP 0x0800
#define ARP_OP_REQUEST_REV 0x3
+#define VMS_LOAD true
+#define VMS_SAVE false
static int announce_self_create(uint8_t *buf,
uint8_t *mac_addr)
@@ -182,17 +184,19 @@ static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs,
int is_writable)
/* bool */
-static int get_bool(QEMUFile *f, void *pv, size_t size)
+static int get_bool(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
- bool *v = pv;
- *v = qemu_get_byte(f);
+ bool *val = pv;
+ visit_type_bool(v, val, name, err);
return 0;
}
-static void put_bool(QEMUFile *f, void *pv, size_t size)
+static void put_bool(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
- bool *v = pv;
- qemu_put_byte(f, *v);
+ bool *val = pv;
+ visit_type_bool(v, val, name, err);
}
const VMStateInfo vmstate_info_bool = {
@@ -203,17 +207,19 @@ const VMStateInfo vmstate_info_bool = {
/* 8 bit int */
-static int get_int8(QEMUFile *f, void *pv, size_t size)
+static int get_int8(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
- int8_t *v = pv;
- qemu_get_s8s(f, v);
+ int8_t *val = pv;
+ visit_type_int8(v, val, name, err);
return 0;
}
-static void put_int8(QEMUFile *f, void *pv, size_t size)
+static void put_int8(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
- int8_t *v = pv;
- qemu_put_s8s(f, v);
+ int8_t *val = pv;
+ visit_type_int8(v, val, name, err);
}
const VMStateInfo vmstate_info_int8 = {
@@ -224,17 +230,19 @@ const VMStateInfo vmstate_info_int8 = {
/* 16 bit int */
-static int get_int16(QEMUFile *f, void *pv, size_t size)
+static int get_int16(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
- int16_t *v = pv;
- qemu_get_sbe16s(f, v);
+ int16_t *val = pv;
+ visit_type_int16(v, val, name, err);
return 0;
}
-static void put_int16(QEMUFile *f, void *pv, size_t size)
+static void put_int16(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
- int16_t *v = pv;
- qemu_put_sbe16s(f, v);
+ int16_t *val = pv;
+ visit_type_int16(v, val, name, err);
}
const VMStateInfo vmstate_info_int16 = {
@@ -245,17 +253,19 @@ const VMStateInfo vmstate_info_int16 = {
/* 32 bit int */
-static int get_int32(QEMUFile *f, void *pv, size_t size)
+static int get_int32(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
- int32_t *v = pv;
- qemu_get_sbe32s(f, v);
+ int32_t *val = pv;
+ visit_type_int32(v, val, name, err);
return 0;
}
-static void put_int32(QEMUFile *f, void *pv, size_t size)
+static void put_int32(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
- int32_t *v = pv;
- qemu_put_sbe32s(f, v);
+ int32_t *val = pv;
+ visit_type_int32(v, val, name, err);
}
const VMStateInfo vmstate_info_int32 = {
@@ -267,13 +277,14 @@ const VMStateInfo vmstate_info_int32 = {
/* 32 bit int. See that the received value is the same than the one
in the field */
-static int get_int32_equal(QEMUFile *f, void *pv, size_t size)
+static int get_int32_equal(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
- int32_t *v = pv;
+ int32_t *v1 = pv;
int32_t v2;
- qemu_get_sbe32s(f, &v2);
+ visit_type_int32(v, &v2, name, err);
- if (*v == v2)
+ if (*v1 == v2)
return 0;
return -EINVAL;
}
@@ -287,11 +298,12 @@ const VMStateInfo vmstate_info_int32_equal = {
/* 32 bit int. See that the received value is the less or the same
than the one in the field */
-static int get_int32_le(QEMUFile *f, void *pv, size_t size)
+static int get_int32_le(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
int32_t *old = pv;
int32_t new;
- qemu_get_sbe32s(f, &new);
+ visit_type_int32(v, &new, name, err);
if (*old <= new)
return 0;
@@ -306,17 +318,19 @@ const VMStateInfo vmstate_info_int32_le = {
/* 64 bit int */
-static int get_int64(QEMUFile *f, void *pv, size_t size)
+static int get_int64(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
- int64_t *v = pv;
- qemu_get_sbe64s(f, v);
+ int64_t *val = pv;
+ visit_type_int64(v, val, name, err);
return 0;
}
-static void put_int64(QEMUFile *f, void *pv, size_t size)
+static void put_int64(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
- int64_t *v = pv;
- qemu_put_sbe64s(f, v);
+ int64_t *val = pv;
+ visit_type_int64(v, val, name, err);
}
const VMStateInfo vmstate_info_int64 = {
@@ -327,17 +341,19 @@ const VMStateInfo vmstate_info_int64 = {
/* 8 bit unsigned int */
-static int get_uint8(QEMUFile *f, void *pv, size_t size)
+static int get_uint8(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
- uint8_t *v = pv;
- qemu_get_8s(f, v);
+ uint8_t *val = pv;
+ visit_type_uint8(v, val, name, err);
return 0;
}
-static void put_uint8(QEMUFile *f, void *pv, size_t size)
+static void put_uint8(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
- uint8_t *v = pv;
- qemu_put_8s(f, v);
+ uint8_t *val = pv;
+ visit_type_uint8(v, val, name, err);
}
const VMStateInfo vmstate_info_uint8 = {
@@ -348,17 +364,19 @@ const VMStateInfo vmstate_info_uint8 = {
/* 16 bit unsigned int */
-static int get_uint16(QEMUFile *f, void *pv, size_t size)
+static int get_uint16(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
- uint16_t *v = pv;
- qemu_get_be16s(f, v);
+ uint16_t *val = pv;
+ visit_type_uint16(v, val, name, err);
return 0;
}
-static void put_uint16(QEMUFile *f, void *pv, size_t size)
+static void put_uint16(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
- uint16_t *v = pv;
- qemu_put_be16s(f, v);
+ uint16_t *val = pv;
+ visit_type_uint16(v, val, name, err);
}
const VMStateInfo vmstate_info_uint16 = {
@@ -369,17 +387,19 @@ const VMStateInfo vmstate_info_uint16 = {
/* 32 bit unsigned int */
-static int get_uint32(QEMUFile *f, void *pv, size_t size)
+static int get_uint32(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
- uint32_t *v = pv;
- qemu_get_be32s(f, v);
+ uint32_t *val = pv;
+ visit_type_uint32(v, val, name, err);
return 0;
}
-static void put_uint32(QEMUFile *f, void *pv, size_t size)
+static void put_uint32(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
- uint32_t *v = pv;
- qemu_put_be32s(f, v);
+ uint32_t *val = pv;
+ visit_type_uint32(v, val, name, err);
}
const VMStateInfo vmstate_info_uint32 = {
@@ -391,13 +411,14 @@ const VMStateInfo vmstate_info_uint32 = {
/* 32 bit uint. See that the received value is the same than the one
in the field */
-static int get_uint32_equal(QEMUFile *f, void *pv, size_t size)
+static int get_uint32_equal(Visitor *v, const char *name, void *pv, size_t
size,
+ Error **err)
{
- uint32_t *v = pv;
+ uint32_t *v1 = pv;
uint32_t v2;
- qemu_get_be32s(f, &v2);
+ visit_type_uint32(v, &v2, name, err);
- if (*v == v2) {
+ if (*v1 == v2) {
return 0;
}
return -EINVAL;
@@ -411,17 +432,19 @@ const VMStateInfo vmstate_info_uint32_equal = {
/* 64 bit unsigned int */
-static int get_uint64(QEMUFile *f, void *pv, size_t size)
+static int get_uint64(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
- uint64_t *v = pv;
- qemu_get_be64s(f, v);
+ uint64_t *val = pv;
+ visit_type_uint64(v, val, name, err);
return 0;
}
-static void put_uint64(QEMUFile *f, void *pv, size_t size)
+static void put_uint64(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
- uint64_t *v = pv;
- qemu_put_be64s(f, v);
+ uint64_t *val = pv;
+ visit_type_uint64(v, val, name, err);
}
const VMStateInfo vmstate_info_uint64 = {
@@ -433,13 +456,14 @@ const VMStateInfo vmstate_info_uint64 = {
/* 8 bit int. See that the received value is the same than the one
in the field */
-static int get_uint8_equal(QEMUFile *f, void *pv, size_t size)
+static int get_uint8_equal(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
- uint8_t *v = pv;
+ uint8_t *v1 = pv;
uint8_t v2;
- qemu_get_8s(f, &v2);
+ visit_type_uint8(v, &v2, name, err);
- if (*v == v2)
+ if (*v1 == v2)
return 0;
return -EINVAL;
}
@@ -453,13 +477,14 @@ const VMStateInfo vmstate_info_uint8_equal = {
/* 16 bit unsigned int int. See that the received value is the same than the
one
in the field */
-static int get_uint16_equal(QEMUFile *f, void *pv, size_t size)
+static int get_uint16_equal(Visitor *v, const char *name, void *pv, size_t
size,
+ Error **err)
{
- uint16_t *v = pv;
+ uint16_t *v1 = pv;
uint16_t v2;
- qemu_get_be16s(f, &v2);
+ visit_type_uint16(v, &v2, name, err);
- if (*v == v2)
+ if (*v1 == v2)
return 0;
return -EINVAL;
}
@@ -472,17 +497,19 @@ const VMStateInfo vmstate_info_uint16_equal = {
/* timers */
-static int get_timer(QEMUFile *f, void *pv, size_t size)
+static int get_timer(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
- QEMUTimer *v = pv;
- qemu_get_timer(f, v);
+ QEMUTimer *t = pv;
+ qemu_get_timer_visitor(v, name, t, err);
return 0;
}
-static void put_timer(QEMUFile *f, void *pv, size_t size)
+static void put_timer(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
- QEMUTimer *v = pv;
- qemu_put_timer(f, v);
+ QEMUTimer *t = pv;
+ qemu_put_timer_visitor(v, name, t, err);
}
const VMStateInfo vmstate_info_timer = {
@@ -493,17 +520,29 @@ const VMStateInfo vmstate_info_timer = {
/* uint8_t buffers */
-static int get_buffer(QEMUFile *f, void *pv, size_t size)
+static int get_buffer(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
- uint8_t *v = pv;
- qemu_get_buffer(f, v, size);
+ uint8_t *val = pv;
+ int i;
+ visit_start_array(v, NULL, name, size, 1, err);
+ for (i = 0; i < size; i++) {
+ visit_type_uint8(v, &val[i], NULL, err);
+ }
+ visit_end_array(v, err);
return 0;
}
-static void put_buffer(QEMUFile *f, void *pv, size_t size)
+static void put_buffer(Visitor *v, const char *name, void *pv, size_t size,
+ Error **err)
{
- uint8_t *v = pv;
- qemu_put_buffer(f, v, size);
+ uint8_t *val = pv;
+ int i;
+ visit_start_array(v, NULL, name, size, 1, err);
+ for (i = 0; i < size; i++) {
+ visit_type_uint8(v, &val[i], NULL, err);
+ }
+ visit_end_array(v, err);
}
const VMStateInfo vmstate_info_buffer = {
@@ -515,29 +554,39 @@ const VMStateInfo vmstate_info_buffer = {
/* unused buffers: space that was used for some fields that are
not useful anymore */
-static int get_unused_buffer(QEMUFile *f, void *pv, size_t size)
+static int get_unused_buffer(Visitor *v, const char *name, void *pv,
+ size_t size, Error **err)
{
uint8_t buf[1024];
- int block_len;
+ int block_len, i;
+ visit_start_array(v, NULL, name, size, 1, err);
while (size > 0) {
block_len = MIN(sizeof(buf), size);
size -= block_len;
- qemu_get_buffer(f, buf, block_len);
+ for (i = 0; i < block_len; i++) {
+ visit_type_uint8(v, &buf[i], NULL, err);
+ }
}
+ visit_end_array(v, err);
return 0;
}
-static void put_unused_buffer(QEMUFile *f, void *pv, size_t size)
+static void put_unused_buffer(Visitor *v, const char *name, void *pv,
+ size_t size, Error **err)
{
- static const uint8_t buf[1024];
- int block_len;
+ static uint8_t buf[1024];
+ int block_len, i;
+ visit_start_array(v, NULL, name, size, 1, err);
while (size > 0) {
block_len = MIN(sizeof(buf), size);
size -= block_len;
- qemu_put_buffer(f, buf, block_len);
+ for (i = 0; i < block_len; i++) {
+ visit_type_uint8(v, &buf[i], NULL, err);
+ }
}
+ visit_end_array(v, err);
}
const VMStateInfo vmstate_info_unused_buffer = {
@@ -797,34 +846,59 @@ static void vmstate_subsection_save(QEMUFile *f, const
VMStateDescription *vmsd,
static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque);
-int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
- void *opaque, int version_id)
+static bool vmstate_field_needed(VMStateField *field,
+ const VMStateDescription *vmsd,
+ void *opaque, int version_id, bool load)
+{
+ if (load) {
+ return ((field->field_exists &&
+ field->field_exists(opaque, version_id)) ||
+ (!field->field_exists && field->version_id <= version_id));
+ }
+ return (!field->field_exists ||
+ field->field_exists(opaque, vmsd->version_id));
+}
+
+static int vmstate_process(QEMUFile *f, const VMStateDescription *vmsd,
+ void *opaque, int version_id, bool load)
{
VMStateField *field = vmsd->fields;
int ret;
+ Visitor *v;
+ Error *err = NULL;
- if (version_id > vmsd->version_id) {
- return -EINVAL;
- }
- if (version_id < vmsd->minimum_version_id_old) {
- return -EINVAL;
- }
- if (version_id < vmsd->minimum_version_id) {
- return vmsd->load_state_old(f, opaque, version_id);
- }
- if (vmsd->pre_load) {
- int ret = vmsd->pre_load(opaque);
- if (ret)
- return ret;
+ if (load) {
+ v = qemu_file_get_input_visitor(f);
+ if (version_id > vmsd->version_id) {
+ return -EINVAL;
+ }
+ if (version_id < vmsd->minimum_version_id_old) {
+ return -EINVAL;
+ }
+ if (version_id < vmsd->minimum_version_id) {
+ return vmsd->load_state_old(f, opaque, version_id);
+ }
+ if (vmsd->pre_load) {
+ int ret = vmsd->pre_load(opaque);
+ if (ret) {
+ return ret;
+ }
+ }
+ } else {
+ v = qemu_file_get_output_visitor(f);
+ if (vmsd->pre_save) {
+ vmsd->pre_save(opaque);
+ }
}
+ assert(v);
+
+ visit_start_struct(v, NULL, NULL, vmsd->name, 0, &err);
while(field->name) {
- if ((field->field_exists &&
- field->field_exists(opaque, version_id)) ||
- (!field->field_exists &&
- field->version_id <= version_id)) {
+ if (vmstate_field_needed(field, vmsd, opaque, version_id, load)) {
void *base_addr = opaque + field->offset;
int i, n_elems = 1;
int size = field->size;
+ bool is_array = false;
if (field->flags & VMS_VBUFFER) {
size = *(int32_t *)(opaque+field->size_offset);
@@ -834,14 +908,28 @@ int vmstate_load_state(QEMUFile *f, const
VMStateDescription *vmsd,
}
if (field->flags & VMS_ARRAY) {
n_elems = field->num;
+ visit_start_array(v, NULL, field->name, n_elems, size, &err);
+ is_array = true;
} else if (field->flags & VMS_VARRAY_INT32) {
n_elems = *(int32_t *)(opaque+field->num_offset);
+ visit_start_array(v, NULL, field->name, n_elems,
+ sizeof(int32_t), &err);
+ is_array = true;
} else if (field->flags & VMS_VARRAY_UINT32) {
n_elems = *(uint32_t *)(opaque+field->num_offset);
+ visit_start_array(v, NULL, field->name, n_elems,
+ sizeof(uint32_t), &err);
+ is_array = true;
} else if (field->flags & VMS_VARRAY_UINT16) {
n_elems = *(uint16_t *)(opaque+field->num_offset);
+ visit_start_array(v, NULL, field->name, n_elems,
+ sizeof(uint16_t), &err);
+ is_array = true;
} else if (field->flags & VMS_VARRAY_UINT8) {
n_elems = *(uint8_t *)(opaque+field->num_offset);
+ visit_start_array(v, NULL, field->name, n_elems,
+ sizeof(uint8_t), &err);
+ is_array = true;
}
if (field->flags & VMS_POINTER) {
base_addr = *(void **)base_addr + field->start;
@@ -853,77 +941,62 @@ int vmstate_load_state(QEMUFile *f, const
VMStateDescription *vmsd,
addr = *(void **)addr;
}
if (field->flags & VMS_STRUCT) {
- ret = vmstate_load_state(f, field->vmsd, addr,
field->vmsd->version_id);
+ if (load) {
+ ret = vmstate_load_state(f, field->vmsd, addr,
+ field->vmsd->version_id);
+ } else {
+ vmstate_save_state(f, field->vmsd, addr);
+ }
} else {
- ret = field->info->get(f, addr, size);
-
+ if (load) {
+ ret = field->info->get(v, field->name, addr, size,
&err);
+ } else {
+ field->info->put(v, field->name, addr, size, &err);
+ }
}
- if (ret < 0) {
+ if (load && ret < 0) {
return ret;
}
}
+ if (is_array) {
+ visit_end_array(v, &err);
+ }
}
field++;
}
- ret = vmstate_subsection_load(f, vmsd, opaque);
- if (ret != 0) {
- return ret;
+
+ if (load) {
+ if (error_is_set(&err)) {
+ error_report("error loading state: %s", error_get_pretty(err));
+ error_free(err);
+ return -EINVAL;
+ }
+ ret = vmstate_subsection_load(f, vmsd, opaque);
+ if (ret != 0) {
+ return ret;
+ }
+ } else {
+ vmstate_subsection_save(f, vmsd, opaque);
}
- if (vmsd->post_load) {
+
+ visit_end_struct(v, &err);
+
+ if (load && vmsd->post_load) {
return vmsd->post_load(opaque, version_id);
}
+
return 0;
}
-void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
- void *opaque)
+int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
+ void *opaque, int version_id)
{
- VMStateField *field = vmsd->fields;
-
- if (vmsd->pre_save) {
- vmsd->pre_save(opaque);
- }
- while(field->name) {
- if (!field->field_exists ||
- field->field_exists(opaque, vmsd->version_id)) {
- void *base_addr = opaque + field->offset;
- int i, n_elems = 1;
- int size = field->size;
-
- if (field->flags & VMS_VBUFFER) {
- size = *(int32_t *)(opaque+field->size_offset);
- if (field->flags & VMS_MULTIPLY) {
- size *= field->size;
- }
- }
- if (field->flags & VMS_ARRAY) {
- n_elems = field->num;
- } else if (field->flags & VMS_VARRAY_INT32) {
- n_elems = *(int32_t *)(opaque+field->num_offset);
- } else if (field->flags & VMS_VARRAY_UINT16) {
- n_elems = *(uint16_t *)(opaque+field->num_offset);
- } else if (field->flags & VMS_VARRAY_UINT8) {
- n_elems = *(uint8_t *)(opaque+field->num_offset);
- }
- if (field->flags & VMS_POINTER) {
- base_addr = *(void **)base_addr + field->start;
- }
- for (i = 0; i < n_elems; i++) {
- void *addr = base_addr + size * i;
+ return vmstate_process(f, vmsd, opaque, version_id, VMS_LOAD);
+}
- if (field->flags & VMS_ARRAY_OF_POINTER) {
- addr = *(void **)addr;
- }
- if (field->flags & VMS_STRUCT) {
- vmstate_save_state(f, field->vmsd, addr);
- } else {
- field->info->put(f, addr, size);
- }
- }
- }
- field++;
- }
- vmstate_subsection_save(f, vmsd, opaque);
+void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd, void
*opaque)
+{
+ vmstate_process(f, vmsd, opaque, 0, VMS_SAVE);
}
static int vmstate_load(QEMUFile *f, SaveStateEntry *se, int version_id)
@@ -940,7 +1013,7 @@ static void vmstate_save(QEMUFile *f, SaveStateEntry *se)
se->save_state(f, se->opaque);
return;
}
- vmstate_save_state(f,se->vmsd, se->opaque);
+ vmstate_save_state(f, se->vmsd, se->opaque);
}
#define QEMU_VM_FILE_MAGIC 0x5145564d
@@ -1173,22 +1246,34 @@ static int vmstate_subsection_load(QEMUFile *f, const
VMStateDescription *vmsd,
void *opaque)
{
const VMStateSubsection *sub = vmsd->subsections;
+ uint8_t tag;
+ int i;
+ Visitor *v = qemu_file_get_input_visitor(f);
+ Error *err = NULL;
+ assert(v);
if (!sub || !sub->needed) {
return 0;
}
+ visit_start_list(v, "subsections", &err);
while (qemu_peek_byte(f) == QEMU_VM_SUBSECTION) {
char idstr[256];
int ret;
- uint8_t version_id, len;
+ uint32_t version_id, len;
const VMStateDescription *sub_vmsd;
- qemu_get_byte(f); /* subsection */
- len = qemu_get_byte(f);
- qemu_get_buffer(f, (uint8_t *)idstr, len);
+ visit_start_struct(v, NULL, NULL, NULL, 0, &err);
+
+ visit_type_uint8(v, &tag, "__SUBSECTION__", &err);
+ visit_type_uint8(v, (uint8_t *)&len, "len", &err);
+ visit_start_array(v, NULL, "name", len, 1, &err);
+ for (i = 0; i < len; i++) {
+ visit_type_uint8(v, (uint8_t *)&idstr[i], NULL, &err);
+ }
+ visit_end_array(v, &err);
idstr[len] = 0;
- version_id = qemu_get_be32(f);
+ visit_type_uint32(v, &version_id, "version_id", &err);
sub_vmsd = vmstate_get_subsection(sub, idstr);
if (sub_vmsd == NULL) {
@@ -1199,6 +1284,15 @@ static int vmstate_subsection_load(QEMUFile *f, const
VMStateDescription *vmsd,
if (ret) {
return ret;
}
+
+ visit_end_struct(v, &err);
+ }
+ visit_end_list(v, &err);
+
+ if (error_is_set(&err)) {
+ error_report("error loading subsections: %s", error_get_pretty(err));
+ error_free(err);
+ return -EINVAL;
}
return 0;
}
@@ -1207,22 +1301,37 @@ static void vmstate_subsection_save(QEMUFile *f, const
VMStateDescription *vmsd,
void *opaque)
{
const VMStateSubsection *sub = vmsd->subsections;
+ uint8_t tag = QEMU_VM_SUBSECTION;
+ int i;
+ Visitor *v = qemu_file_get_output_visitor(f);
+ Error *err = NULL;
+ assert(v);
+ visit_start_list(v, "subsections", &err);
while (sub && sub->needed) {
if (sub->needed(opaque)) {
const VMStateDescription *vmsd = sub->vmsd;
uint8_t len;
- qemu_put_byte(f, QEMU_VM_SUBSECTION);
+ visit_start_struct(v, NULL, NULL, NULL, 0, &err);
+
+ visit_type_uint8(v, &tag, "__SUBSECTION__", &err);
len = strlen(vmsd->name);
- qemu_put_byte(f, len);
- qemu_put_buffer(f, (uint8_t *)vmsd->name, len);
- qemu_put_be32(f, vmsd->version_id);
+ visit_type_uint8(v, &len, "len", &err);
+ visit_start_array(v, (void **)&vmsd->name, "name", len, 1, &err);
+ for (i = 0; i < len; i++) {
+ visit_type_uint8(v, (uint8_t *)&vmsd->name[i], NULL, &err);
+ }
+ visit_end_array(v, &err);
+ visit_type_uint32(v, (uint32_t *)&vmsd->version_id, "version_id",
&err);
assert(!vmsd->subsections);
vmstate_save_state(f, vmsd, opaque);
+
+ visit_end_struct(v, &err);
}
sub++;
}
+ visit_end_list(v, &err);
}
typedef struct LoadStateEntry {
diff --git a/target-alpha/machine.c b/target-alpha/machine.c
index 76d70d9..4e6c549 100644
--- a/target-alpha/machine.c
+++ b/target-alpha/machine.c
@@ -1,17 +1,22 @@
#include "hw/hw.h"
#include "hw/boards.h"
-static int get_fpcr(QEMUFile *f, void *opaque, size_t size)
+static int get_fpcr(Visitor *v, const char *name, void *opaque,
+ size_t size, Error **err)
{
CPUAlphaState *env = opaque;
- cpu_alpha_store_fpcr(env, qemu_get_be64(f));
+ uint64_t fpcr;
+ visit_type_uint64(v, &fpcr, name, err);
+ cpu_alpha_store_fpcr(env, fpcr);
return 0;
}
-static void put_fpcr(QEMUFile *f, void *opaque, size_t size)
+static void put_fpcr(Visitor *v, const char *name, void *opaque,
+ size_t size, Error **err)
{
CPUAlphaState *env = opaque;
- qemu_put_be64(f, cpu_alpha_load_fpcr(env));
+ uint64_t fpcr = cpu_alpha_load_fpcr(env);
+ visit_type_uint64(v, &fpcr, name, err);
}
static const VMStateInfo vmstate_fpcr = {
diff --git a/target-i386/machine.c b/target-i386/machine.c
index 25fa97d..1a4281c 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -78,7 +78,8 @@ static const VMStateDescription vmstate_mtrr_var = {
#define VMSTATE_MTRR_VARS(_field, _state, _n, _v) \
VMSTATE_STRUCT_ARRAY(_field, _state, _n, _v, vmstate_mtrr_var, MTRRVar)
-static void put_fpreg_error(QEMUFile *f, void *opaque, size_t size)
+static void put_fpreg_error(Visitor *v, const char *name, void *opaque,
+ size_t size, Error **err)
{
fprintf(stderr, "call put_fpreg() with invalid arguments\n");
exit(0);
@@ -106,19 +107,23 @@ static void fp64_to_fp80(union x86_longdouble *p,
uint64_t temp)
p->exp = e;
}
-static int get_fpreg(QEMUFile *f, void *opaque, size_t size)
+static int get_fpreg(Visitor *v, const char *name, void *opaque,
+ size_t size, Error **err)
{
FPReg *fp_reg = opaque;
uint64_t mant;
uint16_t exp;
- qemu_get_be64s(f, &mant);
- qemu_get_be16s(f, &exp);
+ visit_start_struct(v, NULL, NULL, name, 0, err);
+ visit_type_uint64(v, &mant, "mant", err);
+ visit_type_uint16(v, &exp, "exp", err);
+ visit_end_struct(v, err);
fp_reg->d = cpu_set_fp80(mant, exp);
return 0;
}
-static void put_fpreg(QEMUFile *f, void *opaque, size_t size)
+static void put_fpreg(Visitor *v, const char *name, void *opaque,
+ size_t size, Error **err)
{
FPReg *fp_reg = opaque;
uint64_t mant;
@@ -126,8 +131,10 @@ static void put_fpreg(QEMUFile *f, void *opaque, size_t
size)
/* we save the real CPU data (in case of MMX usage only 'mant'
contains the MMX register */
cpu_get_fp80(&mant, &exp, fp_reg->d);
- qemu_put_be64s(f, &mant);
- qemu_put_be16s(f, &exp);
+ visit_start_struct(v, NULL, NULL, name, 0, err);
+ visit_type_uint64(v, &mant, "mant", err);
+ visit_type_uint16(v, &exp, "exp", err);
+ visit_end_struct(v, err);
}
static const VMStateInfo vmstate_fpreg = {
@@ -136,12 +143,13 @@ static const VMStateInfo vmstate_fpreg = {
.put = put_fpreg,
};
-static int get_fpreg_1_mmx(QEMUFile *f, void *opaque, size_t size)
+static int get_fpreg_1_mmx(Visitor *v, const char *name, void *opaque,
+ size_t size, Error **err)
{
union x86_longdouble *p = opaque;
uint64_t mant;
- qemu_get_be64s(f, &mant);
+ visit_type_uint64(v, &mant, name, err);
p->mant = mant;
p->exp = 0xffff;
return 0;
@@ -153,12 +161,13 @@ static const VMStateInfo vmstate_fpreg_1_mmx = {
.put = put_fpreg_error,
};
-static int get_fpreg_1_no_mmx(QEMUFile *f, void *opaque, size_t size)
+static int get_fpreg_1_no_mmx(Visitor *v, const char *name, void *opaque,
+ size_t size, Error **err)
{
union x86_longdouble *p = opaque;
uint64_t mant;
- qemu_get_be64s(f, &mant);
+ visit_type_uint64(v, &mant, name, err);
fp64_to_fp80(p, mant);
return 0;
}
@@ -212,17 +221,23 @@ static bool less_than_7(void *opaque, int version_id)
return version_id < 7;
}
-static int get_uint64_as_uint32(QEMUFile *f, void *pv, size_t size)
+static int get_uint64_as_uint32(Visitor *v, const char *name, void *pv,
+ size_t size, Error **err)
{
- uint64_t *v = pv;
- *v = qemu_get_be32(f);
+ uint64_t *val1 = pv;
+ uint32_t val2;
+ visit_type_uint32(v, &val2, name, err);
+ *val1 = val2;
return 0;
}
-static void put_uint64_as_uint32(QEMUFile *f, void *pv, size_t size)
+static void put_uint64_as_uint32(Visitor *v, const char *name, void *pv,
+ size_t size, Error **err)
{
- uint64_t *v = pv;
- qemu_put_be32(f, *v);
+ uint64_t *val1 = pv;
+ uint32_t val2;
+ visit_type_uint32(v, &val2, name, err);
+ *val1 = val2;
}
static const VMStateInfo vmstate_hack_uint64_as_uint32 = {
--
1.7.4.1
- [Qemu-devel] [PATCH 00/10] do savevm/migration save/load via Visitor interface, Michael Roth, 2011/10/14
- [Qemu-devel] [PATCH 02/10] qapi: add QemuFileOutputVisitor, Michael Roth, 2011/10/14
- [Qemu-devel] [PATCH 03/10] qapi: add QemuFileInputVisitor, Michael Roth, 2011/10/14
- [Qemu-devel] [PATCH 01/10] qapi: add Visitor interfaces for uint*_t and int*_t, Michael Roth, 2011/10/14
- [Qemu-devel] [PATCH 04/10] savevm: move QEMUFile interfaces into qemu-file.c, Michael Roth, 2011/10/14
- [Qemu-devel] [PATCH 06/10] savevm: add QEMUFile->visitor lookup routines, Michael Roth, 2011/10/14
- [Qemu-devel] [PATCH 05/10] qapi: test cases for QEMUFile input/output visitors, Michael Roth, 2011/10/14
- [Qemu-devel] [PATCH 08/10] trace: add trace statements for visitor interface, Michael Roth, 2011/10/14
- [Qemu-devel] [PATCH 09/10] qapi: add trace statements to qapi-visit-core.c, Michael Roth, 2011/10/14
- [Qemu-devel] [PATCH 07/10] trace: qemu_(put|get)_(byte|buffer) events, Michael Roth, 2011/10/14
- [Qemu-devel] [PATCH 10/10] vmstate: use visitors,
Michael Roth <=