@@ -341,20 +341,30 @@ static arm_lpae_iopte arm_lpae_install_table(arm_lpae_iopte *table,
341341}
342342
343343static 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 )
346347{
347348 arm_lpae_iopte * cptep , pte ;
348349 size_t block_size = ARM_LPAE_BLOCK_SIZE (lvl , data );
349350 size_t tblsz = ARM_LPAE_GRANULE (data );
350351 struct io_pgtable_cfg * cfg = & data -> iop .cfg ;
352+ int ret = 0 , num_entries , max_entries , map_idx_start ;
351353
352354 /* 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 ;
354357
355358 /* 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+ }
358368
359369 /* We can't allocate tables at the final level */
360370 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,
383393 }
384394
385395 /* 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 );
387398}
388399
389400static 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,
450461 return pte ;
451462}
452463
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 )
455467{
456468 struct arm_lpae_io_pgtable * data = io_pgtable_ops_to_data (ops );
457469 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,
460472 arm_lpae_iopte prot ;
461473 long iaext = (s64 )iova >> cfg -> ias ;
462474
463- if (WARN_ON (!size || (size & cfg -> pgsize_bitmap ) != size ))
475+ if (WARN_ON (!pgsize || (pgsize & cfg -> pgsize_bitmap ) != pgsize ))
464476 return - EINVAL ;
465477
466478 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,
473485 return 0 ;
474486
475487 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 );
477490 /*
478491 * Synchronise all PTE updates for the new mapping before there's
479492 * 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,
483496 return ret ;
484497}
485498
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+
486506static void __arm_lpae_free_pgtable (struct arm_lpae_io_pgtable * data , int lvl ,
487507 arm_lpae_iopte * ptep )
488508{
@@ -787,6 +807,7 @@ arm_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg)
787807
788808 data -> iop .ops = (struct io_pgtable_ops ) {
789809 .map = arm_lpae_map ,
810+ .map_pages = arm_lpae_map_pages ,
790811 .unmap = arm_lpae_unmap ,
791812 .unmap_pages = arm_lpae_unmap_pages ,
792813 .iova_to_phys = arm_lpae_iova_to_phys ,
0 commit comments