mm/migrate: correct failure handling if !hugepage_migration_support()
[firefly-linux-kernel-4.4.55.git] / drivers / iommu / intel-iommu.c
index 15e9b57e9cf05ba43e19d76f37e64275d3e6db44..59779e19315e1c55eef91bdc0dbe067c1ff701c0 100644 (file)
@@ -782,7 +782,11 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
        int offset;
 
        BUG_ON(!domain->pgd);
-       BUG_ON(addr_width < BITS_PER_LONG && pfn >> addr_width);
+
+       if (addr_width < BITS_PER_LONG && pfn >> addr_width)
+               /* Address beyond IOMMU's addressing capabilities. */
+               return NULL;
+
        parent = domain->pgd;
 
        while (level > 0) {
@@ -913,7 +917,7 @@ static void dma_pte_free_level(struct dmar_domain *domain, int level,
 
                /* If range covers entire pagetable, free it */
                if (!(start_pfn > level_pfn ||
-                     last_pfn < level_pfn + level_size(level))) {
+                     last_pfn < level_pfn + level_size(level) - 1)) {
                        dma_clear_pte(pte);
                        domain_flush_cache(domain, pte, sizeof(*pte));
                        free_pgtable_page(level_pte);
@@ -3777,11 +3781,10 @@ static void iommu_detach_dependent_devices(struct intel_iommu *iommu,
 static void domain_remove_one_dev_info(struct dmar_domain *domain,
                                          struct pci_dev *pdev)
 {
-       struct device_domain_info *info;
+       struct device_domain_info *info, *tmp;
        struct intel_iommu *iommu;
        unsigned long flags;
        int found = 0;
-       struct list_head *entry, *tmp;
 
        iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number,
                                pdev->devfn);
@@ -3789,8 +3792,7 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain,
                return;
 
        spin_lock_irqsave(&device_domain_lock, flags);
-       list_for_each_safe(entry, tmp, &domain->devices) {
-               info = list_entry(entry, struct device_domain_info, link);
+       list_for_each_entry_safe(info, tmp, &domain->devices, link) {
                if (info->segment == pci_domain_nr(pdev->bus) &&
                    info->bus == pdev->bus->number &&
                    info->devfn == pdev->devfn) {