Skip to content

Commit f2f3e46

Browse files
Steve Sistarelegoater
authored andcommitted
vfio/iommufd: cpr state
VFIO iommufd devices will need access to ioas_id, devid, and hwpt_id in new QEMU at realize time, so add them to CPR state. Define CprVFIODevice as the object which holds the state and is serialized to the vmstate file. Define accessors to copy state between VFIODevice and CprVFIODevice. Signed-off-by: Steve Sistare <steven.sistare@oracle.com> Reviewed-by: Zhenzhong Duan <zhenzhong.duan@intel.com> Link: https://lore.kernel.org/qemu-devel/1751493538-202042-15-git-send-email-steven.sistare@oracle.com Signed-off-by: Cédric Le Goater <clg@redhat.com>
1 parent a6f2f9c commit f2f3e46

File tree

4 files changed

+105
-1
lines changed

4 files changed

+105
-1
lines changed

hw/vfio/cpr-iommufd.c

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,98 @@
77
#include "qemu/osdep.h"
88
#include "qapi/error.h"
99
#include "hw/vfio/vfio-cpr.h"
10+
#include "hw/vfio/vfio-device.h"
1011
#include "migration/blocker.h"
1112
#include "migration/cpr.h"
1213
#include "migration/migration.h"
1314
#include "migration/vmstate.h"
1415
#include "system/iommufd.h"
1516
#include "vfio-iommufd.h"
17+
#include "trace.h"
18+
19+
typedef struct CprVFIODevice {
20+
char *name;
21+
unsigned int namelen;
22+
uint32_t ioas_id;
23+
int devid;
24+
uint32_t hwpt_id;
25+
QLIST_ENTRY(CprVFIODevice) next;
26+
} CprVFIODevice;
27+
28+
static const VMStateDescription vmstate_cpr_vfio_device = {
29+
.name = "cpr vfio device",
30+
.version_id = 1,
31+
.minimum_version_id = 1,
32+
.fields = (VMStateField[]) {
33+
VMSTATE_UINT32(namelen, CprVFIODevice),
34+
VMSTATE_VBUFFER_ALLOC_UINT32(name, CprVFIODevice, 0, NULL, namelen),
35+
VMSTATE_INT32(devid, CprVFIODevice),
36+
VMSTATE_UINT32(ioas_id, CprVFIODevice),
37+
VMSTATE_UINT32(hwpt_id, CprVFIODevice),
38+
VMSTATE_END_OF_LIST()
39+
}
40+
};
41+
42+
const VMStateDescription vmstate_cpr_vfio_devices = {
43+
.name = CPR_STATE "/vfio devices",
44+
.version_id = 1,
45+
.minimum_version_id = 1,
46+
.fields = (const VMStateField[]){
47+
VMSTATE_QLIST_V(vfio_devices, CprState, 1, vmstate_cpr_vfio_device,
48+
CprVFIODevice, next),
49+
VMSTATE_END_OF_LIST()
50+
}
51+
};
52+
53+
static void vfio_cpr_save_device(VFIODevice *vbasedev)
54+
{
55+
CprVFIODevice *elem = g_new0(CprVFIODevice, 1);
56+
57+
elem->name = g_strdup(vbasedev->name);
58+
elem->namelen = strlen(vbasedev->name) + 1;
59+
elem->ioas_id = vbasedev->cpr.ioas_id;
60+
elem->devid = vbasedev->devid;
61+
elem->hwpt_id = vbasedev->cpr.hwpt_id;
62+
QLIST_INSERT_HEAD(&cpr_state.vfio_devices, elem, next);
63+
}
64+
65+
static CprVFIODevice *find_device(const char *name)
66+
{
67+
CprVFIODeviceList *head = &cpr_state.vfio_devices;
68+
CprVFIODevice *elem;
69+
70+
QLIST_FOREACH(elem, head, next) {
71+
if (!strcmp(elem->name, name)) {
72+
return elem;
73+
}
74+
}
75+
return NULL;
76+
}
77+
78+
static void vfio_cpr_delete_device(const char *name)
79+
{
80+
CprVFIODevice *elem = find_device(name);
1681

17-
const VMStateDescription vmstate_cpr_vfio_devices; /* TBD in a later patch */
82+
if (elem) {
83+
QLIST_REMOVE(elem, next);
84+
g_free(elem->name);
85+
g_free(elem);
86+
}
87+
}
88+
89+
static bool vfio_cpr_find_device(VFIODevice *vbasedev)
90+
{
91+
CprVFIODevice *elem = find_device(vbasedev->name);
92+
93+
if (elem) {
94+
vbasedev->cpr.ioas_id = elem->ioas_id;
95+
vbasedev->devid = elem->devid;
96+
vbasedev->cpr.hwpt_id = elem->hwpt_id;
97+
trace_vfio_cpr_find_device(elem->ioas_id, elem->devid, elem->hwpt_id);
98+
return true;
99+
}
100+
return false;
101+
}
18102

19103
static bool vfio_cpr_supported(IOMMUFDBackend *be, Error **errp)
20104
{
@@ -81,8 +165,20 @@ void vfio_iommufd_cpr_unregister_container(VFIOIOMMUFDContainer *container)
81165

82166
void vfio_iommufd_cpr_register_device(VFIODevice *vbasedev)
83167
{
168+
if (!cpr_is_incoming()) {
169+
vfio_cpr_save_device(vbasedev);
170+
}
84171
}
85172

86173
void vfio_iommufd_cpr_unregister_device(VFIODevice *vbasedev)
87174
{
175+
vfio_cpr_delete_device(vbasedev->name);
176+
}
177+
178+
void vfio_cpr_load_device(VFIODevice *vbasedev)
179+
{
180+
if (cpr_is_incoming()) {
181+
bool ret = vfio_cpr_find_device(vbasedev);
182+
g_assert(ret);
183+
}
88184
}

hw/vfio/iommufd.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,8 @@ static bool iommufd_cdev_attach(const char *name, VFIODevice *vbasedev,
515515
const VFIOIOMMUClass *iommufd_vioc =
516516
VFIO_IOMMU_CLASS(object_class_by_name(TYPE_VFIO_IOMMU_IOMMUFD));
517517

518+
vfio_cpr_load_device(vbasedev);
519+
518520
if (vbasedev->fd < 0) {
519521
devfd = iommufd_cdev_getfd(vbasedev->sysfsdev, errp);
520522
if (devfd < 0) {

hw/vfio/trace-events

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,9 @@ iommufd_cdev_alloc_ioas(int iommufd, int ioas_id) " [iommufd=%d] new IOMMUFD con
197197
iommufd_cdev_device_info(char *name, int devfd, int num_irqs, int num_regions, int flags) " %s (%d) num_irqs=%d num_regions=%d flags=%d"
198198
iommufd_cdev_pci_hot_reset_dep_devices(int domain, int bus, int slot, int function, int dev_id) "\t%04x:%02x:%02x.%x devid %d"
199199

200+
# cpr-iommufd.c
201+
vfio_cpr_find_device(uint32_t ioas_id, int devid, uint32_t hwpt_id) "ioas_id %u, devid %d, hwpt_id %u"
202+
200203
# device.c
201204
vfio_device_get_region_info_type(const char *name, int index, uint32_t type, uint32_t subtype) "%s index %d, %08x/%08x"
202205
vfio_device_reset_handler(void) ""

include/hw/vfio/vfio-cpr.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ typedef struct VFIOContainerCPR {
3434
typedef struct VFIODeviceCPR {
3535
Error *mdev_blocker;
3636
Error *id_blocker;
37+
uint32_t hwpt_id;
38+
uint32_t ioas_id;
3739
} VFIODeviceCPR;
3840

3941
bool vfio_legacy_cpr_register_container(struct VFIOContainer *container,
@@ -55,6 +57,7 @@ bool vfio_iommufd_cpr_register_iommufd(struct IOMMUFDBackend *be, Error **errp);
5557
void vfio_iommufd_cpr_unregister_iommufd(struct IOMMUFDBackend *be);
5658
void vfio_iommufd_cpr_register_device(struct VFIODevice *vbasedev);
5759
void vfio_iommufd_cpr_unregister_device(struct VFIODevice *vbasedev);
60+
void vfio_cpr_load_device(struct VFIODevice *vbasedev);
5861

5962
int vfio_cpr_group_get_device_fd(int d, const char *name);
6063

0 commit comments

Comments
 (0)