diff options
| -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 |
