hw/vfio: add ramfb migration support

Add a "VFIODisplay" subsection whenever "x-ramfb-migrate" is turned on.

Turn it off by default on machines <= 8.1 for compatibility reasons.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
[ clg:  - checkpatch fixes
  	- improved warn_report() in vfio_realize() ]
Signed-off-by: Cédric Le Goater <clg@redhat.com>
master
Marc-André Lureau 2023-10-09 10:32:47 +04:00 committed by Cédric Le Goater
parent a1e88d2d2b
commit 8741781157
5 changed files with 74 additions and 0 deletions

View File

@ -35,6 +35,7 @@
GlobalProperty hw_compat_8_1[] = {
{ TYPE_PCI_BRIDGE, "x-pci-express-writeable-slt-bug", "true" },
{ "ramfb", "x-migrate", "off" },
{ "vfio-pci-nohotplug", "x-ramfb-migrate", "off" }
};
const size_t hw_compat_8_1_len = G_N_ELEMENTS(hw_compat_8_1);

View File

@ -544,3 +544,24 @@ void vfio_display_finalize(VFIOPCIDevice *vdev)
vfio_display_edid_exit(vdev->dpy);
g_free(vdev->dpy);
}
static bool migrate_needed(void *opaque)
{
VFIODisplay *dpy = opaque;
bool ramfb_exists = dpy->ramfb != NULL;
/* see vfio_display_migration_needed() */
assert(ramfb_exists);
return ramfb_exists;
}
const VMStateDescription vfio_display_vmstate = {
.name = "VFIODisplay",
.version_id = 1,
.minimum_version_id = 1,
.needed = migrate_needed,
.fields = (VMStateField[]) {
VMSTATE_STRUCT_POINTER(ramfb, VFIODisplay, ramfb_vmstate, RAMFBState),
VMSTATE_END_OF_LIST(),
}
};

View File

@ -2675,6 +2675,33 @@ static bool vfio_msix_present(void *opaque, int version_id)
return msix_present(pdev);
}
static bool vfio_display_migration_needed(void *opaque)
{
VFIOPCIDevice *vdev = opaque;
/*
* We need to migrate the VFIODisplay object if ramfb *migration* was
* explicitly requested (in which case we enforced both ramfb=on and
* display=on), or ramfb migration was left at the default "auto"
* setting, and *ramfb* was explicitly requested (in which case we
* enforced display=on).
*/
return vdev->ramfb_migrate == ON_OFF_AUTO_ON ||
(vdev->ramfb_migrate == ON_OFF_AUTO_AUTO && vdev->enable_ramfb);
}
const VMStateDescription vmstate_vfio_display = {
.name = "VFIOPCIDevice/VFIODisplay",
.version_id = 1,
.minimum_version_id = 1,
.needed = vfio_display_migration_needed,
.fields = (VMStateField[]){
VMSTATE_STRUCT_POINTER(dpy, VFIOPCIDevice, vfio_display_vmstate,
VFIODisplay),
VMSTATE_END_OF_LIST()
}
};
const VMStateDescription vmstate_vfio_pci_config = {
.name = "VFIOPCIDevice",
.version_id = 1,
@ -2683,6 +2710,10 @@ const VMStateDescription vmstate_vfio_pci_config = {
VMSTATE_PCI_DEVICE(pdev, VFIOPCIDevice),
VMSTATE_MSIX_TEST(pdev, VFIOPCIDevice, vfio_msix_present),
VMSTATE_END_OF_LIST()
},
.subsections = (const VMStateDescription * []) {
&vmstate_vfio_display,
NULL
}
};
@ -3300,6 +3331,20 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
}
}
if (vdev->ramfb_migrate == ON_OFF_AUTO_ON && !vdev->enable_ramfb) {
warn_report("x-ramfb-migrate=on but ramfb=off. "
"Forcing x-ramfb-migrate to off.");
vdev->ramfb_migrate = ON_OFF_AUTO_OFF;
}
if (vbasedev->enable_migration == ON_OFF_AUTO_OFF) {
if (vdev->ramfb_migrate == ON_OFF_AUTO_AUTO) {
vdev->ramfb_migrate = ON_OFF_AUTO_OFF;
} else if (vdev->ramfb_migrate == ON_OFF_AUTO_ON) {
error_setg(errp, "x-ramfb-migrate requires enable-migration");
goto out_deregister;
}
}
if (!pdev->failover_pair_id) {
if (!vfio_migration_realize(vbasedev, errp)) {
goto out_deregister;
@ -3511,6 +3556,8 @@ static const TypeInfo vfio_pci_dev_info = {
static Property vfio_pci_dev_nohotplug_properties[] = {
DEFINE_PROP_BOOL("ramfb", VFIOPCIDevice, enable_ramfb, false),
DEFINE_PROP_ON_OFF_AUTO("x-ramfb-migrate", VFIOPCIDevice, ramfb_migrate,
ON_OFF_AUTO_AUTO),
DEFINE_PROP_END_OF_LIST(),
};

View File

@ -174,6 +174,7 @@ struct VFIOPCIDevice {
bool no_kvm_ioeventfd;
bool no_vfio_ioeventfd;
bool enable_ramfb;
OnOffAuto ramfb_migrate;
bool defer_kvm_irq_routing;
bool clear_parent_atomics_on_exit;
VFIODisplay *dpy;
@ -227,4 +228,6 @@ void vfio_display_reset(VFIOPCIDevice *vdev);
int vfio_display_probe(VFIOPCIDevice *vdev, Error **errp);
void vfio_display_finalize(VFIOPCIDevice *vdev);
extern const VMStateDescription vfio_display_vmstate;
#endif /* HW_VFIO_VFIO_PCI_H */

View File

@ -2,6 +2,8 @@
#include "qapi/error.h"
#include "hw/display/ramfb.h"
const VMStateDescription ramfb_vmstate = {};
void ramfb_display_update(QemuConsole *con, RAMFBState *s)
{
}