Skip to content

Commit 4296ee0

Browse files
Steve Sistarelegoater
authored andcommitted
vfio/iommufd: reconstruct device
Reconstruct userland device state after CPR. During vfio_realize, skip all ioctls that configure the device, as it was already configured in old QEMU. Skip bind, and use the devid from CPR state. Skip allocation of, and attachment to, ioas_id. Recover ioas_id from CPR state, and use it to find a matching container, if any, before creating a new one. This reconstruction is not complete. hwpt_id is handled in a subsequent patch. 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-17-git-send-email-steven.sistare@oracle.com Signed-off-by: Cédric Le Goater <clg@redhat.com>
1 parent 2a3f0a5 commit 4296ee0

File tree

1 file changed

+28
-2
lines changed

1 file changed

+28
-2
lines changed

hw/vfio/iommufd.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "system/reset.h"
2626
#include "qemu/cutils.h"
2727
#include "qemu/chardev_open.h"
28+
#include "migration/cpr.h"
2829
#include "pci.h"
2930
#include "vfio-iommufd.h"
3031
#include "vfio-helpers.h"
@@ -121,6 +122,10 @@ static bool iommufd_cdev_connect_and_bind(VFIODevice *vbasedev, Error **errp)
121122
goto err_kvm_device_add;
122123
}
123124

125+
if (cpr_is_incoming()) {
126+
goto skip_bind;
127+
}
128+
124129
/* Bind device to iommufd */
125130
bind.iommufd = iommufd->fd;
126131
if (ioctl(vbasedev->fd, VFIO_DEVICE_BIND_IOMMUFD, &bind)) {
@@ -132,6 +137,8 @@ static bool iommufd_cdev_connect_and_bind(VFIODevice *vbasedev, Error **errp)
132137
vbasedev->devid = bind.out_devid;
133138
trace_iommufd_cdev_connect_and_bind(bind.iommufd, vbasedev->name,
134139
vbasedev->fd, vbasedev->devid);
140+
141+
skip_bind:
135142
return true;
136143
err_bind:
137144
iommufd_cdev_kvm_device_del(vbasedev);
@@ -421,7 +428,9 @@ static bool iommufd_cdev_attach_container(VFIODevice *vbasedev,
421428
return iommufd_cdev_autodomains_get(vbasedev, container, errp);
422429
}
423430

424-
return !iommufd_cdev_attach_ioas_hwpt(vbasedev, container->ioas_id, errp);
431+
/* If CPR, we are already attached to ioas_id. */
432+
return cpr_is_incoming() ||
433+
!iommufd_cdev_attach_ioas_hwpt(vbasedev, container->ioas_id, errp);
425434
}
426435

427436
static void iommufd_cdev_detach_container(VFIODevice *vbasedev,
@@ -510,6 +519,7 @@ static bool iommufd_cdev_attach(const char *name, VFIODevice *vbasedev,
510519
VFIOAddressSpace *space;
511520
struct vfio_device_info dev_info = { .argsz = sizeof(dev_info) };
512521
int ret, devfd;
522+
bool res;
513523
uint32_t ioas_id;
514524
Error *err = NULL;
515525
const VFIOIOMMUClass *iommufd_vioc =
@@ -540,7 +550,16 @@ static bool iommufd_cdev_attach(const char *name, VFIODevice *vbasedev,
540550
vbasedev->iommufd != container->be) {
541551
continue;
542552
}
543-
if (!iommufd_cdev_attach_container(vbasedev, container, &err)) {
553+
554+
if (!cpr_is_incoming()) {
555+
res = iommufd_cdev_attach_container(vbasedev, container, &err);
556+
} else if (vbasedev->cpr.ioas_id == container->ioas_id) {
557+
res = true;
558+
} else {
559+
continue;
560+
}
561+
562+
if (!res) {
544563
const char *msg = error_get_pretty(err);
545564

546565
trace_iommufd_cdev_fail_attach_existing_container(msg);
@@ -557,17 +576,24 @@ static bool iommufd_cdev_attach(const char *name, VFIODevice *vbasedev,
557576
}
558577
}
559578

579+
if (cpr_is_incoming()) {
580+
ioas_id = vbasedev->cpr.ioas_id;
581+
goto skip_ioas_alloc;
582+
}
583+
560584
/* Need to allocate a new dedicated container */
561585
if (!iommufd_backend_alloc_ioas(vbasedev->iommufd, &ioas_id, errp)) {
562586
goto err_alloc_ioas;
563587
}
564588

565589
trace_iommufd_cdev_alloc_ioas(vbasedev->iommufd->fd, ioas_id);
566590

591+
skip_ioas_alloc:
567592
container = VFIO_IOMMU_IOMMUFD(object_new(TYPE_VFIO_IOMMU_IOMMUFD));
568593
container->be = vbasedev->iommufd;
569594
container->ioas_id = ioas_id;
570595
QLIST_INIT(&container->hwpt_list);
596+
vbasedev->cpr.ioas_id = ioas_id;
571597

572598
bcontainer = &container->bcontainer;
573599
vfio_address_space_insert(space, bcontainer);

0 commit comments

Comments
 (0)