Commit 25b11ce2 authored by Alex Williamson's avatar Alex Williamson Committed by Joerg Roedel

iommu/amd: Split init_iommu_group() from iommu_init_device()

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: default avatarAlex Williamson <alex.williamson@redhat.com>
Cc: stable@vger.kernel.org # 3.17
Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent f096c061
...@@ -260,17 +260,13 @@ static bool check_device(struct device *dev) ...@@ -260,17 +260,13 @@ static bool check_device(struct device *dev)
return true; return true;
} }
static int init_iommu_group(struct device *dev) static void init_iommu_group(struct device *dev)
{ {
struct iommu_group *group; struct iommu_group *group;
group = iommu_group_get_for_dev(dev); group = iommu_group_get_for_dev(dev);
if (!IS_ERR(group))
if (IS_ERR(group))
return PTR_ERR(group);
iommu_group_put(group); iommu_group_put(group);
return 0;
} }
static int __last_alias(struct pci_dev *pdev, u16 alias, void *data) static int __last_alias(struct pci_dev *pdev, u16 alias, void *data)
...@@ -340,7 +336,6 @@ static int iommu_init_device(struct device *dev) ...@@ -340,7 +336,6 @@ static int iommu_init_device(struct device *dev)
struct pci_dev *pdev = to_pci_dev(dev); struct pci_dev *pdev = to_pci_dev(dev);
struct iommu_dev_data *dev_data; struct iommu_dev_data *dev_data;
u16 alias; u16 alias;
int ret;
if (dev->archdata.iommu) if (dev->archdata.iommu)
return 0; return 0;
...@@ -364,12 +359,6 @@ static int iommu_init_device(struct device *dev) ...@@ -364,12 +359,6 @@ static int iommu_init_device(struct device *dev)
dev_data->alias_data = alias_data; 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)) { if (pci_iommuv2_capable(pdev)) {
struct amd_iommu *iommu; struct amd_iommu *iommu;
...@@ -455,6 +444,15 @@ int __init amd_iommu_init_devices(void) ...@@ -455,6 +444,15 @@ int __init amd_iommu_init_devices(void)
goto out_free; 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; return 0;
out_free: out_free:
...@@ -2415,6 +2413,7 @@ static int device_change_notifier(struct notifier_block *nb, ...@@ -2415,6 +2413,7 @@ static int device_change_notifier(struct notifier_block *nb,
case BUS_NOTIFY_ADD_DEVICE: case BUS_NOTIFY_ADD_DEVICE:
iommu_init_device(dev); iommu_init_device(dev);
init_iommu_group(dev);
/* /*
* dev_data is still NULL and * dev_data is still NULL and
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment