Loading arch/x86/kernel/amd_iommu.c +41 −36 Original line number Diff line number Diff line Loading @@ -183,6 +183,7 @@ static int iommu_init_device(struct device *dev) return -ENOMEM; alias = amd_iommu_alias_table[dev_data->devid]; if (alias != dev_data->devid) { pdev = pci_get_bus_and_slot(PCI_BUS(alias), alias & 0xff); if (pdev) dev_data->alias = &pdev->dev; Loading @@ -190,6 +191,7 @@ static int iommu_init_device(struct device *dev) free_dev_data(dev_data); return -ENOTSUPP; } } dev->archdata.iommu = dev_data; Loading Loading @@ -1604,16 +1606,19 @@ static void do_detach(struct iommu_dev_data *dev_data) static int __attach_device(struct iommu_dev_data *dev_data, struct protection_domain *domain) { struct iommu_dev_data *alias_data; int ret; /* lock domain */ spin_lock(&domain->lock); if (dev_data->alias != NULL) { struct iommu_dev_data *alias_data; alias_data = get_dev_data(dev_data->alias); ret = -EINVAL; if (!alias_data) return -EINVAL; /* lock domain */ spin_lock(&domain->lock); goto out_unlock; /* Some sanity checks */ ret = -EBUSY; Loading @@ -1626,7 +1631,6 @@ static int __attach_device(struct iommu_dev_data *dev_data, goto out_unlock; /* Do real assignment */ if (dev_data->devid != alias_data->devid) { if (alias_data->domain == NULL) do_attach(alias_data, domain); Loading Loading @@ -1696,8 +1700,8 @@ static void __detach_device(struct iommu_dev_data *dev_data) spin_lock_irqsave(&domain->lock, flags); if (dev_data->alias) { alias_data = get_dev_data(dev_data->alias); if (dev_data->devid != alias_data->devid) { if (atomic_dec_and_test(&alias_data->bind)) do_detach(alias_data); } Loading Loading @@ -1744,24 +1748,25 @@ static void detach_device(struct device *dev) */ static struct protection_domain *domain_for_device(struct device *dev) { struct protection_domain *dom; struct iommu_dev_data *dev_data, *alias_data; struct protection_domain *dom = NULL; unsigned long flags; dev_data = get_dev_data(dev); if (dev_data->domain) return dev_data->domain; if (dev_data->alias != NULL) { alias_data = get_dev_data(dev_data->alias); if (!alias_data) return NULL; read_lock_irqsave(&amd_iommu_devtable_lock, flags); dom = dev_data->domain; if (dom == NULL && alias_data->domain != NULL) { if (alias_data->domain != NULL) { __attach_device(dev_data, alias_data->domain); dom = alias_data->domain; } read_unlock_irqrestore(&amd_iommu_devtable_lock, flags); } return dom; } Loading Loading
arch/x86/kernel/amd_iommu.c +41 −36 Original line number Diff line number Diff line Loading @@ -183,6 +183,7 @@ static int iommu_init_device(struct device *dev) return -ENOMEM; alias = amd_iommu_alias_table[dev_data->devid]; if (alias != dev_data->devid) { pdev = pci_get_bus_and_slot(PCI_BUS(alias), alias & 0xff); if (pdev) dev_data->alias = &pdev->dev; Loading @@ -190,6 +191,7 @@ static int iommu_init_device(struct device *dev) free_dev_data(dev_data); return -ENOTSUPP; } } dev->archdata.iommu = dev_data; Loading Loading @@ -1604,16 +1606,19 @@ static void do_detach(struct iommu_dev_data *dev_data) static int __attach_device(struct iommu_dev_data *dev_data, struct protection_domain *domain) { struct iommu_dev_data *alias_data; int ret; /* lock domain */ spin_lock(&domain->lock); if (dev_data->alias != NULL) { struct iommu_dev_data *alias_data; alias_data = get_dev_data(dev_data->alias); ret = -EINVAL; if (!alias_data) return -EINVAL; /* lock domain */ spin_lock(&domain->lock); goto out_unlock; /* Some sanity checks */ ret = -EBUSY; Loading @@ -1626,7 +1631,6 @@ static int __attach_device(struct iommu_dev_data *dev_data, goto out_unlock; /* Do real assignment */ if (dev_data->devid != alias_data->devid) { if (alias_data->domain == NULL) do_attach(alias_data, domain); Loading Loading @@ -1696,8 +1700,8 @@ static void __detach_device(struct iommu_dev_data *dev_data) spin_lock_irqsave(&domain->lock, flags); if (dev_data->alias) { alias_data = get_dev_data(dev_data->alias); if (dev_data->devid != alias_data->devid) { if (atomic_dec_and_test(&alias_data->bind)) do_detach(alias_data); } Loading Loading @@ -1744,24 +1748,25 @@ static void detach_device(struct device *dev) */ static struct protection_domain *domain_for_device(struct device *dev) { struct protection_domain *dom; struct iommu_dev_data *dev_data, *alias_data; struct protection_domain *dom = NULL; unsigned long flags; dev_data = get_dev_data(dev); if (dev_data->domain) return dev_data->domain; if (dev_data->alias != NULL) { alias_data = get_dev_data(dev_data->alias); if (!alias_data) return NULL; read_lock_irqsave(&amd_iommu_devtable_lock, flags); dom = dev_data->domain; if (dom == NULL && alias_data->domain != NULL) { if (alias_data->domain != NULL) { __attach_device(dev_data, alias_data->domain); dom = alias_data->domain; } read_unlock_irqrestore(&amd_iommu_devtable_lock, flags); } return dom; } Loading