diff mbox series

[RFC,1/2] virtio: new post_load hook

Message ID 20191010180412.26236-1-mst@redhat.com (mailing list archive)
State New, archived
Headers show
Series [RFC,1/2] virtio: new post_load hook | expand

Commit Message

Michael S. Tsirkin Oct. 10, 2019, 6:04 p.m. UTC
Post load hook in virtio vmsd is called early while device is processed,
and when VirtIODevice core isn't fully initialized.  Most device
specific code isn't ready to deal with a device in such state, and
behaves weirdly.

Add a new post_load hook in a device class instead.  Devices should use
this unless they specifically want to verify the migration stream as
it's processed, e.g. for bounds checking.

Suggested-by: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Cc: Mikhail Sennikovsky <mikhail.sennikovskii@cloud.ionos.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/virtio/virtio.c         | 7 +++++++
 include/hw/virtio/virtio.h | 6 ++++++
 2 files changed, 13 insertions(+)

Comments

Alex Bennée Oct. 11, 2019, 1:15 p.m. UTC | #1
Michael S. Tsirkin <mst@redhat.com> writes:

> Post load hook in virtio vmsd is called early while device is processed,
> and when VirtIODevice core isn't fully initialized.  Most device
> specific code isn't ready to deal with a device in such state, and
> behaves weirdly.
>
> Add a new post_load hook in a device class instead.  Devices should use
> this unless they specifically want to verify the migration stream as
> it's processed, e.g. for bounds checking.
>
> Suggested-by: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> Cc: Mikhail Sennikovsky <mikhail.sennikovskii@cloud.ionos.com>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> ---
>  hw/virtio/virtio.c         | 7 +++++++
>  include/hw/virtio/virtio.h | 6 ++++++
>  2 files changed, 13 insertions(+)
>
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 527df03bfd..54a46e204c 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -2291,6 +2291,13 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
>      }
>      rcu_read_unlock();
>
> +    if (vdc->post_load) {
> +        ret = vdc->post_load(vdev);
> +        if (ret) {
> +            return ret;
> +        }

I see this pattern repeated above because we get early exits on error
but here it seems superfluous. Why not:

    return vdc->_post_load(vdev)

?


> +    }
> +
>      return 0;
>  }
>
> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> index 48e8d04ff6..ca4f9c0bcc 100644
> --- a/include/hw/virtio/virtio.h
> +++ b/include/hw/virtio/virtio.h
> @@ -158,6 +158,12 @@ typedef struct VirtioDeviceClass {
>       */
>      void (*save)(VirtIODevice *vdev, QEMUFile *f);
>      int (*load)(VirtIODevice *vdev, QEMUFile *f, int version_id);
> +    /* Post load hook in vmsd is called early while device is processed, and
> +     * when VirtIODevice isn't fully initialized.  Devices should use this instead,
> +     * unless they specifically want to verify the migration stream as it's
> +     * processed, e.g. for bounds checking.
> +     */
> +    int (*post_load)(VirtIODevice *vdev);
>      const VMStateDescription *vmsd;
>  } VirtioDeviceClass;


--
Alex Bennée
diff mbox series

Patch

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 527df03bfd..54a46e204c 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -2291,6 +2291,13 @@  int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
     }
     rcu_read_unlock();
 
+    if (vdc->post_load) {
+        ret = vdc->post_load(vdev);
+        if (ret) {
+            return ret;
+        }
+    }
+
     return 0;
 }
 
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 48e8d04ff6..ca4f9c0bcc 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -158,6 +158,12 @@  typedef struct VirtioDeviceClass {
      */
     void (*save)(VirtIODevice *vdev, QEMUFile *f);
     int (*load)(VirtIODevice *vdev, QEMUFile *f, int version_id);
+    /* Post load hook in vmsd is called early while device is processed, and
+     * when VirtIODevice isn't fully initialized.  Devices should use this instead,
+     * unless they specifically want to verify the migration stream as it's
+     * processed, e.g. for bounds checking.
+     */
+    int (*post_load)(VirtIODevice *vdev);
     const VMStateDescription *vmsd;
 } VirtioDeviceClass;