Skip to content
Permalink
Browse files
vfio/pci: Add bind_iommufd() support
vfio pci implements the [un]bind_iommufd() callback to support iommufd.

Signed-off-by: Liu Yi L <yi.l.liu@intel.com>
  • Loading branch information
yiliu1765 committed Dec 10, 2021
1 parent 352505c commit 74814fdbefe2fb370111a0ce00641c64376447cb
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 0 deletions.
@@ -4,6 +4,7 @@ config VFIO_PCI_CORE
tristate
select VFIO_VIRQFD
select IRQ_BYPASS_MANAGER
select IOMMUFD

config VFIO_PCI_MMAP
def_bool y if !S390
@@ -128,6 +128,8 @@ static int vfio_pci_open_device(struct vfio_device *core_vdev)
static const struct vfio_device_ops vfio_pci_ops = {
.name = "vfio-pci",
.release = vfio_pci_core_release,
.bind_iommufd = vfio_pci_core_bind_iommufd,
.unbind_iommufd = vfio_pci_core_unbind_iommufd,
.open_device = vfio_pci_open_device,
.close_device = vfio_pci_core_close_device,
.ioctl = vfio_pci_core_ioctl,
@@ -634,6 +634,53 @@ int vfio_pci_register_dev_region(struct vfio_pci_core_device *vdev,
}
EXPORT_SYMBOL_GPL(vfio_pci_register_dev_region);

int vfio_pci_core_bind_iommufd(struct vfio_device *core_vdev,
struct vfio_device_bind_iommufd *bind)
{
struct vfio_pci_core_device *vdev =
container_of(core_vdev, struct vfio_pci_core_device, vdev);
struct iommufd_device *idev;
u32 id;
int ret = 0;

mutex_lock(&vdev->idev_lock);

/* Allow only one iommufd per vfio_device */
if (vdev->idev) {
ret = -EBUSY;
goto out_unlock;
}

idev = iommufd_bind_pci_device(bind->iommufd, vdev->pdev,
&id, bind->dev_cookie);
if (IS_ERR(idev)) {
ret = PTR_ERR(idev);
goto out_unlock;
}

vdev->idev = idev;
bind->out_devid = id;

out_unlock:
mutex_unlock(&vdev->idev_lock);
return ret;
}
EXPORT_SYMBOL_GPL(vfio_pci_core_bind_iommufd);

void vfio_pci_core_unbind_iommufd(struct vfio_device *core_vdev)
{
struct vfio_pci_core_device *vdev =
container_of(core_vdev, struct vfio_pci_core_device, vdev);

mutex_lock(&vdev->idev_lock);
if (vdev->idev) {
iommufd_unbind_device(vdev->idev);
vdev->idev = NULL;
}
mutex_unlock(&vdev->idev_lock);
}
EXPORT_SYMBOL_GPL(vfio_pci_core_unbind_iommufd);

long vfio_pci_core_ioctl(struct vfio_device *core_vdev, unsigned int cmd,
unsigned long arg)
{
@@ -1795,6 +1842,7 @@ vfio_pci_core_alloc_device(struct pci_dev *pdev,
mutex_init(&vdev->vma_lock);
INIT_LIST_HEAD(&vdev->vma_list);
init_rwsem(&vdev->memory_lock);
mutex_init(&vdev->idev_lock);

out:
return vdev;
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/uuid.h>
#include <linux/notifier.h>
#include <linux/iommufd.h>

#ifndef VFIO_PCI_CORE_H
#define VFIO_PCI_CORE_H
@@ -137,6 +138,8 @@ struct vfio_pci_core_device {
struct mutex vma_lock;
struct list_head vma_list;
struct rw_semaphore memory_lock;
struct mutex idev_lock;
struct iommufd_device *idev;
};

#define is_intx(vdev) (vdev->irq_type == VFIO_PCI_INTX_IRQ_INDEX)
@@ -210,6 +213,9 @@ static inline int vfio_pci_info_zdev_add_caps(struct vfio_pci_core_device *vdev,
void vfio_pci_core_set_params(bool nointxmask, bool is_disable_vga,
bool is_disable_idle_d3);
void vfio_pci_core_release(struct vfio_device *core_dev);
int vfio_pci_core_bind_iommufd(struct vfio_device *core_vdev,
struct vfio_device_bind_iommufd *bind);
void vfio_pci_core_unbind_iommufd(struct vfio_device *core_vdev);
void vfio_pci_core_close_device(struct vfio_device *core_vdev);
struct vfio_pci_core_device *
vfio_pci_core_alloc_device(struct pci_dev *pdev,

0 comments on commit 74814fd

Please sign in to comment.