summaryrefslogtreecommitdiffstats
path: root/drivers/iommu/intel-iommu.c
diff options
context:
space:
mode:
authorLu Baolu <baolu.lu@linux.intel.com>2019-07-09 01:22:45 -0400
committerJoerg Roedel <jroedel@suse.de>2019-07-22 11:16:24 -0400
commit557529494d79f3f1fadd486dd18d2de0b19be4da (patch)
tree9e226486ee963fe35a7663c6e3ac144a0f261a3c /drivers/iommu/intel-iommu.c
parent301e7ee1dec513e5aca12d01c819a1f762918d0a (diff)
iommu/vt-d: Avoid duplicated pci dma alias consideration
As we have abandoned the home-made lazy domain allocation and delegated the DMA domain life cycle up to the default domain mechanism defined in the generic iommu layer, we needn't consider pci alias anymore when mapping/unmapping the context entries. Without this fix, we see kernel NULL pointer dereference during pci device hot-plug test. Cc: Ashok Raj <ashok.raj@intel.com> Cc: Jacob Pan <jacob.jun.pan@linux.intel.com> Cc: Kevin Tian <kevin.tian@intel.com> Fixes: fa954e6831789 ("iommu/vt-d: Delegate the dma domain to upper layer") Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Reported-and-tested-by: Xu Pengfei <pengfei.xu@intel.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu/intel-iommu.c')
-rw-r--r--drivers/iommu/intel-iommu.c55
1 files changed, 2 insertions, 53 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 441781d12553..9b1d62d03370 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -339,8 +339,6 @@ static void domain_exit(struct dmar_domain *domain);
339static void domain_remove_dev_info(struct dmar_domain *domain); 339static void domain_remove_dev_info(struct dmar_domain *domain);
340static void dmar_remove_one_dev_info(struct device *dev); 340static void dmar_remove_one_dev_info(struct device *dev);
341static void __dmar_remove_one_dev_info(struct device_domain_info *info); 341static void __dmar_remove_one_dev_info(struct device_domain_info *info);
342static void domain_context_clear(struct intel_iommu *iommu,
343 struct device *dev);
344static int domain_detach_iommu(struct dmar_domain *domain, 342static int domain_detach_iommu(struct dmar_domain *domain,
345 struct intel_iommu *iommu); 343 struct intel_iommu *iommu);
346static bool device_is_rmrr_locked(struct device *dev); 344static bool device_is_rmrr_locked(struct device *dev);
@@ -2105,26 +2103,9 @@ out_unlock:
2105 return ret; 2103 return ret;
2106} 2104}
2107 2105
2108struct domain_context_mapping_data {
2109 struct dmar_domain *domain;
2110 struct intel_iommu *iommu;
2111 struct pasid_table *table;
2112};
2113
2114static int domain_context_mapping_cb(struct pci_dev *pdev,
2115 u16 alias, void *opaque)
2116{
2117 struct domain_context_mapping_data *data = opaque;
2118
2119 return domain_context_mapping_one(data->domain, data->iommu,
2120 data->table, PCI_BUS_NUM(alias),
2121 alias & 0xff);
2122}
2123
2124static int 2106static int
2125domain_context_mapping(struct dmar_domain *domain, struct device *dev) 2107domain_context_mapping(struct dmar_domain *domain, struct device *dev)
2126{ 2108{
2127 struct domain_context_mapping_data data;
2128 struct pasid_table *table; 2109 struct pasid_table *table;
2129 struct intel_iommu *iommu; 2110 struct intel_iommu *iommu;
2130 u8 bus, devfn; 2111 u8 bus, devfn;
@@ -2134,17 +2115,7 @@ domain_context_mapping(struct dmar_domain *domain, struct device *dev)
2134 return -ENODEV; 2115 return -ENODEV;
2135 2116
2136 table = intel_pasid_get_table(dev); 2117 table = intel_pasid_get_table(dev);
2137 2118 return domain_context_mapping_one(domain, iommu, table, bus, devfn);
2138 if (!dev_is_pci(dev))
2139 return domain_context_mapping_one(domain, iommu, table,
2140 bus, devfn);
2141
2142 data.domain = domain;
2143 data.iommu = iommu;
2144 data.table = table;
2145
2146 return pci_for_each_dma_alias(to_pci_dev(dev),
2147 &domain_context_mapping_cb, &data);
2148} 2119}
2149 2120
2150static int domain_context_mapped_cb(struct pci_dev *pdev, 2121static int domain_context_mapped_cb(struct pci_dev *pdev,
@@ -4784,28 +4755,6 @@ out_free_dmar:
4784 return ret; 4755 return ret;
4785} 4756}
4786 4757
4787static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *opaque)
4788{
4789 struct intel_iommu *iommu = opaque;
4790
4791 domain_context_clear_one(iommu, PCI_BUS_NUM(alias), alias & 0xff);
4792 return 0;
4793}
4794
4795/*
4796 * NB - intel-iommu lacks any sort of reference counting for the users of
4797 * dependent devices. If multiple endpoints have intersecting dependent
4798 * devices, unbinding the driver from any one of them will possibly leave
4799 * the others unable to operate.
4800 */
4801static void domain_context_clear(struct intel_iommu *iommu, struct device *dev)
4802{
4803 if (!iommu || !dev || !dev_is_pci(dev))
4804 return;
4805
4806 pci_for_each_dma_alias(to_pci_dev(dev), &domain_context_clear_one_cb, iommu);
4807}
4808
4809static void __dmar_remove_one_dev_info(struct device_domain_info *info) 4758static void __dmar_remove_one_dev_info(struct device_domain_info *info)
4810{ 4759{
4811 struct dmar_domain *domain; 4760 struct dmar_domain *domain;
@@ -4826,7 +4775,7 @@ static void __dmar_remove_one_dev_info(struct device_domain_info *info)
4826 PASID_RID2PASID); 4775 PASID_RID2PASID);
4827 4776
4828 iommu_disable_dev_iotlb(info); 4777 iommu_disable_dev_iotlb(info);
4829 domain_context_clear(iommu, info->dev); 4778 domain_context_clear_one(iommu, info->bus, info->devfn);
4830 intel_pasid_free_table(info->dev); 4779 intel_pasid_free_table(info->dev);
4831 } 4780 }
4832 4781