mirror of https://github.com/xemu-project/xemu.git
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>
This commit is contained in:
parent
e93b733bcf
commit
c5e2fb3ce4
|
@ -41,6 +41,7 @@
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "migration/blocker.h"
|
#include "migration/blocker.h"
|
||||||
|
#include "migration/qemu-file.h"
|
||||||
|
|
||||||
#define TYPE_VFIO_PCI_NOHOTPLUG "vfio-pci-nohotplug"
|
#define TYPE_VFIO_PCI_NOHOTPLUG "vfio-pci-nohotplug"
|
||||||
|
|
||||||
|
@ -2401,11 +2402,61 @@ static Object *vfio_pci_get_object(VFIODevice *vbasedev)
|
||||||
return OBJECT(vdev);
|
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 = {
|
static VFIODeviceOps vfio_pci_ops = {
|
||||||
.vfio_compute_needs_reset = vfio_pci_compute_needs_reset,
|
.vfio_compute_needs_reset = vfio_pci_compute_needs_reset,
|
||||||
.vfio_hot_reset_multi = vfio_pci_hot_reset_multi,
|
.vfio_hot_reset_multi = vfio_pci_hot_reset_multi,
|
||||||
.vfio_eoi = vfio_intx_eoi,
|
.vfio_eoi = vfio_intx_eoi,
|
||||||
.vfio_get_object = vfio_pci_get_object,
|
.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)
|
int vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp)
|
||||||
|
|
|
@ -120,6 +120,8 @@ struct VFIODeviceOps {
|
||||||
int (*vfio_hot_reset_multi)(VFIODevice *vdev);
|
int (*vfio_hot_reset_multi)(VFIODevice *vdev);
|
||||||
void (*vfio_eoi)(VFIODevice *vdev);
|
void (*vfio_eoi)(VFIODevice *vdev);
|
||||||
Object *(*vfio_get_object)(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 {
|
typedef struct VFIOGroup {
|
||||||
|
|
Loading…
Reference in New Issue