mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-26 05:34:13 +08:00
70693f4708
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>
107 lines
2.3 KiB
C
107 lines
2.3 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* Copyright (C) 2013 - Virtual Open Systems
|
|
* Author: Antonios Motakis <a.motakis@virtualopensystems.com>
|
|
*/
|
|
|
|
#include <linux/module.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/vfio.h>
|
|
#include <linux/amba/bus.h>
|
|
|
|
#include "vfio_platform_private.h"
|
|
|
|
#define DRIVER_VERSION "0.10"
|
|
#define DRIVER_AUTHOR "Antonios Motakis <a.motakis@virtualopensystems.com>"
|
|
#define DRIVER_DESC "VFIO for AMBA devices - User Level meta-driver"
|
|
|
|
/* probing devices from the AMBA bus */
|
|
|
|
static struct resource *get_amba_resource(struct vfio_platform_device *vdev,
|
|
int i)
|
|
{
|
|
struct amba_device *adev = (struct amba_device *) vdev->opaque;
|
|
|
|
if (i == 0)
|
|
return &adev->res;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static int get_amba_irq(struct vfio_platform_device *vdev, int i)
|
|
{
|
|
struct amba_device *adev = (struct amba_device *) vdev->opaque;
|
|
int ret = 0;
|
|
|
|
if (i < AMBA_NR_IRQS)
|
|
ret = adev->irq[i];
|
|
|
|
/* zero is an unset IRQ for AMBA devices */
|
|
return ret ? ret : -ENXIO;
|
|
}
|
|
|
|
static int vfio_amba_probe(struct amba_device *adev, const struct amba_id *id)
|
|
{
|
|
struct vfio_platform_device *vdev;
|
|
int ret;
|
|
|
|
vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
|
|
if (!vdev)
|
|
return -ENOMEM;
|
|
|
|
vdev->name = kasprintf(GFP_KERNEL, "vfio-amba-%08x", adev->periphid);
|
|
if (!vdev->name) {
|
|
kfree(vdev);
|
|
return -ENOMEM;
|
|
}
|
|
|
|
vdev->opaque = (void *) adev;
|
|
vdev->flags = VFIO_DEVICE_FLAGS_AMBA;
|
|
vdev->get_resource = get_amba_resource;
|
|
vdev->get_irq = get_amba_irq;
|
|
vdev->reset_required = false;
|
|
|
|
ret = vfio_platform_probe_common(vdev, &adev->dev);
|
|
if (ret) {
|
|
kfree(vdev->name);
|
|
kfree(vdev);
|
|
return ret;
|
|
}
|
|
|
|
dev_set_drvdata(&adev->dev, vdev);
|
|
return 0;
|
|
}
|
|
|
|
static void vfio_amba_remove(struct amba_device *adev)
|
|
{
|
|
struct vfio_platform_device *vdev = dev_get_drvdata(&adev->dev);
|
|
|
|
vfio_platform_remove_common(vdev);
|
|
kfree(vdev->name);
|
|
kfree(vdev);
|
|
}
|
|
|
|
static const struct amba_id pl330_ids[] = {
|
|
{ 0, 0 },
|
|
};
|
|
|
|
MODULE_DEVICE_TABLE(amba, pl330_ids);
|
|
|
|
static struct amba_driver vfio_amba_driver = {
|
|
.probe = vfio_amba_probe,
|
|
.remove = vfio_amba_remove,
|
|
.id_table = pl330_ids,
|
|
.drv = {
|
|
.name = "vfio-amba",
|
|
.owner = THIS_MODULE,
|
|
},
|
|
.driver_managed_dma = true,
|
|
};
|
|
|
|
module_amba_driver(vfio_amba_driver);
|
|
|
|
MODULE_VERSION(DRIVER_VERSION);
|
|
MODULE_LICENSE("GPL v2");
|
|
MODULE_AUTHOR(DRIVER_AUTHOR);
|
|
MODULE_DESCRIPTION(DRIVER_DESC);
|