diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2014-03-09 18:44:17 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2014-03-24 10:07:52 -0400 |
commit | 146922ec798de6484897a43fc6180e49c425f183 (patch) | |
tree | 653fed54d03ffa3ef6ee524e028d014df4c4a3f9 /drivers/iommu | |
parent | e1f167f3fd69d794b570fc4d3159191568ff9b70 (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.c | 75 |
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 */ |
2210 | static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) | 2210 | static 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 | ||
2275 | found_domain: | 2274 | found_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); | ||
2278 | error: | 2276 | error: |
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)); |