aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2009-08-09 05:53:41 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2009-08-09 05:53:50 -0400
commit5fe60f4e5871b64e687229199fafd4ef13cd0886 (patch)
tree8a4967096922ffbed25d4918ab9ddefebbee215b /drivers/pci
parenta131bc185528331451a93db6c50a7d2070376a61 (diff)
intel-iommu: make domain_add_dev_info() call domain_context_mapping()
All callers of the former were also calling the latter, in one order or the other, and failing to correctly clean up if the second returned failure. Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/intel-iommu.c35
1 files changed, 15 insertions, 20 deletions
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index 3f256b8d83c1..09606e9aedec 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -2094,15 +2094,23 @@ static int identity_mapping(struct pci_dev *pdev)
2094} 2094}
2095 2095
2096static int domain_add_dev_info(struct dmar_domain *domain, 2096static int domain_add_dev_info(struct dmar_domain *domain,
2097 struct pci_dev *pdev) 2097 struct pci_dev *pdev,
2098 int translation)
2098{ 2099{
2099 struct device_domain_info *info; 2100 struct device_domain_info *info;
2100 unsigned long flags; 2101 unsigned long flags;
2102 int ret;
2101 2103
2102 info = alloc_devinfo_mem(); 2104 info = alloc_devinfo_mem();
2103 if (!info) 2105 if (!info)
2104 return -ENOMEM; 2106 return -ENOMEM;
2105 2107
2108 ret = domain_context_mapping(domain, pdev, translation);
2109 if (ret) {
2110 free_devinfo_mem(info);
2111 return ret;
2112 }
2113
2106 info->segment = pci_domain_nr(pdev->bus); 2114 info->segment = pci_domain_nr(pdev->bus);
2107 info->bus = pdev->bus->number; 2115 info->bus = pdev->bus->number;
2108 info->devfn = pdev->devfn; 2116 info->devfn = pdev->devfn;
@@ -2173,15 +2181,11 @@ static int iommu_prepare_static_identity_mapping(int hw)
2173 printk(KERN_INFO "IOMMU: %s identity mapping for device %s\n", 2181 printk(KERN_INFO "IOMMU: %s identity mapping for device %s\n",
2174 hw ? "hardware" : "software", pci_name(pdev)); 2182 hw ? "hardware" : "software", pci_name(pdev));
2175 2183
2176 ret = domain_context_mapping(si_domain, pdev, 2184 ret = domain_add_dev_info(si_domain, pdev,
2177 hw ? CONTEXT_TT_PASS_THROUGH : 2185 hw ? CONTEXT_TT_PASS_THROUGH :
2178 CONTEXT_TT_MULTI_LEVEL); 2186 CONTEXT_TT_MULTI_LEVEL);
2179 if (ret) 2187 if (ret)
2180 return ret; 2188 return ret;
2181
2182 ret = domain_add_dev_info(si_domain, pdev);
2183 if (ret)
2184 return ret;
2185 } 2189 }
2186 } 2190 }
2187 2191
@@ -2510,13 +2514,10 @@ static int iommu_no_mapping(struct device *dev)
2510 */ 2514 */
2511 if (iommu_should_identity_map(pdev, 0)) { 2515 if (iommu_should_identity_map(pdev, 0)) {
2512 int ret; 2516 int ret;
2513 ret = domain_add_dev_info(si_domain, pdev); 2517 ret = domain_add_dev_info(si_domain, pdev,
2514 if (ret) 2518 hw_pass_through ?
2515 return 0; 2519 CONTEXT_TT_PASS_THROUGH :
2516 ret = domain_context_mapping(si_domain, pdev, 2520 CONTEXT_TT_MULTI_LEVEL);
2517 hw_pass_through ?
2518 CONTEXT_TT_PASS_THROUGH :
2519 CONTEXT_TT_MULTI_LEVEL);
2520 if (!ret) { 2521 if (!ret) {
2521 printk(KERN_INFO "64bit %s uses identity mapping\n", 2522 printk(KERN_INFO "64bit %s uses identity mapping\n",
2522 pci_name(pdev)); 2523 pci_name(pdev));
@@ -3486,7 +3487,6 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
3486 struct intel_iommu *iommu; 3487 struct intel_iommu *iommu;
3487 int addr_width; 3488 int addr_width;
3488 u64 end; 3489 u64 end;
3489 int ret;
3490 3490
3491 /* normally pdev is not mapped */ 3491 /* normally pdev is not mapped */
3492 if (unlikely(domain_context_mapped(pdev))) { 3492 if (unlikely(domain_context_mapped(pdev))) {
@@ -3518,12 +3518,7 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
3518 return -EFAULT; 3518 return -EFAULT;
3519 } 3519 }
3520 3520
3521 ret = domain_add_dev_info(dmar_domain, pdev); 3521 return domain_add_dev_info(dmar_domain, pdev, CONTEXT_TT_MULTI_LEVEL);
3522 if (ret)
3523 return ret;
3524
3525 ret = domain_context_mapping(dmar_domain, pdev, CONTEXT_TT_MULTI_LEVEL);
3526 return ret;
3527} 3522}
3528 3523
3529static void intel_iommu_detach_device(struct iommu_domain *domain, 3524static void intel_iommu_detach_device(struct iommu_domain *domain,