aboutsummaryrefslogtreecommitdiff
path: root/hw/vfio/iommufd.c
diff options
context:
space:
mode:
authorZhenzhong Duan <zhenzhong.duan@intel.com>2023-11-21 16:44:10 +0800
committerCédric Le Goater <clg@redhat.com>2023-12-19 19:03:38 +0100
commitda3e04b26fd8d15b344944504d5ffa9c5f20b54b (patch)
tree7278965f6dc90c409ba3fffa3169b60149142869 /hw/vfio/iommufd.c
parentee42b261b0a2e465ae003ddcaf1caf117c201f74 (diff)
downloadqemu-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.c12
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) {