diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2014-03-06 12:12:03 -0500 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2014-03-24 10:06:36 -0400 |
commit | 0bcb3e28c3c9b06a3ffab6238c517acdc851e625 (patch) | |
tree | 73bd6b293d54082081280ca3d01b0e986a60b4c2 /drivers/iommu | |
parent | 1525a29a7d619901aed0dc5f1eb0592fc881805a (diff) |
iommu/vt-d: Use struct device in device_domain_info, not struct pci_dev
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/iommu')
-rw-r--r-- | drivers/iommu/intel-iommu.c | 54 |
1 files changed, 32 insertions, 22 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 40dbafd376fb..dc84147cd5c9 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -372,7 +372,7 @@ struct device_domain_info { | |||
372 | int segment; /* PCI domain */ | 372 | int segment; /* PCI domain */ |
373 | u8 bus; /* PCI bus number */ | 373 | u8 bus; /* PCI bus number */ |
374 | u8 devfn; /* PCI devfn number */ | 374 | u8 devfn; /* PCI devfn number */ |
375 | struct pci_dev *dev; /* it's NULL for PCIe-to-PCI bridge */ | 375 | struct device *dev; /* it's NULL for PCIe-to-PCI bridge */ |
376 | struct intel_iommu *iommu; /* IOMMU used by this device */ | 376 | struct intel_iommu *iommu; /* IOMMU used by this device */ |
377 | struct dmar_domain *domain; /* pointer to domain */ | 377 | struct dmar_domain *domain; /* pointer to domain */ |
378 | }; | 378 | }; |
@@ -428,7 +428,7 @@ static void domain_remove_dev_info(struct dmar_domain *domain); | |||
428 | static void domain_remove_one_dev_info(struct dmar_domain *domain, | 428 | static void domain_remove_one_dev_info(struct dmar_domain *domain, |
429 | struct pci_dev *pdev); | 429 | struct pci_dev *pdev); |
430 | static void iommu_detach_dependent_devices(struct intel_iommu *iommu, | 430 | static void iommu_detach_dependent_devices(struct intel_iommu *iommu, |
431 | struct pci_dev *pdev); | 431 | struct device *dev); |
432 | 432 | ||
433 | #ifdef CONFIG_INTEL_IOMMU_DEFAULT_ON | 433 | #ifdef CONFIG_INTEL_IOMMU_DEFAULT_ON |
434 | int dmar_disabled = 0; | 434 | int dmar_disabled = 0; |
@@ -1247,6 +1247,7 @@ static struct device_domain_info *iommu_support_dev_iotlb( | |||
1247 | unsigned long flags; | 1247 | unsigned long flags; |
1248 | struct device_domain_info *info; | 1248 | struct device_domain_info *info; |
1249 | struct intel_iommu *iommu = device_to_iommu(segment, bus, devfn); | 1249 | struct intel_iommu *iommu = device_to_iommu(segment, bus, devfn); |
1250 | struct pci_dev *pdev; | ||
1250 | 1251 | ||
1251 | if (!ecap_dev_iotlb_support(iommu->ecap)) | 1252 | if (!ecap_dev_iotlb_support(iommu->ecap)) |
1252 | return NULL; | 1253 | return NULL; |
@@ -1262,13 +1263,15 @@ static struct device_domain_info *iommu_support_dev_iotlb( | |||
1262 | } | 1263 | } |
1263 | spin_unlock_irqrestore(&device_domain_lock, flags); | 1264 | spin_unlock_irqrestore(&device_domain_lock, flags); |
1264 | 1265 | ||
1265 | if (!found || !info->dev) | 1266 | if (!found || !info->dev || !dev_is_pci(info->dev)) |
1266 | return NULL; | 1267 | return NULL; |
1267 | 1268 | ||
1268 | if (!pci_find_ext_capability(info->dev, PCI_EXT_CAP_ID_ATS)) | 1269 | pdev = to_pci_dev(info->dev); |
1270 | |||
1271 | if (!pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ATS)) | ||
1269 | return NULL; | 1272 | return NULL; |
1270 | 1273 | ||
1271 | if (!dmar_find_matched_atsr_unit(info->dev)) | 1274 | if (!dmar_find_matched_atsr_unit(pdev)) |
1272 | return NULL; | 1275 | return NULL; |
1273 | 1276 | ||
1274 | info->iommu = iommu; | 1277 | info->iommu = iommu; |
@@ -1278,18 +1281,19 @@ static struct device_domain_info *iommu_support_dev_iotlb( | |||
1278 | 1281 | ||
1279 | static void iommu_enable_dev_iotlb(struct device_domain_info *info) | 1282 | static void iommu_enable_dev_iotlb(struct device_domain_info *info) |
1280 | { | 1283 | { |
1281 | if (!info) | 1284 | if (!info || !dev_is_pci(info->dev)) |
1282 | return; | 1285 | return; |
1283 | 1286 | ||
1284 | pci_enable_ats(info->dev, VTD_PAGE_SHIFT); | 1287 | pci_enable_ats(to_pci_dev(info->dev), VTD_PAGE_SHIFT); |
1285 | } | 1288 | } |
1286 | 1289 | ||
1287 | static void iommu_disable_dev_iotlb(struct device_domain_info *info) | 1290 | static void iommu_disable_dev_iotlb(struct device_domain_info *info) |
1288 | { | 1291 | { |
1289 | if (!info->dev || !pci_ats_enabled(info->dev)) | 1292 | if (!info->dev || !dev_is_pci(info->dev) || |
1293 | !pci_ats_enabled(to_pci_dev(info->dev))) | ||
1290 | return; | 1294 | return; |
1291 | 1295 | ||
1292 | pci_disable_ats(info->dev); | 1296 | pci_disable_ats(to_pci_dev(info->dev)); |
1293 | } | 1297 | } |
1294 | 1298 | ||
1295 | static void iommu_flush_dev_iotlb(struct dmar_domain *domain, | 1299 | static void iommu_flush_dev_iotlb(struct dmar_domain *domain, |
@@ -1301,11 +1305,16 @@ static void iommu_flush_dev_iotlb(struct dmar_domain *domain, | |||
1301 | 1305 | ||
1302 | spin_lock_irqsave(&device_domain_lock, flags); | 1306 | spin_lock_irqsave(&device_domain_lock, flags); |
1303 | list_for_each_entry(info, &domain->devices, link) { | 1307 | list_for_each_entry(info, &domain->devices, link) { |
1304 | if (!info->dev || !pci_ats_enabled(info->dev)) | 1308 | struct pci_dev *pdev; |
1309 | if (!info->dev || !dev_is_pci(info->dev)) | ||
1310 | continue; | ||
1311 | |||
1312 | pdev = to_pci_dev(info->dev); | ||
1313 | if (!pci_ats_enabled(pdev)) | ||
1305 | continue; | 1314 | continue; |
1306 | 1315 | ||
1307 | sid = info->bus << 8 | info->devfn; | 1316 | sid = info->bus << 8 | info->devfn; |
1308 | qdep = pci_ats_queue_depth(info->dev); | 1317 | qdep = pci_ats_queue_depth(pdev); |
1309 | qi_flush_dev_iotlb(info->iommu, sid, qdep, addr, mask); | 1318 | qi_flush_dev_iotlb(info->iommu, sid, qdep, addr, mask); |
1310 | } | 1319 | } |
1311 | spin_unlock_irqrestore(&device_domain_lock, flags); | 1320 | spin_unlock_irqrestore(&device_domain_lock, flags); |
@@ -2071,7 +2080,7 @@ static inline void unlink_domain_info(struct device_domain_info *info) | |||
2071 | list_del(&info->link); | 2080 | list_del(&info->link); |
2072 | list_del(&info->global); | 2081 | list_del(&info->global); |
2073 | if (info->dev) | 2082 | if (info->dev) |
2074 | info->dev->dev.archdata.iommu = NULL; | 2083 | info->dev->archdata.iommu = NULL; |
2075 | } | 2084 | } |
2076 | 2085 | ||
2077 | static void domain_remove_dev_info(struct dmar_domain *domain) | 2086 | static void domain_remove_dev_info(struct dmar_domain *domain) |
@@ -2140,7 +2149,7 @@ dmar_search_domain_by_dev_info(int segment, int bus, int devfn) | |||
2140 | } | 2149 | } |
2141 | 2150 | ||
2142 | static int dmar_insert_dev_info(int segment, int bus, int devfn, | 2151 | static int dmar_insert_dev_info(int segment, int bus, int devfn, |
2143 | struct pci_dev *dev, struct dmar_domain **domp) | 2152 | struct device *dev, struct dmar_domain **domp) |
2144 | { | 2153 | { |
2145 | struct dmar_domain *found, *domain = *domp; | 2154 | struct dmar_domain *found, *domain = *domp; |
2146 | struct device_domain_info *info; | 2155 | struct device_domain_info *info; |
@@ -2160,7 +2169,7 @@ static int dmar_insert_dev_info(int segment, int bus, int devfn, | |||
2160 | 2169 | ||
2161 | spin_lock_irqsave(&device_domain_lock, flags); | 2170 | spin_lock_irqsave(&device_domain_lock, flags); |
2162 | if (dev) | 2171 | if (dev) |
2163 | found = find_domain(&dev->dev); | 2172 | found = find_domain(dev); |
2164 | else | 2173 | else |
2165 | found = dmar_search_domain_by_dev_info(segment, bus, devfn); | 2174 | found = dmar_search_domain_by_dev_info(segment, bus, devfn); |
2166 | if (found) { | 2175 | if (found) { |
@@ -2174,7 +2183,7 @@ static int dmar_insert_dev_info(int segment, int bus, int devfn, | |||
2174 | list_add(&info->link, &domain->devices); | 2183 | list_add(&info->link, &domain->devices); |
2175 | list_add(&info->global, &device_domain_list); | 2184 | list_add(&info->global, &device_domain_list); |
2176 | if (dev) | 2185 | if (dev) |
2177 | dev->dev.archdata.iommu = info; | 2186 | dev->archdata.iommu = info; |
2178 | spin_unlock_irqrestore(&device_domain_lock, flags); | 2187 | spin_unlock_irqrestore(&device_domain_lock, flags); |
2179 | } | 2188 | } |
2180 | 2189 | ||
@@ -2245,7 +2254,7 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) | |||
2245 | 2254 | ||
2246 | found_domain: | 2255 | found_domain: |
2247 | if (dmar_insert_dev_info(segment, pdev->bus->number, pdev->devfn, | 2256 | if (dmar_insert_dev_info(segment, pdev->bus->number, pdev->devfn, |
2248 | pdev, &domain) == 0) | 2257 | &pdev->dev, &domain) == 0) |
2249 | return domain; | 2258 | return domain; |
2250 | error: | 2259 | error: |
2251 | if (free) | 2260 | if (free) |
@@ -2458,7 +2467,7 @@ static int domain_add_dev_info(struct dmar_domain *domain, | |||
2458 | info->segment = pci_domain_nr(pdev->bus); | 2467 | info->segment = pci_domain_nr(pdev->bus); |
2459 | info->bus = pdev->bus->number; | 2468 | info->bus = pdev->bus->number; |
2460 | info->devfn = pdev->devfn; | 2469 | info->devfn = pdev->devfn; |
2461 | info->dev = pdev; | 2470 | info->dev = &pdev->dev; |
2462 | info->domain = domain; | 2471 | info->domain = domain; |
2463 | 2472 | ||
2464 | spin_lock_irqsave(&device_domain_lock, flags); | 2473 | spin_lock_irqsave(&device_domain_lock, flags); |
@@ -3189,7 +3198,6 @@ static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist, | |||
3189 | int nelems, enum dma_data_direction dir, | 3198 | int nelems, enum dma_data_direction dir, |
3190 | struct dma_attrs *attrs) | 3199 | struct dma_attrs *attrs) |
3191 | { | 3200 | { |
3192 | struct pci_dev *pdev = to_pci_dev(hwdev); | ||
3193 | struct dmar_domain *domain; | 3201 | struct dmar_domain *domain; |
3194 | unsigned long start_pfn, last_pfn; | 3202 | unsigned long start_pfn, last_pfn; |
3195 | struct iova *iova; | 3203 | struct iova *iova; |
@@ -3985,13 +3993,15 @@ out_free_dmar: | |||
3985 | } | 3993 | } |
3986 | 3994 | ||
3987 | static void iommu_detach_dependent_devices(struct intel_iommu *iommu, | 3995 | static void iommu_detach_dependent_devices(struct intel_iommu *iommu, |
3988 | struct pci_dev *pdev) | 3996 | struct device *dev) |
3989 | { | 3997 | { |
3990 | struct pci_dev *tmp, *parent; | 3998 | struct pci_dev *tmp, *parent, *pdev; |
3991 | 3999 | ||
3992 | if (!iommu || !pdev) | 4000 | if (!iommu || !dev || !dev_is_pci(dev)) |
3993 | return; | 4001 | return; |
3994 | 4002 | ||
4003 | pdev = to_pci_dev(dev); | ||
4004 | |||
3995 | /* dependent device detach */ | 4005 | /* dependent device detach */ |
3996 | tmp = pci_find_upstream_pcie_bridge(pdev); | 4006 | tmp = pci_find_upstream_pcie_bridge(pdev); |
3997 | /* Secondary interface's bus number and devfn 0 */ | 4007 | /* Secondary interface's bus number and devfn 0 */ |
@@ -4034,7 +4044,7 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain, | |||
4034 | 4044 | ||
4035 | iommu_disable_dev_iotlb(info); | 4045 | iommu_disable_dev_iotlb(info); |
4036 | iommu_detach_dev(iommu, info->bus, info->devfn); | 4046 | iommu_detach_dev(iommu, info->bus, info->devfn); |
4037 | iommu_detach_dependent_devices(iommu, pdev); | 4047 | iommu_detach_dependent_devices(iommu, &pdev->dev); |
4038 | free_devinfo_mem(info); | 4048 | free_devinfo_mem(info); |
4039 | 4049 | ||
4040 | spin_lock_irqsave(&device_domain_lock, flags); | 4050 | spin_lock_irqsave(&device_domain_lock, flags); |