vfio/container: ram discard disable helper

Define a helper to set ram discard disable, generate error messages,
and cleanup on failure.  The second vfio_ram_block_discard_disable
call site now performs VFIO_GROUP_UNSET_CONTAINER immediately on failure,
instead of relying on the close of the container fd to do so in the kernel,
but this is equivalent.

Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
Reviewed-by: Cedric Le Goater <clg@redhat.com>
Link: https://lore.kernel.org/qemu-devel/1746195760-101443-2-git-send-email-steven.sistare@oracle.com
[ clg: vfio_attach_discard_disable() -> vfio_container_attach_discard_disable() ]
Signed-off-by: Cédric Le Goater <clg@redhat.com>
This commit is contained in:
Steve Sistare 2025-05-02 07:22:38 -07:00 committed by Cédric Le Goater
parent 4b1f5b73e0
commit 2cc3643df5

View file

@ -511,16 +511,10 @@ static bool vfio_legacy_setup(VFIOContainerBase *bcontainer, Error **errp)
return true;
}
static bool vfio_container_connect(VFIOGroup *group, AddressSpace *as,
Error **errp)
static bool vfio_container_attach_discard_disable(VFIOContainer *container,
VFIOGroup *group, Error **errp)
{
VFIOContainer *container;
VFIOContainerBase *bcontainer;
int ret, fd;
VFIOAddressSpace *space;
VFIOIOMMUClass *vioc;
space = vfio_address_space_get(as);
int ret;
/*
* VFIO is currently incompatible with discarding of RAM insofar as the
@ -553,18 +547,32 @@ static bool vfio_container_connect(VFIOGroup *group, AddressSpace *as,
* details once we know which type of IOMMU we are using.
*/
ret = vfio_ram_block_discard_disable(container, true);
if (ret) {
error_setg_errno(errp, -ret, "Cannot set discarding of RAM broken");
if (ioctl(group->fd, VFIO_GROUP_UNSET_CONTAINER, &container->fd)) {
error_report("vfio: error disconnecting group %d from"
" container", group->groupid);
}
}
return !ret;
}
static bool vfio_container_connect(VFIOGroup *group, AddressSpace *as,
Error **errp)
{
VFIOContainer *container;
VFIOContainerBase *bcontainer;
int ret, fd;
VFIOAddressSpace *space;
VFIOIOMMUClass *vioc;
space = vfio_address_space_get(as);
QLIST_FOREACH(bcontainer, &space->containers, next) {
container = container_of(bcontainer, VFIOContainer, bcontainer);
if (!ioctl(group->fd, VFIO_GROUP_SET_CONTAINER, &container->fd)) {
ret = vfio_ram_block_discard_disable(container, true);
if (ret) {
error_setg_errno(errp, -ret,
"Cannot set discarding of RAM broken");
if (ioctl(group->fd, VFIO_GROUP_UNSET_CONTAINER,
&container->fd)) {
error_report("vfio: error disconnecting group %d from"
" container", group->groupid);
}
if (!vfio_container_attach_discard_disable(container, group, errp)) {
return false;
}
group->container = container;
@ -596,9 +604,7 @@ static bool vfio_container_connect(VFIOGroup *group, AddressSpace *as,
goto free_container_exit;
}
ret = vfio_ram_block_discard_disable(container, true);
if (ret) {
error_setg_errno(errp, -ret, "Cannot set discarding of RAM broken");
if (!vfio_container_attach_discard_disable(container, group, errp)) {
goto unregister_container_exit;
}