aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/migration/vmstate.h11
-rw-r--r--vmstate.c13
2 files changed, 21 insertions, 3 deletions
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index 71a8a95641..9a001bd28f 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -101,6 +101,7 @@ enum VMStateFlags {
VMS_VARRAY_UINT8 = 0x400, /* Array with size in uint8_t field*/
VMS_VARRAY_UINT32 = 0x800, /* Array with size in uint32_t field*/
VMS_MUST_EXIST = 0x1000, /* Field must exist in input */
+ VMS_ALLOC = 0x2000, /* Alloc a buffer on the destination */
};
typedef struct {
@@ -429,6 +430,16 @@ extern const VMStateInfo vmstate_info_bitmap;
.offset = offsetof(_state, _field), \
}
+#define VMSTATE_STRUCT_VARRAY_ALLOC(_field, _state, _field_num, _version, _vmsd, _type) {\
+ .name = (stringify(_field)), \
+ .version_id = (_version), \
+ .vmsd = &(_vmsd), \
+ .num_offset = vmstate_offset_value(_state, _field_num, int32_t), \
+ .size = sizeof(_type), \
+ .flags = VMS_STRUCT|VMS_VARRAY_INT32|VMS_ALLOC|VMS_POINTER, \
+ .offset = vmstate_offset_pointer(_state, _field, _type), \
+}
+
#define VMSTATE_STATIC_BUFFER(_field, _state, _version, _test, _start, _size) { \
.name = (stringify(_field)), \
.version_id = (_version), \
diff --git a/vmstate.c b/vmstate.c
index c9965205df..ef2f87bdad 100644
--- a/vmstate.c
+++ b/vmstate.c
@@ -43,11 +43,18 @@ static int vmstate_size(void *opaque, VMStateField *field)
return size;
}
-static void *vmstate_base_addr(void *opaque, VMStateField *field)
+static void *vmstate_base_addr(void *opaque, VMStateField *field, bool alloc)
{
void *base_addr = opaque + field->offset;
if (field->flags & VMS_POINTER) {
+ if (alloc && (field->flags & VMS_ALLOC)) {
+ int n_elems = vmstate_n_elems(opaque, field);
+ if (n_elems) {
+ gsize size = n_elems * field->size;
+ *((void **)base_addr + field->start) = g_malloc(size);
+ }
+ }
base_addr = *(void **)base_addr + field->start;
}
@@ -81,7 +88,7 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
field->field_exists(opaque, version_id)) ||
(!field->field_exists &&
field->version_id <= version_id)) {
- void *base_addr = vmstate_base_addr(opaque, field);
+ void *base_addr = vmstate_base_addr(opaque, field, true);
int i, n_elems = vmstate_n_elems(opaque, field);
int size = vmstate_size(opaque, field);
@@ -135,7 +142,7 @@ void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
while (field->name) {
if (!field->field_exists ||
field->field_exists(opaque, vmsd->version_id)) {
- void *base_addr = vmstate_base_addr(opaque, field);
+ void *base_addr = vmstate_base_addr(opaque, field, false);
int i, n_elems = vmstate_n_elems(opaque, field);
int size = vmstate_size(opaque, field);