xref: /qemu/hw/vfio/cpr-iommufd.c (revision a6f2f9c42f3a5418fc7000b1fd331b086b6133d9)
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 const VMStateDescription vmstate_cpr_vfio_devices;  /* TBD in a later patch */
18 
19 static bool vfio_cpr_supported(IOMMUFDBackend *be, Error **errp)
20 {
21     if (!iommufd_change_process_capable(be)) {
22         if (errp) {
23             error_setg(errp, "vfio iommufd backend does not support "
24                        "IOMMU_IOAS_CHANGE_PROCESS");
25         }
26         return false;
27     }
28     return true;
29 }
30 
31 static const VMStateDescription iommufd_cpr_vmstate = {
32     .name = "iommufd",
33     .version_id = 0,
34     .minimum_version_id = 0,
35     .needed = cpr_incoming_needed,
36     .fields = (VMStateField[]) {
37         VMSTATE_END_OF_LIST()
38     }
39 };
40 
41 bool vfio_iommufd_cpr_register_iommufd(IOMMUFDBackend *be, Error **errp)
42 {
43     Error **cpr_blocker = &be->cpr_blocker;
44 
45     if (!vfio_cpr_supported(be, cpr_blocker)) {
46         return migrate_add_blocker_modes(cpr_blocker, errp,
47                                          MIG_MODE_CPR_TRANSFER, -1) == 0;
48     }
49 
50     vmstate_register(NULL, -1, &iommufd_cpr_vmstate, be);
51 
52     return true;
53 }
54 
55 void vfio_iommufd_cpr_unregister_iommufd(IOMMUFDBackend *be)
56 {
57     vmstate_unregister(NULL, &iommufd_cpr_vmstate, be);
58     migrate_del_blocker(&be->cpr_blocker);
59 }
60 
61 bool vfio_iommufd_cpr_register_container(VFIOIOMMUFDContainer *container,
62                                          Error **errp)
63 {
64     VFIOContainerBase *bcontainer = &container->bcontainer;
65 
66     migration_add_notifier_mode(&bcontainer->cpr_reboot_notifier,
67                                 vfio_cpr_reboot_notifier,
68                                 MIG_MODE_CPR_REBOOT);
69 
70     vfio_cpr_add_kvm_notifier();
71 
72     return true;
73 }
74 
75 void vfio_iommufd_cpr_unregister_container(VFIOIOMMUFDContainer *container)
76 {
77     VFIOContainerBase *bcontainer = &container->bcontainer;
78 
79     migration_remove_notifier(&bcontainer->cpr_reboot_notifier);
80 }
81 
82 void vfio_iommufd_cpr_register_device(VFIODevice *vbasedev)
83 {
84 }
85 
86 void vfio_iommufd_cpr_unregister_device(VFIODevice *vbasedev)
87 {
88 }
89