[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v7 05/13] vfio: Add migration region initialization
From: |
Kirti Wankhede |
Subject: |
[Qemu-devel] [PATCH v7 05/13] vfio: Add migration region initialization and finalize function |
Date: |
Tue, 9 Jul 2019 15:19:12 +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 | 145 ++++++++++++++++++++++++++++++++++++++++++
hw/vfio/trace-events | 3 +
include/hw/vfio/vfio-common.h | 14 ++++
4 files changed, 163 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..a2cfbd5af2e1
--- /dev/null
+++ b/hw/vfio/migration.c
@@ -0,0 +1,145 @@
+/*
+ * 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.buffer.size) {
+ vfio_region_exit(&migration->region.buffer);
+ vfio_region_finalize(&migration->region.buffer);
+ }
+}
+
+static int vfio_migration_region_init(VFIODevice *vbasedev)
+{
+ VFIOMigration *migration = vbasedev->migration;
+ Object *obj = NULL;
+ int ret = -EINVAL;
+
+ if (!migration) {
+ return ret;
+ }
+
+ 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.buffer,
+ migration->region.index, "migration");
+ if (ret) {
+ error_report("%s: Failed to setup VFIO migration region %d: %s",
+ vbasedev->name, migration->region.index, strerror(-ret));
+ goto err;
+ }
+
+ if (!migration->region.buffer.size) {
+ ret = -EINVAL;
+ error_report("%s: Invalid region size of VFIO migration region %d: %s",
+ vbasedev->name, migration->region.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);
+ vbasedev->migration->region.index = info->index;
+
+ ret = vfio_migration_region_init(vbasedev);
+ if (ret) {
+ error_report("%s: Failed to initialise migration region",
+ vbasedev->name);
+ 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) {
+ return;
+ }
+
+ if (vbasedev->migration_blocker) {
+ migrate_del_blocker(vbasedev->migration_blocker);
+ error_free(vbasedev->migration_blocker);
+ }
+
+ vfio_migration_region_exit(vbasedev);
+ 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 ee72bd984a36..152da3f8d6f3 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -57,6 +57,15 @@ typedef struct VFIORegion {
uint8_t nr; /* cache the region number for debug */
} VFIORegion;
+typedef struct VFIOMigration {
+ struct {
+ VFIORegion buffer;
+ uint32_t index;
+ } region;
+ uint64_t pending_bytes;
+ QemuMutex lock;
+} VFIOMigration;
+
typedef struct VFIOAddressSpace {
AddressSpace *as;
QLIST_HEAD(, VFIOContainer) containers;
@@ -113,6 +122,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 +215,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
- Re: [Qemu-devel] [PATCH v7 01/13] vfio: KABI for migration interface, (continued)
- [Qemu-devel] [PATCH v7 02/13] vfio: Add function to unmap VFIO region, Kirti Wankhede, 2019/07/09
- [Qemu-devel] [PATCH v7 03/13] vfio: Add vfio_get_object callback to VFIODeviceOps, Kirti Wankhede, 2019/07/09
- [Qemu-devel] [PATCH v7 04/13] vfio: Add save and load functions for VFIO PCI devices, Kirti Wankhede, 2019/07/09
- [Qemu-devel] [PATCH v7 05/13] vfio: Add migration region initialization and finalize function,
Kirti Wankhede <=
- [Qemu-devel] [PATCH v7 06/13] vfio: Add VM state change handler to know state of VM, Kirti Wankhede, 2019/07/09
- Re: [Qemu-devel] [PATCH v7 06/13] vfio: Add VM state change handler to know state of VM, Alex Williamson, 2019/07/16
- Re: [Qemu-devel] [PATCH v7 06/13] vfio: Add VM state change handler to know state of VM, Yan Zhao, 2019/07/22
- [Qemu-devel] [PATCH v7 07/13] vfio: Add migration state change notifier, Kirti Wankhede, 2019/07/09