xref: /openbmc/qemu/hw/vfio/cpr-legacy.c (revision 54857b08168a0a74711d1f773c16a7122499027b)
1 /*
2  * Copyright (c) 2021-2025 Oracle and/or its affiliates.
3  *
4  * SPDX-License-Identifier: GPL-2.0-or-later
5  */
6 
7 #include <sys/ioctl.h>
8 #include <linux/vfio.h>
9 #include "qemu/osdep.h"
10 #include "hw/vfio/vfio-container.h"
11 #include "migration/blocker.h"
12 #include "migration/cpr.h"
13 #include "migration/migration.h"
14 #include "migration/vmstate.h"
15 #include "qapi/error.h"
16 
17 static bool vfio_cpr_supported(VFIOContainer *container, Error **errp)
18 {
19     if (!ioctl(container->fd, VFIO_CHECK_EXTENSION, VFIO_UPDATE_VADDR)) {
20         error_setg(errp, "VFIO container does not support VFIO_UPDATE_VADDR");
21         return false;
22 
23     } else if (!ioctl(container->fd, VFIO_CHECK_EXTENSION, VFIO_UNMAP_ALL)) {
24         error_setg(errp, "VFIO container does not support VFIO_UNMAP_ALL");
25         return false;
26 
27     } else {
28         return true;
29     }
30 }
31 
32 static const VMStateDescription vfio_container_vmstate = {
33     .name = "vfio-container",
34     .version_id = 0,
35     .minimum_version_id = 0,
36     .needed = cpr_incoming_needed,
37     .fields = (VMStateField[]) {
38         VMSTATE_END_OF_LIST()
39     }
40 };
41 
42 bool vfio_legacy_cpr_register_container(VFIOContainer *container, Error **errp)
43 {
44     VFIOContainerBase *bcontainer = &container->bcontainer;
45     Error **cpr_blocker = &container->cpr.blocker;
46 
47     migration_add_notifier_mode(&bcontainer->cpr_reboot_notifier,
48                                 vfio_cpr_reboot_notifier,
49                                 MIG_MODE_CPR_REBOOT);
50 
51     if (!vfio_cpr_supported(container, cpr_blocker)) {
52         return migrate_add_blocker_modes(cpr_blocker, errp,
53                                          MIG_MODE_CPR_TRANSFER, -1) == 0;
54     }
55 
56     vmstate_register(NULL, -1, &vfio_container_vmstate, container);
57 
58     return true;
59 }
60 
61 void vfio_legacy_cpr_unregister_container(VFIOContainer *container)
62 {
63     VFIOContainerBase *bcontainer = &container->bcontainer;
64 
65     migration_remove_notifier(&bcontainer->cpr_reboot_notifier);
66     migrate_del_blocker(&container->cpr.blocker);
67     vmstate_unregister(NULL, &vfio_container_vmstate, container);
68 }
69