@@ -341,20 +341,30 @@ static arm_lpae_iopte arm_lpae_install_table(arm_lpae_iopte *table,
341
341
}
342
342
343
343
static int __arm_lpae_map (struct arm_lpae_io_pgtable * data , unsigned long iova ,
344
- phys_addr_t paddr , size_t size , arm_lpae_iopte prot ,
345
- int lvl , arm_lpae_iopte * ptep , gfp_t gfp )
344
+ phys_addr_t paddr , size_t size , size_t pgcount ,
345
+ arm_lpae_iopte prot , int lvl , arm_lpae_iopte * ptep ,
346
+ gfp_t gfp , size_t * mapped )
346
347
{
347
348
arm_lpae_iopte * cptep , pte ;
348
349
size_t block_size = ARM_LPAE_BLOCK_SIZE (lvl , data );
349
350
size_t tblsz = ARM_LPAE_GRANULE (data );
350
351
struct io_pgtable_cfg * cfg = & data -> iop .cfg ;
352
+ int ret = 0 , num_entries , max_entries , map_idx_start ;
351
353
352
354
/* Find our entry at the current level */
353
- ptep += ARM_LPAE_LVL_IDX (iova , lvl , data );
355
+ map_idx_start = ARM_LPAE_LVL_IDX (iova , lvl , data );
356
+ ptep += map_idx_start ;
354
357
355
358
/* If we can install a leaf entry at this level, then do so */
356
- if (size == block_size )
357
- return arm_lpae_init_pte (data , iova , paddr , prot , lvl , 1 , ptep );
359
+ if (size == block_size ) {
360
+ max_entries = ARM_LPAE_PTES_PER_TABLE (data ) - map_idx_start ;
361
+ num_entries = min_t (int , pgcount , max_entries );
362
+ ret = arm_lpae_init_pte (data , iova , paddr , prot , lvl , num_entries , ptep );
363
+ if (!ret && mapped )
364
+ * mapped += num_entries * size ;
365
+
366
+ return ret ;
367
+ }
358
368
359
369
/* We can't allocate tables at the final level */
360
370
if (WARN_ON (lvl >= ARM_LPAE_MAX_LEVELS - 1 ))
@@ -383,7 +393,8 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova,
383
393
}
384
394
385
395
/* Rinse, repeat */
386
- return __arm_lpae_map (data , iova , paddr , size , prot , lvl + 1 , cptep , gfp );
396
+ return __arm_lpae_map (data , iova , paddr , size , pgcount , prot , lvl + 1 ,
397
+ cptep , gfp , mapped );
387
398
}
388
399
389
400
static arm_lpae_iopte arm_lpae_prot_to_pte (struct arm_lpae_io_pgtable * data ,
@@ -450,8 +461,9 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data,
450
461
return pte ;
451
462
}
452
463
453
- static int arm_lpae_map (struct io_pgtable_ops * ops , unsigned long iova ,
454
- phys_addr_t paddr , size_t size , int iommu_prot , gfp_t gfp )
464
+ static int arm_lpae_map_pages (struct io_pgtable_ops * ops , unsigned long iova ,
465
+ phys_addr_t paddr , size_t pgsize , size_t pgcount ,
466
+ int iommu_prot , gfp_t gfp , size_t * mapped )
455
467
{
456
468
struct arm_lpae_io_pgtable * data = io_pgtable_ops_to_data (ops );
457
469
struct io_pgtable_cfg * cfg = & data -> iop .cfg ;
@@ -460,7 +472,7 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova,
460
472
arm_lpae_iopte prot ;
461
473
long iaext = (s64 )iova >> cfg -> ias ;
462
474
463
- if (WARN_ON (!size || (size & cfg -> pgsize_bitmap ) != size ))
475
+ if (WARN_ON (!pgsize || (pgsize & cfg -> pgsize_bitmap ) != pgsize ))
464
476
return - EINVAL ;
465
477
466
478
if (cfg -> quirks & IO_PGTABLE_QUIRK_ARM_TTBR1 )
@@ -473,7 +485,8 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova,
473
485
return 0 ;
474
486
475
487
prot = arm_lpae_prot_to_pte (data , iommu_prot );
476
- ret = __arm_lpae_map (data , iova , paddr , size , prot , lvl , ptep , gfp );
488
+ ret = __arm_lpae_map (data , iova , paddr , pgsize , pgcount , prot , lvl ,
489
+ ptep , gfp , mapped );
477
490
/*
478
491
* Synchronise all PTE updates for the new mapping before there's
479
492
* a chance for anything to kick off a table walk for the new iova.
@@ -483,6 +496,13 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova,
483
496
return ret ;
484
497
}
485
498
499
+ static int arm_lpae_map (struct io_pgtable_ops * ops , unsigned long iova ,
500
+ phys_addr_t paddr , size_t size , int iommu_prot , gfp_t gfp )
501
+ {
502
+ return arm_lpae_map_pages (ops , iova , paddr , size , 1 , iommu_prot , gfp ,
503
+ NULL );
504
+ }
505
+
486
506
static void __arm_lpae_free_pgtable (struct arm_lpae_io_pgtable * data , int lvl ,
487
507
arm_lpae_iopte * ptep )
488
508
{
@@ -787,6 +807,7 @@ arm_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg)
787
807
788
808
data -> iop .ops = (struct io_pgtable_ops ) {
789
809
.map = arm_lpae_map ,
810
+ .map_pages = arm_lpae_map_pages ,
790
811
.unmap = arm_lpae_unmap ,
791
812
.unmap_pages = arm_lpae_unmap_pages ,
792
813
.iova_to_phys = arm_lpae_iova_to_phys ,
0 commit comments