aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2014-03-09 16:31:18 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2014-03-24 10:06:44 -0400
commit5a8f40e8c8801a9805bbe60d140ed2b0b3b91d18 (patch)
tree8f70047bbeeb2b8e356e3fadac52130df27079db
parente2f8c5f6d45b092b52adea9d71018ef11250b924 (diff)
iommu/vt-d: Always store iommu in device_domain_info
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
-rw-r--r--drivers/iommu/intel-iommu.c47
1 files changed, 31 insertions, 16 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 84f0d4284125..8303f256fe84 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -1274,8 +1274,6 @@ iommu_support_dev_iotlb (struct dmar_domain *domain, struct intel_iommu *iommu,
1274 if (!dmar_find_matched_atsr_unit(pdev)) 1274 if (!dmar_find_matched_atsr_unit(pdev))
1275 return NULL; 1275 return NULL;
1276 1276
1277 info->iommu = iommu;
1278
1279 return info; 1277 return info;
1280} 1278}
1281 1279
@@ -2134,7 +2132,7 @@ static struct dmar_domain *find_domain(struct device *dev)
2134 return NULL; 2132 return NULL;
2135} 2133}
2136 2134
2137static inline struct dmar_domain * 2135static inline struct device_domain_info *
2138dmar_search_domain_by_dev_info(int segment, int bus, int devfn) 2136dmar_search_domain_by_dev_info(int segment, int bus, int devfn)
2139{ 2137{
2140 struct device_domain_info *info; 2138 struct device_domain_info *info;
@@ -2142,16 +2140,17 @@ dmar_search_domain_by_dev_info(int segment, int bus, int devfn)
2142 list_for_each_entry(info, &device_domain_list, global) 2140 list_for_each_entry(info, &device_domain_list, global)
2143 if (info->segment == segment && info->bus == bus && 2141 if (info->segment == segment && info->bus == bus &&
2144 info->devfn == devfn) 2142 info->devfn == devfn)
2145 return info->domain; 2143 return info;
2146 2144
2147 return NULL; 2145 return NULL;
2148} 2146}
2149 2147
2150static struct dmar_domain *dmar_insert_dev_info(int segment, int bus, int devfn, 2148static struct dmar_domain *dmar_insert_dev_info(struct intel_iommu *iommu,
2149 int segment, int bus, int devfn,
2151 struct device *dev, 2150 struct device *dev,
2152 struct dmar_domain *domain) 2151 struct dmar_domain *domain)
2153{ 2152{
2154 struct dmar_domain *found; 2153 struct dmar_domain *found = NULL;
2155 struct device_domain_info *info; 2154 struct device_domain_info *info;
2156 unsigned long flags; 2155 unsigned long flags;
2157 2156
@@ -2164,14 +2163,19 @@ static struct dmar_domain *dmar_insert_dev_info(int segment, int bus, int devfn,
2164 info->devfn = devfn; 2163 info->devfn = devfn;
2165 info->dev = dev; 2164 info->dev = dev;
2166 info->domain = domain; 2165 info->domain = domain;
2166 info->iommu = iommu;
2167 if (!dev) 2167 if (!dev)
2168 domain->flags |= DOMAIN_FLAG_P2P_MULTIPLE_DEVICES; 2168 domain->flags |= DOMAIN_FLAG_P2P_MULTIPLE_DEVICES;
2169 2169
2170 spin_lock_irqsave(&device_domain_lock, flags); 2170 spin_lock_irqsave(&device_domain_lock, flags);
2171 if (dev) 2171 if (dev)
2172 found = find_domain(dev); 2172 found = find_domain(dev);
2173 else 2173 else {
2174 found = dmar_search_domain_by_dev_info(segment, bus, devfn); 2174 struct device_domain_info *info2;
2175 info2 = dmar_search_domain_by_dev_info(segment, bus, devfn);
2176 if (info2)
2177 found = info2->domain;
2178 }
2175 if (found) { 2179 if (found) {
2176 spin_unlock_irqrestore(&device_domain_lock, flags); 2180 spin_unlock_irqrestore(&device_domain_lock, flags);
2177 free_devinfo_mem(info); 2181 free_devinfo_mem(info);
@@ -2192,7 +2196,8 @@ static struct dmar_domain *dmar_insert_dev_info(int segment, int bus, int devfn,
2192static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) 2196static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
2193{ 2197{
2194 struct dmar_domain *domain, *free = NULL; 2198 struct dmar_domain *domain, *free = NULL;
2195 struct intel_iommu *iommu; 2199 struct intel_iommu *iommu = NULL;
2200 struct device_domain_info *info;
2196 struct dmar_drhd_unit *drhd; 2201 struct dmar_drhd_unit *drhd;
2197 struct pci_dev *dev_tmp; 2202 struct pci_dev *dev_tmp;
2198 unsigned long flags; 2203 unsigned long flags;
@@ -2215,10 +2220,13 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
2215 devfn = dev_tmp->devfn; 2220 devfn = dev_tmp->devfn;
2216 } 2221 }
2217 spin_lock_irqsave(&device_domain_lock, flags); 2222 spin_lock_irqsave(&device_domain_lock, flags);
2218 domain = dmar_search_domain_by_dev_info(segment, bus, devfn); 2223 info = dmar_search_domain_by_dev_info(segment, bus, devfn);
2224 if (info) {
2225 iommu = info->iommu;
2226 domain = info->domain;
2227 }
2219 spin_unlock_irqrestore(&device_domain_lock, flags); 2228 spin_unlock_irqrestore(&device_domain_lock, flags);
2220 /* pcie-pci bridge already has a domain, uses it */ 2229 if (info)
2221 if (domain)
2222 goto found_domain; 2230 goto found_domain;
2223 } 2231 }
2224 2232
@@ -2244,14 +2252,15 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
2244 2252
2245 /* register pcie-to-pci device */ 2253 /* register pcie-to-pci device */
2246 if (dev_tmp) { 2254 if (dev_tmp) {
2247 domain = dmar_insert_dev_info(segment, bus, devfn, NULL, domain); 2255 domain = dmar_insert_dev_info(iommu, segment, bus, devfn, NULL,
2256 domain);
2248 if (!domain) 2257 if (!domain)
2249 goto error; 2258 goto error;
2250 } 2259 }
2251 2260
2252found_domain: 2261found_domain:
2253 domain = dmar_insert_dev_info(segment, pdev->bus->number, pdev->devfn, 2262 domain = dmar_insert_dev_info(iommu, segment, pdev->bus->number,
2254 &pdev->dev, domain); 2263 pdev->devfn, &pdev->dev, domain);
2255error: 2264error:
2256 if (free != domain) 2265 if (free != domain)
2257 domain_exit(free); 2266 domain_exit(free);
@@ -2453,9 +2462,15 @@ static int domain_add_dev_info(struct dmar_domain *domain,
2453 int translation) 2462 int translation)
2454{ 2463{
2455 struct dmar_domain *ndomain; 2464 struct dmar_domain *ndomain;
2465 struct intel_iommu *iommu;
2456 int ret; 2466 int ret;
2457 2467
2458 ndomain = dmar_insert_dev_info(pci_domain_nr(pdev->bus), 2468 iommu = device_to_iommu(pci_domain_nr(pdev->bus),
2469 pdev->bus->number, pdev->devfn);
2470 if (!iommu)
2471 return -ENODEV;
2472
2473 ndomain = dmar_insert_dev_info(iommu, pci_domain_nr(pdev->bus),
2459 pdev->bus->number, pdev->devfn, 2474 pdev->bus->number, pdev->devfn,
2460 &pdev->dev, domain); 2475 &pdev->dev, domain);
2461 if (ndomain != domain) 2476 if (ndomain != domain)