aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2014-03-06 12:12:03 -0500
committerDavid Woodhouse <David.Woodhouse@intel.com>2014-03-24 10:06:36 -0400
commit0bcb3e28c3c9b06a3ffab6238c517acdc851e625 (patch)
tree73bd6b293d54082081280ca3d01b0e986a60b4c2 /drivers/iommu
parent1525a29a7d619901aed0dc5f1eb0592fc881805a (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.c54
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);
428static void domain_remove_one_dev_info(struct dmar_domain *domain, 428static void domain_remove_one_dev_info(struct dmar_domain *domain,
429 struct pci_dev *pdev); 429 struct pci_dev *pdev);
430static void iommu_detach_dependent_devices(struct intel_iommu *iommu, 430static 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
434int dmar_disabled = 0; 434int 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
1279static void iommu_enable_dev_iotlb(struct device_domain_info *info) 1282static 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
1287static void iommu_disable_dev_iotlb(struct device_domain_info *info) 1290static 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
1295static void iommu_flush_dev_iotlb(struct dmar_domain *domain, 1299static 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
2077static void domain_remove_dev_info(struct dmar_domain *domain) 2086static 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
2142static int dmar_insert_dev_info(int segment, int bus, int devfn, 2151static 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
2246found_domain: 2255found_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;
2250error: 2259error:
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
3987static void iommu_detach_dependent_devices(struct intel_iommu *iommu, 3995static 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);