diff options
author | Alex Williamson <alex.williamson@redhat.com> | 2012-05-30 16:19:07 -0400 |
---|---|---|
committer | Joerg Roedel <joerg.roedel@amd.com> | 2012-06-25 07:48:28 -0400 |
commit | 9dcd61303af862c279df86aa97fde7ce371be774 (patch) | |
tree | be61c0777c39c5d9cec564545de3cd1e21044936 /drivers/iommu | |
parent | d72e31c9374627068df29da8085ca18c92ae35d3 (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.c | 24 |
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 | ||
257 | static int iommu_init_device(struct device *dev) | 257 | static 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 | ||
310 | static void iommu_uninit_device(struct device *dev) | 330 | static 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 |