|
@@ -276,6 +276,29 @@ static struct iommu_dev_data *get_dev_data(struct device *dev)
|
|
|
return dev->archdata.iommu;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+* Find or create an IOMMU group for a acpihid device.
|
|
|
+*/
|
|
|
+static struct iommu_group *acpihid_device_group(struct device *dev)
|
|
|
+{
|
|
|
+ struct acpihid_map_entry *p, *entry = NULL;
|
|
|
+ u16 devid;
|
|
|
+
|
|
|
+ devid = get_acpihid_device_id(dev, &entry);
|
|
|
+ if (devid < 0)
|
|
|
+ return ERR_PTR(devid);
|
|
|
+
|
|
|
+ list_for_each_entry(p, &acpihid_map, list) {
|
|
|
+ if ((devid == p->devid) && p->group)
|
|
|
+ entry->group = p->group;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!entry->group)
|
|
|
+ entry->group = generic_device_group(dev);
|
|
|
+
|
|
|
+ return entry->group;
|
|
|
+}
|
|
|
+
|
|
|
static bool pci_iommuv2_capable(struct pci_dev *pdev)
|
|
|
{
|
|
|
static const int caps[] = {
|
|
@@ -2445,6 +2468,14 @@ static void amd_iommu_remove_device(struct device *dev)
|
|
|
iommu_completion_wait(iommu);
|
|
|
}
|
|
|
|
|
|
+static struct iommu_group *amd_iommu_device_group(struct device *dev)
|
|
|
+{
|
|
|
+ if (dev_is_pci(dev))
|
|
|
+ return pci_device_group(dev);
|
|
|
+
|
|
|
+ return acpihid_device_group(dev);
|
|
|
+}
|
|
|
+
|
|
|
/*****************************************************************************
|
|
|
*
|
|
|
* The next functions belong to the dma_ops mapping/unmapping code.
|
|
@@ -3286,7 +3317,7 @@ static const struct iommu_ops amd_iommu_ops = {
|
|
|
.iova_to_phys = amd_iommu_iova_to_phys,
|
|
|
.add_device = amd_iommu_add_device,
|
|
|
.remove_device = amd_iommu_remove_device,
|
|
|
- .device_group = pci_device_group,
|
|
|
+ .device_group = amd_iommu_device_group,
|
|
|
.get_dm_regions = amd_iommu_get_dm_regions,
|
|
|
.put_dm_regions = amd_iommu_put_dm_regions,
|
|
|
.pgsize_bitmap = AMD_IOMMU_PGSIZES,
|