Skip to content

Commit 4a77b12

Browse files
Isaac J. Manjarresjoergroedel
authored andcommitted
iommu/io-pgtable-arm: Implement arm_lpae_map_pages()
Implement the map_pages() callback for the ARM LPAE io-pgtable format. Signed-off-by: Isaac J. Manjarres <[email protected]> Signed-off-by: Georgi Djakov <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent 1fe27be commit 4a77b12

File tree

1 file changed

+31
-10
lines changed

1 file changed

+31
-10
lines changed

drivers/iommu/io-pgtable-arm.c

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -341,20 +341,30 @@ static arm_lpae_iopte arm_lpae_install_table(arm_lpae_iopte *table,
341341
}
342342

343343
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)
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

389400
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,
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+
486506
static 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

Comments
 (0)