* David Hildenbrand (david@xxxxxxxxxx) wrote: > We want to make sure that certain properties don't change during > migration, especially to catch user errors in a nice way. Let's migrate > a temporary structure and validate that the properties didn't change. > > Cc: "Michael S. Tsirkin" <mst@xxxxxxxxxx> > Cc: "Dr. David Alan Gilbert" <dgilbert@xxxxxxxxxx> > Signed-off-by: David Hildenbrand <david@xxxxxxxxxx> Yep OK, but some comment below Reviewed-by: Dr. David Alan Gilbert <dgilbert@xxxxxxxxxx> > --- > hw/virtio/virtio-mem.c | 69 ++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 69 insertions(+) > > diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c > index 2df33f9125..450b8dc49d 100644 > --- a/hw/virtio/virtio-mem.c > +++ b/hw/virtio/virtio-mem.c > @@ -519,12 +519,81 @@ static int virtio_mem_post_load(void *opaque, int version_id) > return virtio_mem_restore_unplugged(VIRTIO_MEM(opaque)); > } > > +typedef struct VirtIOMEMMigSanityChecks { > + VirtIOMEM *parent; > + uint64_t addr; > + uint64_t region_size; > + uint64_t block_size; > + uint32_t node; > +} VirtIOMEMMigSanityChecks; > + > +static int virtio_mem_mig_sanity_checks_pre_save(void *opaque) > +{ > + VirtIOMEMMigSanityChecks *tmp = opaque; > + VirtIOMEM *vmem = tmp->parent; > + > + tmp->addr = vmem->addr; > + tmp->region_size = memory_region_size(&vmem->memdev->mr); > + tmp->block_size = vmem->block_size; > + tmp->node = vmem->node; > + return 0; > +} > + > +static int virtio_mem_mig_sanity_checks_post_load(void *opaque, int version_id) > +{ > + VirtIOMEMMigSanityChecks *tmp = opaque; > + VirtIOMEM *vmem = tmp->parent; > + const uint64_t new_region_size = memory_region_size(&vmem->memdev->mr); > + > + if (tmp->addr != vmem->addr) { > + error_report("Property '%s' changed from 0x%" PRIx64 " to 0x%" PRIx64, > + VIRTIO_MEM_ADDR_PROP, tmp->addr, vmem->addr); > + return -EINVAL; > + } It seems weird that you do 'Property ...' and then the string; although you only do it for 3 out of 4. I was going to ask you to include the device name here, but I'm guessing when it fails the outer migration code will print a 'Failed loading device.....' so at least you know what it is. I would want it to be obvious when I see a 'region size changed' that I knew it was my virtio-mem device that was screwy. Dave > + /* > + * Note: Preparation for resizeable memory regions. The maximum size > + * of the memory region must not change during migration. > + */ > + if (tmp->region_size != new_region_size) { > + error_report("region size changed from 0x%" PRIx64 " to 0x%" PRIx64, > + tmp->region_size, new_region_size); > + return -EINVAL; > + } > + if (tmp->block_size != vmem->block_size) { > + error_report("Property '%s' changed from 0x%" PRIx64 " to 0x%" PRIx64, > + VIRTIO_MEM_BLOCK_SIZE_PROP, tmp->block_size, > + vmem->block_size); > + return -EINVAL; > + } > + if (tmp->node != vmem->node) { > + error_report("Property '%s' changed from %" PRIu32 " to %" PRIu32, > + VIRTIO_MEM_NODE_PROP, tmp->node, vmem->node); > + return -EINVAL; > + } > + return 0; > +} > + > +static const VMStateDescription vmstate_virtio_mem_sanity_checks = { > + .name = "virtio-mem-device/sanity-checks", > + .pre_save = virtio_mem_mig_sanity_checks_pre_save, > + .post_load = virtio_mem_mig_sanity_checks_post_load, > + .fields = (VMStateField[]) { > + VMSTATE_UINT64(addr, VirtIOMEMMigSanityChecks), > + VMSTATE_UINT64(region_size, VirtIOMEMMigSanityChecks), > + VMSTATE_UINT64(block_size, VirtIOMEMMigSanityChecks), > + VMSTATE_UINT32(node, VirtIOMEMMigSanityChecks), > + VMSTATE_END_OF_LIST(), > + }, > +}; > + > static const VMStateDescription vmstate_virtio_mem_device = { > .name = "virtio-mem-device", > .minimum_version_id = 1, > .version_id = 1, > .post_load = virtio_mem_post_load, > .fields = (VMStateField[]) { > + VMSTATE_WITH_TMP(VirtIOMEM, VirtIOMEMMigSanityChecks, > + vmstate_virtio_mem_sanity_checks), > VMSTATE_UINT64(usable_region_size, VirtIOMEM), > VMSTATE_UINT64(size, VirtIOMEM), > VMSTATE_UINT64(requested_size, VirtIOMEM), > -- > 2.26.2 > -- Dr. David Alan Gilbert / dgilbert@xxxxxxxxxx / Manchester, UK