Skip to content

Commit 0ce4a85

Browse files
LuBaolujoergroedel
authored andcommitted
Revert "iommu/vt-d: Avoid duplicated pci dma alias consideration"
This reverts commit 5575294. Commit 5575294 ("iommu/vt-d: Avoid duplicated pci dma alias consideration") aimed to address a NULL pointer deference issue happened when a thunderbolt device driver returned unexpectedly. Unfortunately, this change breaks a previous pci quirk added by commit cc346a4 ("PCI: Add function 1 DMA alias quirk for Marvell devices"), as the result, devices like Marvell 88SE9128 SATA controller doesn't work anymore. We will continue to try to find the real culprit mentioned in 5575294, but for now we should revert it to fix current breakage. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=204627 Cc: Stijn Tintel <stijn@linux-ipv6.be> Cc: Petr Vandrovec <petr@vandrovec.name> Reported-by: Stijn Tintel <stijn@linux-ipv6.be> Reported-by: Petr Vandrovec <petr@vandrovec.name> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
1 parent a55aa89 commit 0ce4a85

File tree

1 file changed

+53
-2
lines changed

1 file changed

+53
-2
lines changed

drivers/iommu/intel-iommu.c

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,8 @@ static void domain_exit(struct dmar_domain *domain);
339339
static void domain_remove_dev_info(struct dmar_domain *domain);
340340
static void dmar_remove_one_dev_info(struct device *dev);
341341
static void __dmar_remove_one_dev_info(struct device_domain_info *info);
342+
static void domain_context_clear(struct intel_iommu *iommu,
343+
struct device *dev);
342344
static int domain_detach_iommu(struct dmar_domain *domain,
343345
struct intel_iommu *iommu);
344346
static bool device_is_rmrr_locked(struct device *dev);
@@ -2105,9 +2107,26 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
21052107
return ret;
21062108
}
21072109

2110+
struct domain_context_mapping_data {
2111+
struct dmar_domain *domain;
2112+
struct intel_iommu *iommu;
2113+
struct pasid_table *table;
2114+
};
2115+
2116+
static int domain_context_mapping_cb(struct pci_dev *pdev,
2117+
u16 alias, void *opaque)
2118+
{
2119+
struct domain_context_mapping_data *data = opaque;
2120+
2121+
return domain_context_mapping_one(data->domain, data->iommu,
2122+
data->table, PCI_BUS_NUM(alias),
2123+
alias & 0xff);
2124+
}
2125+
21082126
static int
21092127
domain_context_mapping(struct dmar_domain *domain, struct device *dev)
21102128
{
2129+
struct domain_context_mapping_data data;
21112130
struct pasid_table *table;
21122131
struct intel_iommu *iommu;
21132132
u8 bus, devfn;
@@ -2117,7 +2136,17 @@ domain_context_mapping(struct dmar_domain *domain, struct device *dev)
21172136
return -ENODEV;
21182137

21192138
table = intel_pasid_get_table(dev);
2120-
return domain_context_mapping_one(domain, iommu, table, bus, devfn);
2139+
2140+
if (!dev_is_pci(dev))
2141+
return domain_context_mapping_one(domain, iommu, table,
2142+
bus, devfn);
2143+
2144+
data.domain = domain;
2145+
data.iommu = iommu;
2146+
data.table = table;
2147+
2148+
return pci_for_each_dma_alias(to_pci_dev(dev),
2149+
&domain_context_mapping_cb, &data);
21212150
}
21222151

21232152
static int domain_context_mapped_cb(struct pci_dev *pdev,
@@ -4759,6 +4788,28 @@ int __init intel_iommu_init(void)
47594788
return ret;
47604789
}
47614790

4791+
static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *opaque)
4792+
{
4793+
struct intel_iommu *iommu = opaque;
4794+
4795+
domain_context_clear_one(iommu, PCI_BUS_NUM(alias), alias & 0xff);
4796+
return 0;
4797+
}
4798+
4799+
/*
4800+
* NB - intel-iommu lacks any sort of reference counting for the users of
4801+
* dependent devices. If multiple endpoints have intersecting dependent
4802+
* devices, unbinding the driver from any one of them will possibly leave
4803+
* the others unable to operate.
4804+
*/
4805+
static void domain_context_clear(struct intel_iommu *iommu, struct device *dev)
4806+
{
4807+
if (!iommu || !dev || !dev_is_pci(dev))
4808+
return;
4809+
4810+
pci_for_each_dma_alias(to_pci_dev(dev), &domain_context_clear_one_cb, iommu);
4811+
}
4812+
47624813
static void __dmar_remove_one_dev_info(struct device_domain_info *info)
47634814
{
47644815
struct dmar_domain *domain;
@@ -4779,7 +4830,7 @@ static void __dmar_remove_one_dev_info(struct device_domain_info *info)
47794830
PASID_RID2PASID);
47804831

47814832
iommu_disable_dev_iotlb(info);
4782-
domain_context_clear_one(iommu, info->bus, info->devfn);
4833+
domain_context_clear(iommu, info->dev);
47834834
intel_pasid_free_table(info->dev);
47844835
}
47854836

0 commit comments

Comments
 (0)