}
 EXPORT_SYMBOL_GPL(iommu_domain_has_cap);
 
+static size_t iommu_pgsize(struct iommu_domain *domain,
+                          unsigned long addr_merge, size_t size)
+{
+       unsigned int pgsize_idx;
+       size_t pgsize;
+
+       /* Max page size that still fits into 'size' */
+       pgsize_idx = __fls(size);
+
+       /* need to consider alignment requirements ? */
+       if (likely(addr_merge)) {
+               /* Max page size allowed by address */
+               unsigned int align_pgsize_idx = __ffs(addr_merge);
+               pgsize_idx = min(pgsize_idx, align_pgsize_idx);
+       }
+
+       /* build a mask of acceptable page sizes */
+       pgsize = (1UL << (pgsize_idx + 1)) - 1;
+
+       /* throw away page sizes not supported by the hardware */
+       pgsize &= domain->ops->pgsize_bitmap;
+
+       /* make sure we're still sane */
+       BUG_ON(!pgsize);
+
+       /* pick the biggest page */
+       pgsize_idx = __fls(pgsize);
+       pgsize = 1UL << pgsize_idx;
+
+       return pgsize;
+}
+
 int iommu_map(struct iommu_domain *domain, unsigned long iova,
              phys_addr_t paddr, size_t size, int prot)
 {
                                (unsigned long)paddr, (unsigned long)size);
 
        while (size) {
-               unsigned long pgsize, addr_merge = iova | paddr;
-               unsigned int pgsize_idx;
-
-               /* Max page size that still fits into 'size' */
-               pgsize_idx = __fls(size);
-
-               /* need to consider alignment requirements ? */
-               if (likely(addr_merge)) {
-                       /* Max page size allowed by both iova and paddr */
-                       unsigned int align_pgsize_idx = __ffs(addr_merge);
-
-                       pgsize_idx = min(pgsize_idx, align_pgsize_idx);
-               }
-
-               /* build a mask of acceptable page sizes */
-               pgsize = (1UL << (pgsize_idx + 1)) - 1;
-
-               /* throw away page sizes not supported by the hardware */
-               pgsize &= domain->ops->pgsize_bitmap;
-
-               /* make sure we're still sane */
-               BUG_ON(!pgsize);
-
-               /* pick the biggest page */
-               pgsize_idx = __fls(pgsize);
-               pgsize = 1UL << pgsize_idx;
+               size_t pgsize = iommu_pgsize(domain, iova | paddr, size);
 
                pr_debug("mapping: iova 0x%lx pa 0x%lx pgsize %lu\n", iova,
                                        (unsigned long)paddr, pgsize);
         * or we hit an area that isn't mapped.
         */
        while (unmapped < size) {
-               size_t left = size - unmapped;
+               size_t pgsize = iommu_pgsize(domain, iova, size - unmapped);
 
-               unmapped_page = domain->ops->unmap(domain, iova, left);
+               unmapped_page = domain->ops->unmap(domain, iova, pgsize);
                if (!unmapped_page)
                        break;