@@ -2429,6 +2429,30 @@ static size_t iommu_pgsize(struct iommu_domain *domain, unsigned long iova,
2429
2429
return pgsize ;
2430
2430
}
2431
2431
2432
+ static int __iommu_map_pages (struct iommu_domain * domain , unsigned long iova ,
2433
+ phys_addr_t paddr , size_t size , int prot ,
2434
+ gfp_t gfp , size_t * mapped )
2435
+ {
2436
+ const struct iommu_ops * ops = domain -> ops ;
2437
+ size_t pgsize , count ;
2438
+ int ret ;
2439
+
2440
+ pgsize = iommu_pgsize (domain , iova , paddr , size , & count );
2441
+
2442
+ pr_debug ("mapping: iova 0x%lx pa %pa pgsize 0x%zx count %zu\n" ,
2443
+ iova , & paddr , pgsize , count );
2444
+
2445
+ if (ops -> map_pages ) {
2446
+ ret = ops -> map_pages (domain , iova , paddr , pgsize , count , prot ,
2447
+ gfp , mapped );
2448
+ } else {
2449
+ ret = ops -> map (domain , iova , paddr , pgsize , prot , gfp );
2450
+ * mapped = ret ? 0 : pgsize ;
2451
+ }
2452
+
2453
+ return ret ;
2454
+ }
2455
+
2432
2456
static int __iommu_map (struct iommu_domain * domain , unsigned long iova ,
2433
2457
phys_addr_t paddr , size_t size , int prot , gfp_t gfp )
2434
2458
{
@@ -2439,7 +2463,7 @@ static int __iommu_map(struct iommu_domain *domain, unsigned long iova,
2439
2463
phys_addr_t orig_paddr = paddr ;
2440
2464
int ret = 0 ;
2441
2465
2442
- if (unlikely (ops -> map == NULL ||
2466
+ if (unlikely (!( ops -> map || ops -> map_pages ) ||
2443
2467
domain -> pgsize_bitmap == 0UL ))
2444
2468
return - ENODEV ;
2445
2469
@@ -2463,18 +2487,21 @@ static int __iommu_map(struct iommu_domain *domain, unsigned long iova,
2463
2487
pr_debug ("map: iova 0x%lx pa %pa size 0x%zx\n" , iova , & paddr , size );
2464
2488
2465
2489
while (size ) {
2466
- size_t pgsize = iommu_pgsize ( domain , iova , paddr , size , NULL ) ;
2490
+ size_t mapped = 0 ;
2467
2491
2468
- pr_debug ("mapping: iova 0x%lx pa %pa pgsize 0x%zx\n" ,
2469
- iova , & paddr , pgsize );
2470
- ret = ops -> map (domain , iova , paddr , pgsize , prot , gfp );
2492
+ ret = __iommu_map_pages (domain , iova , paddr , size , prot , gfp ,
2493
+ & mapped );
2494
+ /*
2495
+ * Some pages may have been mapped, even if an error occurred,
2496
+ * so we should account for those so they can be unmapped.
2497
+ */
2498
+ size -= mapped ;
2471
2499
2472
2500
if (ret )
2473
2501
break ;
2474
2502
2475
- iova += pgsize ;
2476
- paddr += pgsize ;
2477
- size -= pgsize ;
2503
+ iova += mapped ;
2504
+ paddr += mapped ;
2478
2505
}
2479
2506
2480
2507
/* unroll mapping in case something went wrong */
0 commit comments