diff options
author | Zhenzhong Duan <zhenzhong.duan@intel.com> | 2023-11-21 16:44:10 +0800 |
---|---|---|
committer | Cédric Le Goater <clg@redhat.com> | 2023-12-19 19:03:38 +0100 |
commit | da3e04b26fd8d15b344944504d5ffa9c5f20b54b (patch) | |
tree | 7278965f6dc90c409ba3fffa3169b60149142869 /hw/vfio/iommufd.c | |
parent | ee42b261b0a2e465ae003ddcaf1caf117c201f74 (diff) | |
download | qemu-da3e04b26fd8d15b344944504d5ffa9c5f20b54b.zip qemu-da3e04b26fd8d15b344944504d5ffa9c5f20b54b.tar.gz qemu-da3e04b26fd8d15b344944504d5ffa9c5f20b54b.tar.bz2 |
vfio/pci: Make vfio cdev pre-openable by passing a file handle
This gives management tools like libvirt a chance to open the vfio
cdev with privilege and pass FD to qemu. This way qemu never needs
to have privilege to open a VFIO or iommu cdev node.
Together with the earlier support of pre-opening /dev/iommu device,
now we have full support of passing a vfio device to unprivileged
qemu by management tool. This mode is no more considered for the
legacy backend. So let's remove the "TODO" comment.
Add helper functions vfio_device_set_fd() and vfio_device_get_name()
to set fd and get device name, they will also be used by other vfio
devices.
There is no easy way to check if a device is mdev with FD passing,
so fail the x-balloon-allowed check unconditionally in this case.
There is also no easy way to get BDF as name with FD passing, so
we fake a name by VFIO_FD[fd].
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Tested-by: Eric Auger <eric.auger@redhat.com>
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Cédric Le Goater <clg@redhat.com>
Diffstat (limited to 'hw/vfio/iommufd.c')
-rw-r--r-- | hw/vfio/iommufd.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c index 6e53e01..5accd26 100644 --- a/hw/vfio/iommufd.c +++ b/hw/vfio/iommufd.c @@ -320,11 +320,15 @@ static int iommufd_cdev_attach(const char *name, VFIODevice *vbasedev, uint32_t ioas_id; Error *err = NULL; - devfd = iommufd_cdev_getfd(vbasedev->sysfsdev, errp); - if (devfd < 0) { - return devfd; + if (vbasedev->fd < 0) { + devfd = iommufd_cdev_getfd(vbasedev->sysfsdev, errp); + if (devfd < 0) { + return devfd; + } + vbasedev->fd = devfd; + } else { + devfd = vbasedev->fd; } - vbasedev->fd = devfd; ret = iommufd_cdev_connect_and_bind(vbasedev, errp); if (ret) { |