lkml.org 
[lkml]   [2022]   [Apr]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RESEND PATCH v8 07/11] vfio: Set DMA ownership for VFIO devices
    Date
    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>
    ---
    drivers/vfio/fsl-mc/vfio_fsl_mc.c | 1 +
    drivers/vfio/pci/vfio_pci.c | 1 +
    drivers/vfio/platform/vfio_amba.c | 1 +
    drivers/vfio/platform/vfio_platform.c | 1 +
    drivers/vfio/vfio.c | 10 +++++++++-
    5 files changed, 13 insertions(+), 1 deletion(-)

    diff --git a/drivers/vfio/fsl-mc/vfio_fsl_mc.c b/drivers/vfio/fsl-mc/vfio_fsl_mc.c
    index 6e2e62c6f47a..3feff729f3ce 100644
    --- a/drivers/vfio/fsl-mc/vfio_fsl_mc.c
    +++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c
    @@ -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)
    diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
    index 2b047469e02f..58839206d1ca 100644
    --- a/drivers/vfio/pci/vfio_pci.c
    +++ b/drivers/vfio/pci/vfio_pci.c
    @@ -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)
    diff --git a/drivers/vfio/platform/vfio_amba.c b/drivers/vfio/platform/vfio_amba.c
    index badfffea14fb..1aaa4f721bd2 100644
    --- a/drivers/vfio/platform/vfio_amba.c
    +++ b/drivers/vfio/platform/vfio_amba.c
    @@ -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);
    diff --git a/drivers/vfio/platform/vfio_platform.c b/drivers/vfio/platform/vfio_platform.c
    index 68a1c87066d7..04f40c5acfd6 100644
    --- a/drivers/vfio/platform/vfio_platform.c
    +++ b/drivers/vfio/platform/vfio_platform.c
    @@ -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);
    diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
    index a4555014bd1e..56e741cbccce 100644
    --- a/drivers/vfio/vfio.c
    +++ b/drivers/vfio/vfio.c
    @@ -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);
    @@ -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;
    --
    2.25.1
    \
     
     \ /
      Last update: 2022-04-18 02:53    [W:2.170 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site