aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2012-05-30 16:19:07 -0400
committerJoerg Roedel <joerg.roedel@amd.com>2012-06-25 07:48:28 -0400
commit9dcd61303af862c279df86aa97fde7ce371be774 (patch)
treebe61c0777c39c5d9cec564545de3cd1e21044936 /drivers/iommu
parentd72e31c9374627068df29da8085ca18c92ae35d3 (diff)
amd_iommu: Support IOMMU groups
Add IOMMU group support to AMD-Vi device init and uninit code. Existing notifiers make sure this gets called for each device. Signed-off-by: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Diffstat (limited to 'drivers/iommu')
-rw-r--r--drivers/iommu/amd_iommu.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 55283d6291c8..60ea92065d31 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -256,9 +256,11 @@ static bool check_device(struct device *dev)
256 256
257static int iommu_init_device(struct device *dev) 257static int iommu_init_device(struct device *dev)
258{ 258{
259 struct pci_dev *pdev = to_pci_dev(dev); 259 struct pci_dev *dma_pdev, *pdev = to_pci_dev(dev);
260 struct iommu_dev_data *dev_data; 260 struct iommu_dev_data *dev_data;
261 struct iommu_group *group;
261 u16 alias; 262 u16 alias;
263 int ret;
262 264
263 if (dev->archdata.iommu) 265 if (dev->archdata.iommu)
264 return 0; 266 return 0;
@@ -279,8 +281,26 @@ static int iommu_init_device(struct device *dev)
279 return -ENOTSUPP; 281 return -ENOTSUPP;
280 } 282 }
281 dev_data->alias_data = alias_data; 283 dev_data->alias_data = alias_data;
284
285 dma_pdev = pci_get_bus_and_slot(alias >> 8, alias & 0xff);
286 } else
287 dma_pdev = pci_dev_get(pdev);
288
289 group = iommu_group_get(&dma_pdev->dev);
290 pci_dev_put(dma_pdev);
291 if (!group) {
292 group = iommu_group_alloc();
293 if (IS_ERR(group))
294 return PTR_ERR(group);
282 } 295 }
283 296
297 ret = iommu_group_add_device(group, dev);
298
299 iommu_group_put(group);
300
301 if (ret)
302 return ret;
303
284 if (pci_iommuv2_capable(pdev)) { 304 if (pci_iommuv2_capable(pdev)) {
285 struct amd_iommu *iommu; 305 struct amd_iommu *iommu;
286 306
@@ -309,6 +329,8 @@ static void iommu_ignore_device(struct device *dev)
309 329
310static void iommu_uninit_device(struct device *dev) 330static void iommu_uninit_device(struct device *dev)
311{ 331{
332 iommu_group_remove_device(dev);
333
312 /* 334 /*
313 * Nothing to do here - we keep dev_data around for unplugged devices 335 * Nothing to do here - we keep dev_data around for unplugged devices
314 * and reuse it when the device is re-plugged - not doing so would 336 * and reuse it when the device is re-plugged - not doing so would