diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-20 10:33:49 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-20 10:33:49 -0700 |
commit | 5269519f9f05888bf52c4b71ed84d37c03c8aadb (patch) | |
tree | c8f00a768b05ef31d1cc65b8e9c9f124c1648a5a | |
parent | 200bde278d78318cbd10cd865f94016924e76c56 (diff) | |
parent | 3426cb3d3578eab55ec231e0ce4dfc12ec3abc1f (diff) |
Merge tag 'iommu-fixes-v3.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull iommu fixes from Joerg Roedel:
"Fixes for regressions:
- fix wrong IOMMU enumeration causing some SCSI device drivers
initialization failures
- ARM-SMMU fixes for a panic condition and a wrong return value"
* tag 'iommu-fixes-v3.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu:
iommu/arm-smmu: fix panic in arm_smmu_alloc_init_pte
iommu/arm-smmu: Return 0 on unmap failure
iommu/vt-d: fix bug in matching PCI devices with DRHD/RMRR descriptors
iommu/vt-d: Fix get_domain_for_dev() handling of upstream PCIe bridges
iommu/vt-d: fix memory leakage caused by commit ea8ea46
-rw-r--r-- | drivers/iommu/arm-smmu.c | 4 | ||||
-rw-r--r-- | drivers/iommu/dmar.c | 3 | ||||
-rw-r--r-- | drivers/iommu/intel-iommu.c | 10 |
3 files changed, 11 insertions, 6 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 8b89e33a89fe..647c3c7fd742 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1381,7 +1381,7 @@ static int arm_smmu_alloc_init_pmd(struct arm_smmu_device *smmu, pud_t *pud, do { next = pmd_addr_end(addr, end); - ret = arm_smmu_alloc_init_pte(smmu, pmd, addr, end, pfn, + ret = arm_smmu_alloc_init_pte(smmu, pmd, addr, next, pfn, prot, stage); phys += next - addr; } while (pmd++, addr = next, addr < end); @@ -1499,7 +1499,7 @@ static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova, ret = arm_smmu_handle_mapping(smmu_domain, iova, 0, size, 0); arm_smmu_tlb_inv_context(&smmu_domain->root_cfg); - return ret ? ret : size; + return ret ? 0 : size; } static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain, diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index f445c10df8df..39f8b717fe84 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -152,7 +152,8 @@ dmar_alloc_pci_notify_info(struct pci_dev *dev, unsigned long event) info->seg = pci_domain_nr(dev->bus); info->level = level; if (event == BUS_NOTIFY_ADD_DEVICE) { - for (tmp = dev, level--; tmp; tmp = tmp->bus->self) { + for (tmp = dev; tmp; tmp = tmp->bus->self) { + level--; info->path[level].device = PCI_SLOT(tmp->devfn); info->path[level].function = PCI_FUNC(tmp->devfn); if (pci_is_root_bus(tmp->bus)) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 69fa7da5e48b..f256ffc02e29 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -1009,11 +1009,13 @@ static struct page *dma_pte_list_pagetables(struct dmar_domain *domain, if (level == 1) return freelist; - for (pte = page_address(pg); !first_pte_in_page(pte); pte++) { + pte = page_address(pg); + do { if (dma_pte_present(pte) && !dma_pte_superpage(pte)) freelist = dma_pte_list_pagetables(domain, level - 1, pte, freelist); - } + pte++; + } while (!first_pte_in_page(pte)); return freelist; } @@ -2235,7 +2237,9 @@ static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw) bridge_devfn = dev_tmp->devfn; } spin_lock_irqsave(&device_domain_lock, flags); - info = dmar_search_domain_by_dev_info(segment, bus, devfn); + info = dmar_search_domain_by_dev_info(segment, + bridge_bus, + bridge_devfn); if (info) { iommu = info->iommu; domain = info->domain; |