Commit 5269519f9f05888bf52c4b71ed84d37c03c8aadb

Authored by Linus Torvalds

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

Showing 3 changed files Side-by-side Diff

drivers/iommu/arm-smmu.c
... ... @@ -1381,7 +1381,7 @@
1381 1381  
1382 1382 do {
1383 1383 next = pmd_addr_end(addr, end);
1384   - ret = arm_smmu_alloc_init_pte(smmu, pmd, addr, end, pfn,
  1384 + ret = arm_smmu_alloc_init_pte(smmu, pmd, addr, next, pfn,
1385 1385 prot, stage);
1386 1386 phys += next - addr;
1387 1387 } while (pmd++, addr = next, addr < end);
... ... @@ -1499,7 +1499,7 @@
1499 1499  
1500 1500 ret = arm_smmu_handle_mapping(smmu_domain, iova, 0, size, 0);
1501 1501 arm_smmu_tlb_inv_context(&smmu_domain->root_cfg);
1502   - return ret ? ret : size;
  1502 + return ret ? 0 : size;
1503 1503 }
1504 1504  
1505 1505 static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain,
drivers/iommu/dmar.c
... ... @@ -152,7 +152,8 @@
152 152 info->seg = pci_domain_nr(dev->bus);
153 153 info->level = level;
154 154 if (event == BUS_NOTIFY_ADD_DEVICE) {
155   - for (tmp = dev, level--; tmp; tmp = tmp->bus->self) {
  155 + for (tmp = dev; tmp; tmp = tmp->bus->self) {
  156 + level--;
156 157 info->path[level].device = PCI_SLOT(tmp->devfn);
157 158 info->path[level].function = PCI_FUNC(tmp->devfn);
158 159 if (pci_is_root_bus(tmp->bus))
drivers/iommu/intel-iommu.c
... ... @@ -1009,11 +1009,13 @@
1009 1009 if (level == 1)
1010 1010 return freelist;
1011 1011  
1012   - for (pte = page_address(pg); !first_pte_in_page(pte); pte++) {
  1012 + pte = page_address(pg);
  1013 + do {
1013 1014 if (dma_pte_present(pte) && !dma_pte_superpage(pte))
1014 1015 freelist = dma_pte_list_pagetables(domain, level - 1,
1015 1016 pte, freelist);
1016   - }
  1017 + pte++;
  1018 + } while (!first_pte_in_page(pte));
1017 1019  
1018 1020 return freelist;
1019 1021 }
... ... @@ -2235,7 +2237,9 @@
2235 2237 bridge_devfn = dev_tmp->devfn;
2236 2238 }
2237 2239 spin_lock_irqsave(&device_domain_lock, flags);
2238   - info = dmar_search_domain_by_dev_info(segment, bus, devfn);
  2240 + info = dmar_search_domain_by_dev_info(segment,
  2241 + bridge_bus,
  2242 + bridge_devfn);
2239 2243 if (info) {
2240 2244 iommu = info->iommu;
2241 2245 domain = info->domain;