aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2014-03-09 18:44:17 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2014-03-24 10:07:52 -0400
commit146922ec798de6484897a43fc6180e49c425f183 (patch)
tree653fed54d03ffa3ef6ee524e028d014df4c4a3f9 /drivers/iommu
parente1f167f3fd69d794b570fc4d3159191568ff9b70 (diff)
iommu/vt-d: Make get_domain_for_dev() take struct device
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/iommu')
-rw-r--r--drivers/iommu/intel-iommu.c75
1 files changed, 36 insertions, 39 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 949aa29dba8b..1c5f656ff19d 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2207,52 +2207,51 @@ static struct dmar_domain *dmar_insert_dev_info(struct intel_iommu *iommu,
2207} 2207}
2208 2208
2209/* domain is initialized */ 2209/* domain is initialized */
2210static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) 2210static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
2211{ 2211{
2212 struct dmar_domain *domain, *free = NULL; 2212 struct dmar_domain *domain, *free = NULL;
2213 struct intel_iommu *iommu = NULL; 2213 struct intel_iommu *iommu = NULL;
2214 struct device_domain_info *info; 2214 struct device_domain_info *info;
2215 struct dmar_drhd_unit *drhd; 2215 struct pci_dev *dev_tmp = NULL;
2216 struct pci_dev *dev_tmp;
2217 unsigned long flags; 2216 unsigned long flags;
2218 int bus = 0, devfn = 0; 2217 u8 bus, devfn, bridge_bus, bridge_devfn;
2219 int segment;
2220 2218
2221 domain = find_domain(&pdev->dev); 2219 domain = find_domain(dev);
2222 if (domain) 2220 if (domain)
2223 return domain; 2221 return domain;
2224 2222
2225 segment = pci_domain_nr(pdev->bus); 2223 if (dev_is_pci(dev)) {
2224 struct pci_dev *pdev = to_pci_dev(dev);
2225 u16 segment;
2226 2226
2227 dev_tmp = pci_find_upstream_pcie_bridge(pdev); 2227 segment = pci_domain_nr(pdev->bus);
2228 if (dev_tmp) { 2228 dev_tmp = pci_find_upstream_pcie_bridge(pdev);
2229 if (pci_is_pcie(dev_tmp)) { 2229 if (dev_tmp) {
2230 bus = dev_tmp->subordinate->number; 2230 if (pci_is_pcie(dev_tmp)) {
2231 devfn = 0; 2231 bridge_bus = dev_tmp->subordinate->number;
2232 } else { 2232 bridge_devfn = 0;
2233 bus = dev_tmp->bus->number; 2233 } else {
2234 devfn = dev_tmp->devfn; 2234 bridge_bus = dev_tmp->bus->number;
2235 } 2235 bridge_devfn = dev_tmp->devfn;
2236 spin_lock_irqsave(&device_domain_lock, flags); 2236 }
2237 info = dmar_search_domain_by_dev_info(segment, bus, devfn); 2237 spin_lock_irqsave(&device_domain_lock, flags);
2238 if (info) { 2238 info = dmar_search_domain_by_dev_info(segment, bus, devfn);
2239 iommu = info->iommu; 2239 if (info) {
2240 domain = info->domain; 2240 iommu = info->iommu;
2241 domain = info->domain;
2242 }
2243 spin_unlock_irqrestore(&device_domain_lock, flags);
2244 /* pcie-pci bridge already has a domain, uses it */
2245 if (info)
2246 goto found_domain;
2241 } 2247 }
2242 spin_unlock_irqrestore(&device_domain_lock, flags);
2243 if (info)
2244 goto found_domain;
2245 } 2248 }
2246 2249
2247 drhd = dmar_find_matched_drhd_unit(pdev); 2250 iommu = device_to_iommu(dev, &bus, &devfn);
2248 if (!drhd) { 2251 if (!iommu)
2249 printk(KERN_ERR "IOMMU: can't find DMAR for device %s\n", 2252 goto error;
2250 pci_name(pdev));
2251 return NULL;
2252 }
2253 iommu = drhd->iommu;
2254 2253
2255 /* Allocate and intialize new domain for the device */ 2254 /* Allocate and initialize new domain for the device */
2256 domain = alloc_domain(false); 2255 domain = alloc_domain(false);
2257 if (!domain) 2256 if (!domain)
2258 goto error; 2257 goto error;
@@ -2266,15 +2265,14 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
2266 2265
2267 /* register pcie-to-pci device */ 2266 /* register pcie-to-pci device */
2268 if (dev_tmp) { 2267 if (dev_tmp) {
2269 domain = dmar_insert_dev_info(iommu, bus, devfn, NULL, 2268 domain = dmar_insert_dev_info(iommu, bridge_bus, bridge_devfn,
2270 domain); 2269 NULL, domain);
2271 if (!domain) 2270 if (!domain)
2272 goto error; 2271 goto error;
2273 } 2272 }
2274 2273
2275found_domain: 2274found_domain:
2276 domain = dmar_insert_dev_info(iommu, pdev->bus->number, 2275 domain = dmar_insert_dev_info(iommu, bus, devfn, dev, domain);
2277 pdev->devfn, &pdev->dev, domain);
2278error: 2276error:
2279 if (free != domain) 2277 if (free != domain)
2280 domain_exit(free); 2278 domain_exit(free);
@@ -2320,7 +2318,7 @@ static int iommu_prepare_identity_map(struct pci_dev *pdev,
2320 struct dmar_domain *domain; 2318 struct dmar_domain *domain;
2321 int ret; 2319 int ret;
2322 2320
2323 domain = get_domain_for_dev(pdev, DEFAULT_DOMAIN_ADDRESS_WIDTH); 2321 domain = get_domain_for_dev(&pdev->dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
2324 if (!domain) 2322 if (!domain)
2325 return -ENOMEM; 2323 return -ENOMEM;
2326 2324
@@ -2864,8 +2862,7 @@ static struct dmar_domain *__get_valid_domain_for_dev(struct pci_dev *pdev)
2864 struct dmar_domain *domain; 2862 struct dmar_domain *domain;
2865 int ret; 2863 int ret;
2866 2864
2867 domain = get_domain_for_dev(pdev, 2865 domain = get_domain_for_dev(&pdev->dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
2868 DEFAULT_DOMAIN_ADDRESS_WIDTH);
2869 if (!domain) { 2866 if (!domain) {
2870 printk(KERN_ERR 2867 printk(KERN_ERR
2871 "Allocating domain for %s failed", pci_name(pdev)); 2868 "Allocating domain for %s failed", pci_name(pdev));