xref: /qemu/hw/vfio/cpr-iommufd.c (revision 06c6a65852af0b7648cdb6ff6cf2e66929a7b5f5)
1 /*
2  * Copyright (c) 2024-2025 Oracle and/or its affiliates.
3  *
4  * SPDX-License-Identifier: GPL-2.0-or-later
5  */
6 
7 #include "qemu/osdep.h"
8 #include "qapi/error.h"
9 #include "hw/vfio/vfio-cpr.h"
10 #include "migration/blocker.h"
11 #include "migration/cpr.h"
12 #include "migration/migration.h"
13 #include "migration/vmstate.h"
14 #include "system/iommufd.h"
15 #include "vfio-iommufd.h"
16 
17 static bool vfio_cpr_supported(IOMMUFDBackend *be, Error **errp)
18 {
19     if (!iommufd_change_process_capable(be)) {
20         if (errp) {
21             error_setg(errp, "vfio iommufd backend does not support "
22                        "IOMMU_IOAS_CHANGE_PROCESS");
23         }
24         return false;
25     }
26     return true;
27 }
28 
29 static const VMStateDescription iommufd_cpr_vmstate = {
30     .name = "iommufd",
31     .version_id = 0,
32     .minimum_version_id = 0,
33     .needed = cpr_incoming_needed,
34     .fields = (VMStateField[]) {
35         VMSTATE_END_OF_LIST()
36     }
37 };
38 
39 bool vfio_iommufd_cpr_register_iommufd(IOMMUFDBackend *be, Error **errp)
40 {
41     Error **cpr_blocker = &be->cpr_blocker;
42 
43     if (!vfio_cpr_supported(be, cpr_blocker)) {
44         return migrate_add_blocker_modes(cpr_blocker, errp,
45                                          MIG_MODE_CPR_TRANSFER, -1) == 0;
46     }
47 
48     vmstate_register(NULL, -1, &iommufd_cpr_vmstate, be);
49 
50     return true;
51 }
52 
53 void vfio_iommufd_cpr_unregister_iommufd(IOMMUFDBackend *be)
54 {
55     vmstate_unregister(NULL, &iommufd_cpr_vmstate, be);
56     migrate_del_blocker(&be->cpr_blocker);
57 }
58 
59 bool vfio_iommufd_cpr_register_container(VFIOIOMMUFDContainer *container,
60                                          Error **errp)
61 {
62     VFIOContainerBase *bcontainer = &container->bcontainer;
63 
64     migration_add_notifier_mode(&bcontainer->cpr_reboot_notifier,
65                                 vfio_cpr_reboot_notifier,
66                                 MIG_MODE_CPR_REBOOT);
67 
68     vfio_cpr_add_kvm_notifier();
69 
70     return true;
71 }
72 
73 void vfio_iommufd_cpr_unregister_container(VFIOIOMMUFDContainer *container)
74 {
75     VFIOContainerBase *bcontainer = &container->bcontainer;
76 
77     migration_remove_notifier(&bcontainer->cpr_reboot_notifier);
78 }
79 
80 void vfio_iommufd_cpr_register_device(VFIODevice *vbasedev)
81 {
82 }
83 
84 void vfio_iommufd_cpr_unregister_device(VFIODevice *vbasedev)
85 {
86 }
87