| From 25b11ce2a3607d7c39a2ca121eea0c67c722b34e Mon Sep 17 00:00:00 2001 |
| From: Alex Williamson <alex.williamson@redhat.com> |
| Date: Fri, 19 Sep 2014 10:03:13 -0600 |
| Subject: iommu/amd: Split init_iommu_group() from iommu_init_device() |
| |
| From: Alex Williamson <alex.williamson@redhat.com> |
| |
| commit 25b11ce2a3607d7c39a2ca121eea0c67c722b34e upstream. |
| |
| For a PCI device, aliases from the IVRS table won't be populated |
| into dma_alias_devfn until after iommu_init_device() is called on |
| each device. We therefore want to split init_iommu_group() to |
| be called from a separate loop immediately following. |
| |
| Signed-off-by: Alex Williamson <alex.williamson@redhat.com> |
| Signed-off-by: Joerg Roedel <jroedel@suse.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/iommu/amd_iommu.c | 27 +++++++++++++-------------- |
| 1 file changed, 13 insertions(+), 14 deletions(-) |
| |
| --- a/drivers/iommu/amd_iommu.c |
| +++ b/drivers/iommu/amd_iommu.c |
| @@ -260,17 +260,13 @@ static bool check_device(struct device * |
| return true; |
| } |
| |
| -static int init_iommu_group(struct device *dev) |
| +static void init_iommu_group(struct device *dev) |
| { |
| struct iommu_group *group; |
| |
| group = iommu_group_get_for_dev(dev); |
| - |
| - if (IS_ERR(group)) |
| - return PTR_ERR(group); |
| - |
| - iommu_group_put(group); |
| - return 0; |
| + if (!IS_ERR(group)) |
| + iommu_group_put(group); |
| } |
| |
| static int __last_alias(struct pci_dev *pdev, u16 alias, void *data) |
| @@ -340,7 +336,6 @@ static int iommu_init_device(struct devi |
| struct pci_dev *pdev = to_pci_dev(dev); |
| struct iommu_dev_data *dev_data; |
| u16 alias; |
| - int ret; |
| |
| if (dev->archdata.iommu) |
| return 0; |
| @@ -364,12 +359,6 @@ static int iommu_init_device(struct devi |
| dev_data->alias_data = alias_data; |
| } |
| |
| - ret = init_iommu_group(dev); |
| - if (ret) { |
| - free_dev_data(dev_data); |
| - return ret; |
| - } |
| - |
| if (pci_iommuv2_capable(pdev)) { |
| struct amd_iommu *iommu; |
| |
| @@ -455,6 +444,15 @@ int __init amd_iommu_init_devices(void) |
| goto out_free; |
| } |
| |
| + /* |
| + * Initialize IOMMU groups only after iommu_init_device() has |
| + * had a chance to populate any IVRS defined aliases. |
| + */ |
| + for_each_pci_dev(pdev) { |
| + if (check_device(&pdev->dev)) |
| + init_iommu_group(&pdev->dev); |
| + } |
| + |
| return 0; |
| |
| out_free: |
| @@ -2415,6 +2413,7 @@ static int device_change_notifier(struct |
| case BUS_NOTIFY_ADD_DEVICE: |
| |
| iommu_init_device(dev); |
| + init_iommu_group(dev); |
| |
| /* |
| * dev_data is still NULL and |