>-----Original Message-----
>From: Steve Sistare <steven.sist...@oracle.com>
>Subject: [PATCH V5 31/38] vfio/iommufd: cpr state
>
>VFIO iommufd devices will need access to ioas_id, devid, and hwpt_id in
>new QEMU at realize time, so add them to CPR state.  Define CprVFIODevice
>as the object which holds the state and is serialized to the vmstate file.
>Define accessors to copy state between VFIODevice and CprVFIODevice.
>
>Signed-off-by: Steve Sistare <steven.sist...@oracle.com>
>---
> include/hw/vfio/vfio-cpr.h |  3 ++
> hw/vfio/cpr-iommufd.c      | 96
>+++++++++++++++++++++++++++++++++++++++++++++-
> hw/vfio/iommufd.c          |  2 +
> 3 files changed, 100 insertions(+), 1 deletion(-)
>
>diff --git a/include/hw/vfio/vfio-cpr.h b/include/hw/vfio/vfio-cpr.h
>index 619af07..f88e4ba 100644
>--- a/include/hw/vfio/vfio-cpr.h
>+++ b/include/hw/vfio/vfio-cpr.h
>@@ -33,6 +33,8 @@ typedef struct VFIOContainerCPR {
> typedef struct VFIODeviceCPR {
>     Error *mdev_blocker;
>     Error *id_blocker;
>+    uint32_t hwpt_id;
>+    uint32_t ioas_id;
> } VFIODeviceCPR;
>
> bool vfio_legacy_cpr_register_container(struct VFIOContainer *container,
>@@ -54,6 +56,7 @@ bool vfio_iommufd_cpr_register_iommufd(struct
>IOMMUFDBackend *be, Error **errp);
> void vfio_iommufd_cpr_unregister_iommufd(struct IOMMUFDBackend *be);
> void vfio_iommufd_cpr_register_device(struct VFIODevice *vbasedev);
> void vfio_iommufd_cpr_unregister_device(struct VFIODevice *vbasedev);
>+void vfio_cpr_load_device(struct VFIODevice *vbasedev);
>
> int vfio_cpr_group_get_device_fd(int d, const char *name);
>
>diff --git a/hw/vfio/cpr-iommufd.c b/hw/vfio/cpr-iommufd.c
>index 3e78265..2eca8a6 100644
>--- a/hw/vfio/cpr-iommufd.c
>+++ b/hw/vfio/cpr-iommufd.c
>@@ -7,6 +7,7 @@
> #include "qemu/osdep.h"
> #include "qapi/error.h"
> #include "hw/vfio/vfio-cpr.h"
>+#include "hw/vfio/vfio-device.h"
> #include "migration/blocker.h"
> #include "migration/cpr.h"
> #include "migration/migration.h"
>@@ -14,7 +15,88 @@
> #include "system/iommufd.h"
> #include "vfio-iommufd.h"
>
>-const VMStateDescription vmstate_cpr_vfio_devices;  /* TBD in a later patch */
>+typedef struct CprVFIODevice {
>+    char *name;
>+    unsigned int namelen;
>+    uint32_t ioas_id;
>+    int devid;
>+    uint32_t hwpt_id;
>+    QLIST_ENTRY(CprVFIODevice) next;
>+} CprVFIODevice;
>+
>+static const VMStateDescription vmstate_cpr_vfio_device = {
>+    .name = "cpr vfio device",
>+    .version_id = 1,
>+    .minimum_version_id = 1,
>+    .fields = (VMStateField[]) {
>+        VMSTATE_UINT32(namelen, CprVFIODevice),
>+        VMSTATE_VBUFFER_ALLOC_UINT32(name, CprVFIODevice, 0, NULL,
>namelen),
>+        VMSTATE_INT32(devid, CprVFIODevice),
>+        VMSTATE_UINT32(ioas_id, CprVFIODevice),
>+        VMSTATE_UINT32(hwpt_id, CprVFIODevice),
>+        VMSTATE_END_OF_LIST()
>+    }
>+};
>+
>+const VMStateDescription vmstate_cpr_vfio_devices = {
>+    .name = CPR_STATE "/vfio devices",
>+    .version_id = 1,
>+    .minimum_version_id = 1,
>+    .fields = (const VMStateField[]){
>+        VMSTATE_QLIST_V(vfio_devices, CprState, 1, vmstate_cpr_vfio_device,
>+                        CprVFIODevice, next),
>+        VMSTATE_END_OF_LIST()
>+    }
>+};
>+
>+static void vfio_cpr_save_device(VFIODevice *vbasedev)
>+{
>+    CprVFIODevice *elem = g_new0(CprVFIODevice, 1);
>+
>+    elem->name = g_strdup(vbasedev->name);
>+    elem->namelen = strlen(vbasedev->name) + 1;
>+    elem->ioas_id = vbasedev->cpr.ioas_id;
>+    elem->devid = vbasedev->devid;
>+    elem->hwpt_id = vbasedev->cpr.hwpt_id;
>+    QLIST_INSERT_HEAD(&cpr_state.vfio_devices, elem, next);
>+}
>+
>+static CprVFIODevice *find_device(const char *name)
>+{
>+    CprVFIODeviceList *head = &cpr_state.vfio_devices;
>+    CprVFIODevice *elem;
>+
>+    QLIST_FOREACH(elem, head, next) {
>+        if (!strcmp(elem->name, name)) {
>+            return elem;
>+        }
>+    }
>+    return NULL;
>+}
>+
>+static void vfio_cpr_delete_device(const char *name)
>+{
>+    CprVFIODevice *elem = find_device(name);
>+
>+    if (elem) {
>+        QLIST_REMOVE(elem, next);
>+        g_free(elem->name);
>+        g_free(elem);
>+    }
>+}
>+
>+static bool vfio_cpr_find_device(VFIODevice *vbasedev)

Better to rename as vfio_cpr_load_device

>+{
>+    CprVFIODevice *elem = find_device(vbasedev->name);
>+
>+    if (elem) {
>+        vbasedev->cpr.ioas_id = elem->ioas_id;
>+        vbasedev->devid = elem->devid;
>+        vbasedev->cpr.hwpt_id = elem->hwpt_id;
>+        return true;
>+    }
>+    return false;
>+}
>
> static bool vfio_cpr_supported(IOMMUFDBackend *be, Error **errp)
> {
>@@ -79,8 +161,20 @@ void
>vfio_iommufd_cpr_unregister_container(VFIOIOMMUFDContainer *container)
>
> void vfio_iommufd_cpr_register_device(VFIODevice *vbasedev)
> {
>+    if (!cpr_is_incoming()) {
>+        vfio_cpr_save_device(vbasedev);
>+    }
> }
>
> void vfio_iommufd_cpr_unregister_device(VFIODevice *vbasedev)
> {
>+    vfio_cpr_delete_device(vbasedev->name);
>+}
>+
>+void vfio_cpr_load_device(VFIODevice *vbasedev)
>+{
>+    if (cpr_is_incoming()) {
>+        bool ret = vfio_cpr_find_device(vbasedev);
>+        g_assert(ret);
>+    }
> }
>diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
>index ff291be..f0d57ea 100644
>--- a/hw/vfio/iommufd.c
>+++ b/hw/vfio/iommufd.c
>@@ -515,6 +515,8 @@ static bool iommufd_cdev_attach(const char *name,
>VFIODevice *vbasedev,
>     const VFIOIOMMUClass *iommufd_vioc =
>
>VFIO_IOMMU_CLASS(object_class_by_name(TYPE_VFIO_IOMMU_IOMMUFD));
>
>+    vfio_cpr_load_device(vbasedev);

This can be open coded.

Thanks
Zhenzhong

>+
>     if (vbasedev->fd < 0) {
>         devfd = iommufd_cdev_getfd(vbasedev->sysfsdev, errp);
>         if (devfd < 0) {
>--
>1.8.3.1


Reply via email to