|
@@ -256,9 +256,11 @@ static bool check_device(struct device *dev)
|
|
|
|
|
|
static int iommu_init_device(struct device *dev)
|
|
|
{
|
|
|
- struct pci_dev *pdev = to_pci_dev(dev);
|
|
|
+ struct pci_dev *dma_pdev, *pdev = to_pci_dev(dev);
|
|
|
struct iommu_dev_data *dev_data;
|
|
|
+ struct iommu_group *group;
|
|
|
u16 alias;
|
|
|
+ int ret;
|
|
|
|
|
|
if (dev->archdata.iommu)
|
|
|
return 0;
|
|
@@ -279,8 +281,26 @@ static int iommu_init_device(struct device *dev)
|
|
|
return -ENOTSUPP;
|
|
|
}
|
|
|
dev_data->alias_data = alias_data;
|
|
|
+
|
|
|
+ dma_pdev = pci_get_bus_and_slot(alias >> 8, alias & 0xff);
|
|
|
+ } else
|
|
|
+ dma_pdev = pci_dev_get(pdev);
|
|
|
+
|
|
|
+ group = iommu_group_get(&dma_pdev->dev);
|
|
|
+ pci_dev_put(dma_pdev);
|
|
|
+ if (!group) {
|
|
|
+ group = iommu_group_alloc();
|
|
|
+ if (IS_ERR(group))
|
|
|
+ return PTR_ERR(group);
|
|
|
}
|
|
|
|
|
|
+ ret = iommu_group_add_device(group, dev);
|
|
|
+
|
|
|
+ iommu_group_put(group);
|
|
|
+
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
if (pci_iommuv2_capable(pdev)) {
|
|
|
struct amd_iommu *iommu;
|
|
|
|
|
@@ -309,6 +329,8 @@ static void iommu_ignore_device(struct device *dev)
|
|
|
|
|
|
static void iommu_uninit_device(struct device *dev)
|
|
|
{
|
|
|
+ iommu_group_remove_device(dev);
|
|
|
+
|
|
|
/*
|
|
|
* Nothing to do here - we keep dev_data around for unplugged devices
|
|
|
* and reuse it when the device is re-plugged - not doing so would
|