mirror of https://github.com/xemu-project/xemu.git
Fix virtio migration
I misunderstood the vmstate macro definition when I reworked the virtio .get/.put. The VMSTATE_STRUCT_VARRAY_KNOWN, was described as being for "a variable length array (i.e. _type *_field) but we know the length". However it actually specified operation for arrays embedded in the struct (i.e. _type _field[]) since it lacked the VMS_POINTER flag. This caused offset calculation to be completely off, examining and potentially sending random data instead of the VirtQueue content. Replace the otherwise unused VMSTATE_STRUCT_VARRAY_KNOWN with a VMSTATE_STRUCT_VARRAY_POINTER_KNOWN that includes the VMS_POINTER flag (so now actually doing what it advertises) and use it in the virtio migration code. Fixes and description as per Sascha's suggestions/debug. Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Reported-by: Sascha Silbe <silbe@linux.vnet.ibm.com> Tested-By: Sascha Silbe <silbe@linux.vnet.ibm.com> Reviewed-By: Sascha Silbe <silbe@linux.vnet.ibm.com> Fixes:50e5ae4dc3
Fixes:2cf0148674
Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Tested-by: Cornelia Huck <cornelia.huck@de.ibm.com>
This commit is contained in:
parent
382d34ff9f
commit
3e996cc583
|
@ -1143,8 +1143,8 @@ static const VMStateDescription vmstate_virtio_virtqueues = {
|
|||
.minimum_version_id = 1,
|
||||
.needed = &virtio_virtqueue_needed,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_STRUCT_VARRAY_KNOWN(vq, struct VirtIODevice, VIRTIO_QUEUE_MAX,
|
||||
0, vmstate_virtqueue, VirtQueue),
|
||||
VMSTATE_STRUCT_VARRAY_POINTER_KNOWN(vq, struct VirtIODevice,
|
||||
VIRTIO_QUEUE_MAX, 0, vmstate_virtqueue, VirtQueue),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
@ -1165,8 +1165,8 @@ static const VMStateDescription vmstate_virtio_ringsize = {
|
|||
.minimum_version_id = 1,
|
||||
.needed = &virtio_ringsize_needed,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_STRUCT_VARRAY_KNOWN(vq, struct VirtIODevice, VIRTIO_QUEUE_MAX,
|
||||
0, vmstate_ringsize, VirtQueue),
|
||||
VMSTATE_STRUCT_VARRAY_POINTER_KNOWN(vq, struct VirtIODevice,
|
||||
VIRTIO_QUEUE_MAX, 0, vmstate_ringsize, VirtQueue),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
|
|
@ -386,19 +386,6 @@ extern const VMStateInfo vmstate_info_bitmap;
|
|||
.offset = vmstate_offset_array(_state, _field, _type, _num),\
|
||||
}
|
||||
|
||||
/* a variable length array (i.e. _type *_field) but we know the
|
||||
* length
|
||||
*/
|
||||
#define VMSTATE_STRUCT_VARRAY_KNOWN(_field, _state, _num, _version, _vmsd, _type) { \
|
||||
.name = (stringify(_field)), \
|
||||
.num = (_num), \
|
||||
.version_id = (_version), \
|
||||
.vmsd = &(_vmsd), \
|
||||
.size = sizeof(_type), \
|
||||
.flags = VMS_STRUCT|VMS_ARRAY, \
|
||||
.offset = offsetof(_state, _field), \
|
||||
}
|
||||
|
||||
#define VMSTATE_STRUCT_VARRAY_UINT8(_field, _state, _field_num, _version, _vmsd, _type) { \
|
||||
.name = (stringify(_field)), \
|
||||
.num_offset = vmstate_offset_value(_state, _field_num, uint8_t), \
|
||||
|
@ -409,6 +396,19 @@ extern const VMStateInfo vmstate_info_bitmap;
|
|||
.offset = offsetof(_state, _field), \
|
||||
}
|
||||
|
||||
/* a variable length array (i.e. _type *_field) but we know the
|
||||
* length
|
||||
*/
|
||||
#define VMSTATE_STRUCT_VARRAY_POINTER_KNOWN(_field, _state, _num, _version, _vmsd, _type) { \
|
||||
.name = (stringify(_field)), \
|
||||
.num = (_num), \
|
||||
.version_id = (_version), \
|
||||
.vmsd = &(_vmsd), \
|
||||
.size = sizeof(_type), \
|
||||
.flags = VMS_STRUCT|VMS_ARRAY|VMS_POINTER, \
|
||||
.offset = offsetof(_state, _field), \
|
||||
}
|
||||
|
||||
#define VMSTATE_STRUCT_VARRAY_POINTER_INT32(_field, _state, _field_num, _vmsd, _type) { \
|
||||
.name = (stringify(_field)), \
|
||||
.version_id = 0, \
|
||||
|
|
Loading…
Reference in New Issue