Add migration support for VFIO devices and the pre-requisite for this Signed-off-by: imxcc <xingchaochao@huawei.com>
107 lines
3.2 KiB
Diff
107 lines
3.2 KiB
Diff
From 92f104ca6e35acae079ca3bb432f24452058d483 Mon Sep 17 00:00:00 2001
|
|
From: Kirti Wankhede <kwankhede@nvidia.com>
|
|
Date: Mon, 26 Oct 2020 15:06:13 +0530
|
|
Subject: [PATCH] vfio: Add save and load functions for VFIO PCI devices
|
|
|
|
Added functions to save and restore PCI device specific data,
|
|
specifically config space of PCI device.
|
|
|
|
Signed-off-by: Kirti Wankhede <kwankhede@nvidia.com>
|
|
Reviewed-by: Neo Jia <cjia@nvidia.com>
|
|
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
|
|
---
|
|
hw/vfio/pci.c | 51 +++++++++++++++++++++++++++++++++++
|
|
include/hw/vfio/vfio-common.h | 2 ++
|
|
2 files changed, 53 insertions(+)
|
|
|
|
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
|
|
index de0d286fc9..b9fae3ad28 100644
|
|
--- a/hw/vfio/pci.c
|
|
+++ b/hw/vfio/pci.c
|
|
@@ -35,6 +35,7 @@
|
|
#include "pci.h"
|
|
#include "trace.h"
|
|
#include "qapi/error.h"
|
|
+#include "migration/qemu-file.h"
|
|
|
|
#define TYPE_VFIO_PCI "vfio-pci"
|
|
#define PCI_VFIO(obj) OBJECT_CHECK(VFIOPCIDevice, obj, TYPE_VFIO_PCI)
|
|
@@ -2395,11 +2396,61 @@ static Object *vfio_pci_get_object(VFIODevice *vbasedev)
|
|
return OBJECT(vdev);
|
|
}
|
|
|
|
+static bool vfio_msix_present(void *opaque, int version_id)
|
|
+{
|
|
+ PCIDevice *pdev = opaque;
|
|
+
|
|
+ return msix_present(pdev);
|
|
+}
|
|
+
|
|
+const VMStateDescription vmstate_vfio_pci_config = {
|
|
+ .name = "VFIOPCIDevice",
|
|
+ .version_id = 1,
|
|
+ .minimum_version_id = 1,
|
|
+ .fields = (VMStateField[]) {
|
|
+ VMSTATE_PCI_DEVICE(pdev, VFIOPCIDevice),
|
|
+ VMSTATE_MSIX_TEST(pdev, VFIOPCIDevice, vfio_msix_present),
|
|
+ VMSTATE_END_OF_LIST()
|
|
+ }
|
|
+};
|
|
+
|
|
+static void vfio_pci_save_config(VFIODevice *vbasedev, QEMUFile *f)
|
|
+{
|
|
+ VFIOPCIDevice *vdev = container_of(vbasedev, VFIOPCIDevice, vbasedev);
|
|
+
|
|
+ vmstate_save_state(f, &vmstate_vfio_pci_config, vdev, NULL);
|
|
+}
|
|
+
|
|
+static int vfio_pci_load_config(VFIODevice *vbasedev, QEMUFile *f)
|
|
+{
|
|
+ VFIOPCIDevice *vdev = container_of(vbasedev, VFIOPCIDevice, vbasedev);
|
|
+ PCIDevice *pdev = &vdev->pdev;
|
|
+ int ret;
|
|
+
|
|
+ ret = vmstate_load_state(f, &vmstate_vfio_pci_config, vdev, 1);
|
|
+ if (ret) {
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ vfio_pci_write_config(pdev, PCI_COMMAND,
|
|
+ pci_get_word(pdev->config + PCI_COMMAND), 2);
|
|
+
|
|
+ if (msi_enabled(pdev)) {
|
|
+ vfio_msi_enable(vdev);
|
|
+ } else if (msix_enabled(pdev)) {
|
|
+ vfio_msix_enable(vdev);
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
static VFIODeviceOps vfio_pci_ops = {
|
|
.vfio_compute_needs_reset = vfio_pci_compute_needs_reset,
|
|
.vfio_hot_reset_multi = vfio_pci_hot_reset_multi,
|
|
.vfio_eoi = vfio_intx_eoi,
|
|
.vfio_get_object = vfio_pci_get_object,
|
|
+ .vfio_save_config = vfio_pci_save_config,
|
|
+ .vfio_load_config = vfio_pci_load_config,
|
|
};
|
|
|
|
int vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
|
|
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
|
|
index 771b6d59a3..6ea4898c4d 100644
|
|
--- a/include/hw/vfio/vfio-common.h
|
|
+++ b/include/hw/vfio/vfio-common.h
|
|
@@ -120,6 +120,8 @@ struct VFIODeviceOps {
|
|
int (*vfio_hot_reset_multi)(VFIODevice *vdev);
|
|
void (*vfio_eoi)(VFIODevice *vdev);
|
|
Object *(*vfio_get_object)(VFIODevice *vdev);
|
|
+ void (*vfio_save_config)(VFIODevice *vdev, QEMUFile *f);
|
|
+ int (*vfio_load_config)(VFIODevice *vdev, QEMUFile *f);
|
|
};
|
|
|
|
typedef struct VFIOGroup {
|
|
--
|
|
2.27.0
|
|
|