[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v8 05/13] vfio: Add migration region initialization
From: |
Kirti Wankhede |
Subject: |
[Qemu-devel] [PATCH v8 05/13] vfio: Add migration region initialization and finalize function |
Date: |
Tue, 27 Aug 2019 00:25:45 +0530 |
- Migration functions are implemented for VFIO_DEVICE_TYPE_PCI device in this
patch series.
- VFIO device supports migration or not is decided based of migration region
query. If migration region query is successful and migration region
initialization is successful then migration is supported else migration is
blocked.
Signed-off-by: Kirti Wankhede <address@hidden>
Reviewed-by: Neo Jia <address@hidden>
---
hw/vfio/Makefile.objs | 2 +-
hw/vfio/migration.c | 140 ++++++++++++++++++++++++++++++++++++++++++
hw/vfio/trace-events | 3 +
include/hw/vfio/vfio-common.h | 11 ++++
4 files changed, 155 insertions(+), 1 deletion(-)
create mode 100644 hw/vfio/migration.c
diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs
index abad8b818c9b..36033d1437c5 100644
--- a/hw/vfio/Makefile.objs
+++ b/hw/vfio/Makefile.objs
@@ -1,4 +1,4 @@
-obj-y += common.o spapr.o
+obj-y += common.o spapr.o migration.o
obj-$(CONFIG_VFIO_PCI) += pci.o pci-quirks.o display.o
obj-$(CONFIG_VFIO_CCW) += ccw.o
obj-$(CONFIG_VFIO_PLATFORM) += platform.o
diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
new file mode 100644
index 000000000000..a1feeb7e1a5a
--- /dev/null
+++ b/hw/vfio/migration.c
@@ -0,0 +1,140 @@
+/*
+ * Migration support for VFIO devices
+ *
+ * Copyright NVIDIA, Inc. 2019
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include <linux/vfio.h>
+
+#include "hw/vfio/vfio-common.h"
+#include "cpu.h"
+#include "migration/migration.h"
+#include "migration/qemu-file.h"
+#include "migration/register.h"
+#include "migration/blocker.h"
+#include "migration/misc.h"
+#include "qapi/error.h"
+#include "exec/ramlist.h"
+#include "exec/ram_addr.h"
+#include "pci.h"
+#include "trace.h"
+
+static void vfio_migration_region_exit(VFIODevice *vbasedev)
+{
+ VFIOMigration *migration = vbasedev->migration;
+
+ if (!migration) {
+ return;
+ }
+
+ if (migration->region.size) {
+ vfio_region_exit(&migration->region);
+ vfio_region_finalize(&migration->region);
+ }
+}
+
+static int vfio_migration_region_init(VFIODevice *vbasedev, int index)
+{
+ VFIOMigration *migration = vbasedev->migration;
+ Object *obj = NULL;
+ int ret = -EINVAL;
+
+ if (!vbasedev->ops || !vbasedev->ops->vfio_get_object) {
+ return ret;
+ }
+
+ obj = vbasedev->ops->vfio_get_object(vbasedev);
+ if (!obj) {
+ return ret;
+ }
+
+ ret = vfio_region_setup(obj, vbasedev, &migration->region, index,
+ "migration");
+ if (ret) {
+ error_report("%s: Failed to setup VFIO migration region %d: %s",
+ vbasedev->name, index, strerror(-ret));
+ goto err;
+ }
+
+ if (!migration->region.size) {
+ ret = -EINVAL;
+ error_report("%s: Invalid region size of VFIO migration region %d: %s",
+ vbasedev->name, index, strerror(-ret));
+ goto err;
+ }
+
+ return 0;
+
+err:
+ vfio_migration_region_exit(vbasedev);
+ return ret;
+}
+
+static int vfio_migration_init(VFIODevice *vbasedev,
+ struct vfio_region_info *info)
+{
+ int ret;
+
+ vbasedev->migration = g_new0(VFIOMigration, 1);
+
+ ret = vfio_migration_region_init(vbasedev, info->index);
+ if (ret) {
+ error_report("%s: Failed to initialise migration region",
+ vbasedev->name);
+ g_free(vbasedev->migration);
+ return ret;
+ }
+
+ return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int vfio_migration_probe(VFIODevice *vbasedev, Error **errp)
+{
+ struct vfio_region_info *info;
+ Error *local_err = NULL;
+ int ret;
+
+ ret = vfio_get_dev_region_info(vbasedev, VFIO_REGION_TYPE_MIGRATION,
+ VFIO_REGION_SUBTYPE_MIGRATION, &info);
+ if (ret) {
+ goto add_blocker;
+ }
+
+ ret = vfio_migration_init(vbasedev, info);
+ if (ret) {
+ goto add_blocker;
+ }
+
+ trace_vfio_migration_probe(vbasedev->name, info->index);
+ return 0;
+
+add_blocker:
+ error_setg(&vbasedev->migration_blocker,
+ "VFIO device doesn't support migration");
+ ret = migrate_add_blocker(vbasedev->migration_blocker, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ error_free(vbasedev->migration_blocker);
+ }
+ return ret;
+}
+
+void vfio_migration_finalize(VFIODevice *vbasedev)
+{
+ if (vbasedev->migration_blocker) {
+ migrate_del_blocker(vbasedev->migration_blocker);
+ error_free(vbasedev->migration_blocker);
+ }
+
+ vfio_migration_region_exit(vbasedev);
+
+ if (vbasedev->migration) {
+ g_free(vbasedev->migration);
+ }
+}
diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
index 8cdc27946cb8..191a726a1312 100644
--- a/hw/vfio/trace-events
+++ b/hw/vfio/trace-events
@@ -143,3 +143,6 @@ vfio_display_edid_link_up(void) ""
vfio_display_edid_link_down(void) ""
vfio_display_edid_update(uint32_t prefx, uint32_t prefy) "%ux%u"
vfio_display_edid_write_error(void) ""
+
+# migration.c
+vfio_migration_probe(char *name, uint32_t index) " (%s) Region %d"
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 6ea4898c4d7e..f80e04e26e1f 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -57,6 +57,12 @@ typedef struct VFIORegion {
uint8_t nr; /* cache the region number for debug */
} VFIORegion;
+typedef struct VFIOMigration {
+ VFIORegion region;
+ uint64_t pending_bytes;
+ QemuMutex lock;
+} VFIOMigration;
+
typedef struct VFIOAddressSpace {
AddressSpace *as;
QLIST_HEAD(, VFIOContainer) containers;
@@ -113,6 +119,8 @@ typedef struct VFIODevice {
unsigned int num_irqs;
unsigned int num_regions;
unsigned int flags;
+ VFIOMigration *migration;
+ Error *migration_blocker;
} VFIODevice;
struct VFIODeviceOps {
@@ -204,4 +212,7 @@ int vfio_spapr_create_window(VFIOContainer *container,
int vfio_spapr_remove_window(VFIOContainer *container,
hwaddr offset_within_address_space);
+int vfio_migration_probe(VFIODevice *vbasedev, Error **errp);
+void vfio_migration_finalize(VFIODevice *vbasedev);
+
#endif /* HW_VFIO_VFIO_COMMON_H */
--
2.7.0
- [Qemu-devel] [PATCH v8 00/13] Add migration support for VFIO device, Kirti Wankhede, 2019/08/26
- [Qemu-devel] [PATCH v8 01/13] vfio: KABI for migration interface, Kirti Wankhede, 2019/08/26
- [Qemu-devel] [PATCH v8 02/13] vfio: Add function to unmap VFIO region, Kirti Wankhede, 2019/08/26
- [Qemu-devel] [PATCH v8 03/13] vfio: Add vfio_get_object callback to VFIODeviceOps, Kirti Wankhede, 2019/08/26
- [Qemu-devel] [PATCH v8 04/13] vfio: Add save and load functions for VFIO PCI devices, Kirti Wankhede, 2019/08/26
- [Qemu-devel] [PATCH v8 05/13] vfio: Add migration region initialization and finalize function,
Kirti Wankhede <=
- [Qemu-devel] [PATCH v8 06/13] vfio: Add VM state change handler to know state of VM, Kirti Wankhede, 2019/08/26
- [Qemu-devel] [PATCH v8 07/13] vfio: Add migration state change notifier, Kirti Wankhede, 2019/08/26
- [Qemu-devel] [PATCH v8 08/13] vfio: Register SaveVMHandlers for VFIO device, Kirti Wankhede, 2019/08/26
- [Qemu-devel] [PATCH v8 09/13] vfio: Add save state functions to SaveVMHandlers, Kirti Wankhede, 2019/08/26
- [Qemu-devel] [PATCH v8 10/13] vfio: Add load state functions to SaveVMHandlers, Kirti Wankhede, 2019/08/26
- [Qemu-devel] [PATCH v8 11/13] vfio: Add function to get dirty page list, Kirti Wankhede, 2019/08/26
- [Qemu-devel] [PATCH v8 12/13] vfio: Add vfio_listener_log_sync to mark dirty pages, Kirti Wankhede, 2019/08/26
- [Qemu-devel] [PATCH v8 13/13] vfio: Make vfio-pci device migration capable., Kirti Wankhede, 2019/08/26
- Re: [Qemu-devel] [PATCH v8 00/13] Add migration support for VFIO device, no-reply, 2019/08/26