mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-06 09:13:55 -06:00
vfio/container: register container for cpr
Register a legacy container for cpr-transfer, replacing the generic CPR register call with a more specific legacy container register call. Add a blocker if the kernel does not support VFIO_UPDATE_VADDR or VFIO_UNMAP_ALL. This is mostly boiler plate. The fields to to saved and restored are added in subsequent patches. Signed-off-by: Steve Sistare <steven.sistare@oracle.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/1749569991-25171-4-git-send-email-steven.sistare@oracle.com Signed-off-by: Cédric Le Goater <clg@redhat.com>
This commit is contained in:
parent
081c09dc52
commit
54857b0816
6 changed files with 91 additions and 7 deletions
|
@ -33,7 +33,6 @@
|
|||
#include "qapi/error.h"
|
||||
#include "pci.h"
|
||||
#include "hw/vfio/vfio-container.h"
|
||||
#include "hw/vfio/vfio-cpr.h"
|
||||
#include "vfio-helpers.h"
|
||||
#include "vfio-listener.h"
|
||||
|
||||
|
@ -643,7 +642,7 @@ static bool vfio_container_connect(VFIOGroup *group, AddressSpace *as,
|
|||
new_container = true;
|
||||
bcontainer = &container->bcontainer;
|
||||
|
||||
if (!vfio_cpr_register_container(bcontainer, errp)) {
|
||||
if (!vfio_legacy_cpr_register_container(container, errp)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -679,7 +678,7 @@ fail:
|
|||
vioc->release(bcontainer);
|
||||
}
|
||||
if (new_container) {
|
||||
vfio_cpr_unregister_container(bcontainer);
|
||||
vfio_legacy_cpr_unregister_container(container);
|
||||
object_unref(container);
|
||||
}
|
||||
if (fd >= 0) {
|
||||
|
@ -720,7 +719,7 @@ static void vfio_container_disconnect(VFIOGroup *group)
|
|||
VFIOAddressSpace *space = bcontainer->space;
|
||||
|
||||
trace_vfio_container_disconnect(container->fd);
|
||||
vfio_cpr_unregister_container(bcontainer);
|
||||
vfio_legacy_cpr_unregister_container(container);
|
||||
close(container->fd);
|
||||
object_unref(container);
|
||||
|
||||
|
|
68
hw/vfio/cpr-legacy.c
Normal file
68
hw/vfio/cpr-legacy.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2021-2025 Oracle and/or its affiliates.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/vfio.h>
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/vfio/vfio-container.h"
|
||||
#include "migration/blocker.h"
|
||||
#include "migration/cpr.h"
|
||||
#include "migration/migration.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "qapi/error.h"
|
||||
|
||||
static bool vfio_cpr_supported(VFIOContainer *container, Error **errp)
|
||||
{
|
||||
if (!ioctl(container->fd, VFIO_CHECK_EXTENSION, VFIO_UPDATE_VADDR)) {
|
||||
error_setg(errp, "VFIO container does not support VFIO_UPDATE_VADDR");
|
||||
return false;
|
||||
|
||||
} else if (!ioctl(container->fd, VFIO_CHECK_EXTENSION, VFIO_UNMAP_ALL)) {
|
||||
error_setg(errp, "VFIO container does not support VFIO_UNMAP_ALL");
|
||||
return false;
|
||||
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static const VMStateDescription vfio_container_vmstate = {
|
||||
.name = "vfio-container",
|
||||
.version_id = 0,
|
||||
.minimum_version_id = 0,
|
||||
.needed = cpr_incoming_needed,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
bool vfio_legacy_cpr_register_container(VFIOContainer *container, Error **errp)
|
||||
{
|
||||
VFIOContainerBase *bcontainer = &container->bcontainer;
|
||||
Error **cpr_blocker = &container->cpr.blocker;
|
||||
|
||||
migration_add_notifier_mode(&bcontainer->cpr_reboot_notifier,
|
||||
vfio_cpr_reboot_notifier,
|
||||
MIG_MODE_CPR_REBOOT);
|
||||
|
||||
if (!vfio_cpr_supported(container, cpr_blocker)) {
|
||||
return migrate_add_blocker_modes(cpr_blocker, errp,
|
||||
MIG_MODE_CPR_TRANSFER, -1) == 0;
|
||||
}
|
||||
|
||||
vmstate_register(NULL, -1, &vfio_container_vmstate, container);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void vfio_legacy_cpr_unregister_container(VFIOContainer *container)
|
||||
{
|
||||
VFIOContainerBase *bcontainer = &container->bcontainer;
|
||||
|
||||
migration_remove_notifier(&bcontainer->cpr_reboot_notifier);
|
||||
migrate_del_blocker(&container->cpr.blocker);
|
||||
vmstate_unregister(NULL, &vfio_container_vmstate, container);
|
||||
}
|
|
@ -7,13 +7,12 @@
|
|||
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/vfio/vfio-device.h"
|
||||
#include "migration/misc.h"
|
||||
#include "hw/vfio/vfio-cpr.h"
|
||||
#include "qapi/error.h"
|
||||
#include "system/runstate.h"
|
||||
|
||||
static int vfio_cpr_reboot_notifier(NotifierWithReturn *notifier,
|
||||
MigrationEvent *e, Error **errp)
|
||||
int vfio_cpr_reboot_notifier(NotifierWithReturn *notifier,
|
||||
MigrationEvent *e, Error **errp)
|
||||
{
|
||||
if (e->type == MIG_EVENT_PRECOPY_SETUP &&
|
||||
!runstate_check(RUN_STATE_SUSPENDED) && !vm_get_suspended()) {
|
||||
|
|
|
@ -21,6 +21,7 @@ system_ss.add(when: 'CONFIG_VFIO_XGMAC', if_true: files('calxeda-xgmac.c'))
|
|||
system_ss.add(when: 'CONFIG_VFIO_AMD_XGBE', if_true: files('amd-xgbe.c'))
|
||||
system_ss.add(when: 'CONFIG_VFIO', if_true: files(
|
||||
'cpr.c',
|
||||
'cpr-legacy.c',
|
||||
'device.c',
|
||||
'migration.c',
|
||||
'migration-multifd.c',
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#define HW_VFIO_CONTAINER_H
|
||||
|
||||
#include "hw/vfio/vfio-container-base.h"
|
||||
#include "hw/vfio/vfio-cpr.h"
|
||||
|
||||
typedef struct VFIOContainer VFIOContainer;
|
||||
typedef struct VFIODevice VFIODevice;
|
||||
|
@ -29,6 +30,7 @@ typedef struct VFIOContainer {
|
|||
int fd; /* /dev/vfio/vfio, empowered by the attached groups */
|
||||
unsigned iommu_type;
|
||||
QLIST_HEAD(, VFIOGroup) group_list;
|
||||
VFIOContainerCPR cpr;
|
||||
} VFIOContainer;
|
||||
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(VFIOContainer, VFIO_IOMMU_LEGACY);
|
||||
|
|
|
@ -9,8 +9,23 @@
|
|||
#ifndef HW_VFIO_VFIO_CPR_H
|
||||
#define HW_VFIO_VFIO_CPR_H
|
||||
|
||||
#include "migration/misc.h"
|
||||
|
||||
struct VFIOContainer;
|
||||
struct VFIOContainerBase;
|
||||
|
||||
typedef struct VFIOContainerCPR {
|
||||
Error *blocker;
|
||||
} VFIOContainerCPR;
|
||||
|
||||
|
||||
bool vfio_legacy_cpr_register_container(struct VFIOContainer *container,
|
||||
Error **errp);
|
||||
void vfio_legacy_cpr_unregister_container(struct VFIOContainer *container);
|
||||
|
||||
int vfio_cpr_reboot_notifier(NotifierWithReturn *notifier, MigrationEvent *e,
|
||||
Error **errp);
|
||||
|
||||
bool vfio_cpr_register_container(struct VFIOContainerBase *bcontainer,
|
||||
Error **errp);
|
||||
void vfio_cpr_unregister_container(struct VFIOContainerBase *bcontainer);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue