Skip to content

Commit

Permalink
vfio: Set DMA ownership for VFIO devices
Browse files Browse the repository at this point in the history
Claim group dma ownership when an IOMMU group is set to a container,
and release the dma ownership once the iommu group is unset from the
container.

This change disallows some unsafe bridge drivers to bind to non-ACS
bridges while devices under them are assigned to user space. This is an
intentional enhancement and possibly breaks some existing
configurations. The recommendation to such an affected user would be
that the previously allowed host bridge driver was unsafe for this use
case and to continue to enable assignment of devices within that group,
the driver should be unbound from the bridge device or replaced with the
pci-stub driver.

For any bridge driver, we consider it unsafe if it satisfies any of the
following conditions:

  1) The bridge driver uses DMA. Calling pci_set_master() or calling any
     kernel DMA API (dma_map_*() and etc.) is an indicate that the
     driver is doing DMA.

  2) If the bridge driver uses MMIO, it should be tolerant to hostile
     userspace also touching the same MMIO registers via P2P DMA
     attacks.

If the bridge driver turns out to be a safe one, it could be used as
before by setting the driver's .driver_managed_dma field, just like what
we have done in the pcieport driver.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Acked-by: Alex Williamson <alex.williamson@redhat.com>
Link: https://lore.kernel.org/r/20220418005000.897664-8-baolu.lu@linux.intel.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
  • Loading branch information
Lu Baolu authored and Joerg Roedel committed Apr 28, 2022
1 parent c7d4698 commit 70693f4
Show file tree
Hide file tree
Showing 5 changed files with 13 additions and 1 deletion.
1 change: 1 addition & 0 deletions drivers/vfio/fsl-mc/vfio_fsl_mc.c
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,7 @@ static struct fsl_mc_driver vfio_fsl_mc_driver = {
.name = "vfio-fsl-mc",
.owner = THIS_MODULE,
},
.driver_managed_dma = true,
};

static int __init vfio_fsl_mc_driver_init(void)
Expand Down
1 change: 1 addition & 0 deletions drivers/vfio/pci/vfio_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ static struct pci_driver vfio_pci_driver = {
.remove = vfio_pci_remove,
.sriov_configure = vfio_pci_sriov_configure,
.err_handler = &vfio_pci_core_err_handlers,
.driver_managed_dma = true,
};

static void __init vfio_pci_fill_ids(void)
Expand Down
1 change: 1 addition & 0 deletions drivers/vfio/platform/vfio_amba.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ static struct amba_driver vfio_amba_driver = {
.name = "vfio-amba",
.owner = THIS_MODULE,
},
.driver_managed_dma = true,
};

module_amba_driver(vfio_amba_driver);
Expand Down
1 change: 1 addition & 0 deletions drivers/vfio/platform/vfio_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ static struct platform_driver vfio_platform_driver = {
.driver = {
.name = "vfio-platform",
},
.driver_managed_dma = true,
};

module_platform_driver(vfio_platform_driver);
Expand Down
10 changes: 9 additions & 1 deletion drivers/vfio/vfio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1198,6 +1198,8 @@ static void __vfio_group_unset_container(struct vfio_group *group)
driver->ops->detach_group(container->iommu_data,
group->iommu_group);

iommu_group_release_dma_owner(group->iommu_group);

group->container = NULL;
wake_up(&group->container_q);
list_del(&group->container_next);
Expand Down Expand Up @@ -1282,13 +1284,19 @@ static int vfio_group_set_container(struct vfio_group *group, int container_fd)
goto unlock_out;
}

ret = iommu_group_claim_dma_owner(group->iommu_group, f.file);
if (ret)
goto unlock_out;

driver = container->iommu_driver;
if (driver) {
ret = driver->ops->attach_group(container->iommu_data,
group->iommu_group,
group->type);
if (ret)
if (ret) {
iommu_group_release_dma_owner(group->iommu_group);
goto unlock_out;
}
}

group->container = container;
Expand Down

0 comments on commit 70693f4

Please sign in to comment.